diff --git a/doc/66-boot.md b/doc/66-boot.md
index e8cdd85ab7793f3becf3230b47c2b1a589667cb3..5477fb5dd20c69661e4875c21a486e8273ce69e8 100644
--- a/doc/66-boot.md
+++ b/doc/66-boot.md
@@ -90,7 +90,7 @@ In the unusual event that any of the above processes fail, *66-boot* will try to
 
 Skeleton files are mandatory and must exist on your system to be able to boot and shutdown the machine properly. By default those files are installed at `%%skel%%`. Use the `--with-skeleton=DIR` option at compile time to change it.
 
-- `init` : the *66-boot* binary is not meant to be called directly or be linked to the binary directory because it takes command line options. Therefore the `init` skeleton file is used to pass any options to *66-boot. By default *66-boot* is launched with **-m** options. This file ***should be copied*** by the administrator into the binary directory of your system.
+- `init` : the *66-boot* binary is not meant to be called directly or be linked to the binary directory because it takes command line options. Therefore the `init` skeleton file is used to pass any options to *66-boot. By default *66-boot* is launched without options. This file ***should be copied*** by the administrator into the binary directory of your system.
 
 - `init.conf` : this file contains a set of `key=value` pairs. ***All*** keys are mandatory where the name of the key ***must not*** be changed. This is the file available to a user to configure the boot process. By default:
     
@@ -112,7 +112,7 @@ Skeleton files are mandatory and must exist on your system to be able to boot an
 
     * `RESCAN=0` : forces [s6-svscan](https://skarnet.org/software/s6/s6-svscan.html) to perform a scan every *RESCAN* milliseconds. This is an overload function mostly for debugging. It should be 0 during *stage1*. It is strongly discouraged to set *RESCAN* to a positive value smaller than 500.
     
-    * `ISHELL=%%skel%%/ishell` : an absolute path. Gets called in case *stage2* crashes. This file will try to run a *sulogin*.
+    * `ISHELL=%%skel%%/ishell` : an absolute path. Gets called in case *stage2* crashes if define by the administrator at the `rc.init` file.
 
 - `rc.init` : this file is called by the child of *66-boot* to process *stage2*. It invokes two commands:
     
@@ -120,14 +120,12 @@ Skeleton files are mandatory and must exist on your system to be able to boot an
     
     * `66-dbctl -v${VERBOSITY} -l ${LIVE} -t ${TREE} -u` will bring up all `bundle` and `atomic` services inside of *TREE*.
     
-    * If any of these two commands fail the *ISHELL* file is called to provide the means for repair.
+    * If any of these two commands fail a warning message is sent to sdtout. It's the responsability of the administrator to call or not the `ishell` file.
 
 - `rc.shutdown` : this file is called at shudown when the administrator requests the `shutdown`, `halt`, `poweroff` or `reboot` command. It invokes a single command:
     
     * `66-all -v${VERBOSITY} -l ${LIVE} -t ${TREE} -f down` to bring down all *services* for all *trees* marked as enabled.
     
-    * `ishell` : this file is called by `rc.init` in case *stage2* crashes. It will try to run *sulogin* to provide a means of repair.
-    
 The following skeleton files are called to execute their corresponding power related functions and are safe wrappers that accept their corresponding command options. They **should be copied or symlinked** to the binary directory of the system.
 
 - `halt` : wraps [66-hpr -h](66-hpr.html). Terminates all processes and shuts down the CPU.
@@ -137,3 +135,13 @@ The following skeleton files are called to execute their corresponding power rel
 - `reboot` : wraps [66-hpr -r](66-hpr.html). Terminates all processes and instructs a warm boot.
 
 - `shutdown` : wraps [66-shutdown](66-shutdown.html). Like `poweroff` but also runs scripts to bring the system down in a sane way including user notification.
+
+- `ishell` : this file will try to run *sulogin* to provide a means of repair.
+
+## Kernel command line
+
+Any valid `key=value` pair set at the `init.conf` skeleton file can be passed on the kernel command line as parameter:
+
+```
+    BOOT_IMAGE=../vmlinuz-linux root=/dev/sda3 ro vga=895 initrd=../intel-ucode.img,../initramfs-linux.img TREE=boot
+```
diff --git a/src/66/66-boot.c b/src/66/66-boot.c
index 900468a26559e3c0e7750c3287adc25542cfc492..6f9f7d71d0f3afef3288015737b238e153bc63ec 100644
--- a/src/66/66-boot.c
+++ b/src/66/66-boot.c
@@ -56,6 +56,9 @@ static char ttree[MAXENV+1] ;
 static char confile[MAXENV+1] ;
 static char const *const *genv = 0 ;
 static int fdin ;
+static char const *proc_cmdline="/proc/cmdline" ;
+
+#define MAXBUF 1024*64*2
 
 #define USAGE "66-boot [ -h ] [ -m ] [ -s skel ] [ -l log_user ] [ -e environment ] [ -d dev ] [ -b banner ]"
 
@@ -95,6 +98,67 @@ static inline void info_help (void)
  if (buffer_putsflush(buffer_1, help) < 0) sulogin("","") ;
 }
 
+static int read_line(stralloc *dst, char const *line) 
+{
+	char b[MAXBUF] ;
+	int fd ;
+	unsigned int n = 0, m = MAXBUF ;
+
+	fd = open(line, O_RDONLY) ;
+	if (fd == -1) return 0 ;
+
+	for(;;)
+	{
+		ssize_t r = read(fd,b+n,m-n);
+		if (r == -1)
+		{
+			if (errno == EINTR) continue ;
+			break ;
+		}
+		n += r ;
+		// buffer is full
+		if (n == m)
+		{
+			--n ;
+			break ;
+		}
+		// end of file
+		if (r == 0) break ;
+	}
+	close(fd) ;
+
+	if(n)
+	{
+		int i = n ;
+		// remove trailing zeroes
+		while (i && b[i-1] == '\0') --i ;
+		while (i--)
+			if (b[i] == '\n' || b[i] == '\0') b[i] = ' ' ;
+		
+		if (b[n-1] == ' ') b[n-1] = '\0' ;
+	}
+	b[n] = '\0';
+
+	if (!stralloc_cats(dst,b) ||
+		!stralloc_0(dst)) sulogin("close stralloc",dst->s) ;
+ 	return n ;
+}
+
+static int get_value(stralloc *val,char const *key)
+{
+	if (!environ_get_val_of_key(val,key)) return 0 ;
+	/** value may be empty, in this case we use the default one */
+	if (!sastr_clean_element(val)) 
+	{	
+		log_warnu("get value of: ",key," -- keeps the default") ;
+		return 0 ;
+	}
+	if (!sastr_rebuild_in_oneline(val)) sulogin("rebuild line of value: ",val->s) ;
+	if (!stralloc_0(val)) sulogin("append stralloc of value: ",val->s) ;
+	
+	return 1 ;
+}
+
 static void parse_conf(void)
 {
 	static char const *valid[] = 
@@ -102,6 +166,7 @@ static void parse_conf(void)
 	int r ;
 	unsigned int j = 0 ;
 	stralloc src = STRALLOC_ZERO ;
+	stralloc cmdline = STRALLOC_ZERO ;
 	stralloc val = STRALLOC_ZERO ;
 	if (skel[0] != '/') sulogin("skeleton directory must be an aboslute path: ",skel) ;
 	size_t skelen = strlen(skel) ;
@@ -110,22 +175,38 @@ static void parse_conf(void)
 	memcpy(confile + skelen + 1, SS_BOOT_CONF, SS_BOOT_CONF_LEN) ;
 	confile[skelen + 1 + SS_BOOT_CONF_LEN] = 0 ;
 	size_t filesize=file_get_size(confile) ;
+	/** skeleton file */
 	r = openreadfileclose(confile,&src,filesize) ;
 	if(!r) sulogin("open configuration file: ",confile) ; 
 	if (!stralloc_0(&src)) sulogin("append stralloc of file: ",confile) ;
-	
+
+	/** /proc/cmdline */
+	if (!read_line(&cmdline,proc_cmdline)) {
+		/** we don't want to die here */
+		log_warnu("read: ",proc_cmdline) ;
+		cmdline.len = 0 ;
+	} 
+	if (!sastr_split_element_in_nline(&cmdline)) {
+		log_warnu("split: ",proc_cmdline) ;
+		cmdline.len = 0 ;
+	}
 	for (char const *const *p = valid;*p;p++,j++)
 	{
-		if (!stralloc_copy(&val,&src)) sulogin("copy stralloc of file: ",confile) ;
-		if (!environ_get_val_of_key(&val,*p)) continue ;
-		/** value may be empty, in this case we use the default one */
-		if (!sastr_clean_element(&val)) 
-		{	
-			log_warnu("get value of: ",*p," -- keeps the default") ;
-			continue ;
+		/** try first to read from /proc/cmdline.
+		 * If the key is not found, try to read the skeleton file.
+		 * Finally keep the default value if we cannot get a correct
+		 * key=value pair */
+		if (cmdline.len > 0) {
+			if (!stralloc_copy(&val,&cmdline)) sulogin("copy stralloc of file: ",proc_cmdline) ;
+		}
+		else if (!stralloc_copy(&val,&src)) sulogin("copy stralloc of file: ",confile) ;
+		
+		if (!get_value(&val,*p) && cmdline.len > 0)
+		{
+			if (!stralloc_copy(&val,&src)) sulogin("copy stralloc of file: ",confile) ;
+			if (!get_value(&val,*p)) continue ;
 		}
-		if (!sastr_rebuild_in_oneline(&val)) sulogin("rebuild line of value: ",val.s) ;
-		if (!stralloc_0(&val)) sulogin("append stralloc of value: ",val.s) ;
+		else continue ;
 		
 		switch (j)
 		{
@@ -156,6 +237,7 @@ static void parse_conf(void)
 		
 	}
 	stralloc_free(&val) ;
+	stralloc_free(&cmdline) ;
 	stralloc_free(&src) ;
 }