kexecboot: add patch to read mtdparts from /proc/cmdline
authorant <ant@unknown.openembedded.org>
Thu, 4 Sep 2008 10:16:43 +0000 (10:16 +0000)
committerThomas Kunze <thommycheck@gmx.de>
Thu, 4 Sep 2008 10:16:43 +0000 (10:16 +0000)
initramfs-kexecboot: add rotation parameter for c7x0
linux-kexecboot_2.6.26: change defconfigs

16 files changed:
packages/kexecboot/files/kexecboot-rewrite.patch [new file with mode: 0644]
packages/kexecboot/files/rootdelay.patch [deleted file]
packages/kexecboot/initramfs-kexecboot_1.0.bb
packages/kexecboot/kexecboot_0.3.bb
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-akita
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-bootcdx86
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-c7x0
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-htcuniversal
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-hx2000
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-poodle
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-qemuarm
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-qemux86
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-spitz
packages/kexecboot/linux-kexecboot-2.6.26/defconfig-zylonite
packages/kexecboot/linux-kexecboot.inc
packages/kexecboot/linux-kexecboot_2.6.26.bb

diff --git a/packages/kexecboot/files/kexecboot-rewrite.patch b/packages/kexecboot/files/kexecboot-rewrite.patch
new file mode 100644 (file)
index 0000000..4f25206
--- /dev/null
@@ -0,0 +1,344 @@
+--- kexecboot-0.3.orig/kexecboot.h     2008-09-03 02:35:40.000000000 +0400
++++ kexecboot-0.3/kexecboot.h  2008-09-03 02:36:04.000000000 +0400
+@@ -24,6 +24,10 @@
+ #include <string.h>
+ #include <linux/input.h>
+ #include <termios.h>
++#include <unistd.h>
++#include <signal.h>
++#include <sys/wait.h>
++#include <ctype.h>
+ #include "fb.h"
+ #include "devicescan.h"
+ #include "res/logo-img.h"
+@@ -33,4 +37,14 @@
+ #include "res/memory-img.h"
+ #include "res/radeon-font.h"
++/* Macro for dealing with NULL strings */
++#define strlenn(s)    ( (NULL != s) ? (strlen(s)) : 0 )
++
++/* Tags we want from /proc/cmdline */
++char *wanted_tags[] = {
++      "mtdparts",
++      NULL
++};
++
++
+ #endif
+--- kexecboot-0.3.orig/kexecboot.c     2008-09-03 02:35:40.000000000 +0400
++++ kexecboot-0.3/kexecboot.c  2008-09-03 03:33:05.000000000 +0400
+@@ -78,20 +78,293 @@
+       fb_render(fb);
+ }
++/*
++ * Function: get_extra_cmdline()
++ * It gets wanted tags from original cmdline.
++ * Takes 2 args:
++ * - extra_cmdline - buffer to store cmdline parameters;
++ * - extra_cmdline_size - size of buffer
++ *   (inc. terminating '\0').
++ * Return values:
++ * - length of extra_cmdline on success (w/o term. zero);
++ * - -1 on error;
++ * - (- length of extra_cmdline - 1)  on insufficient buffer space.
++ */
++
++int get_extra_cmdline(char *const extra_cmdline, const size_t extra_cmdline_size)
++{
++      char *p, *t, *tag = NULL;
++      char line[COMMAND_LINE_SIZE];
++      int i, len, sp_size;
++      int sum_len = 0;
++      int wanted_tag_found = 0;
++      int overflow = 0;
++
++      const char proc_cmdline_path[] = "/proc/cmdline";
++      
++      /* Open /proc/cmdline and read cmdline */
++      FILE *f = fopen(proc_cmdline_path, "r");
++      if (NULL == f) {
++              perror("Can't open /proc/cmdline");
++              return -1;
++      }
++
++      if ( NULL == fgets(line, sizeof(line), f) ) {
++              perror("Can't read /proc/cmdline");
++              fclose(f);
++              return -1;
++      }
++
++      fclose(f);
++      
++      /* clean up buffer before parsing */
++      t = extra_cmdline;
++      *t = '\0';
++      
++      p = line-1;             /* because of ++p below */
++
++      sp_size = 0;    /* size of (first) space */
++      
++      do {
++              ++p;
++              
++              if ( (NULL == tag) && (isalnum(*p)) ) {
++                      /* new tag found */
++                      tag = p;
++              } else if (tag) {
++                      /* we are working on some tag */
++
++                      if (isspace(*p) || ('\0' == *p) || ('=' == *p) ) {
++                              /* end of tag or '=' found */
++                              
++                              if (!wanted_tag_found) {
++                                      /* search in wanted_tags */
++                                      for (i = 0; wanted_tags[i] != NULL; i++) {
++                                              if ( 0 == strncmp(wanted_tags[i], tag, p-tag) ) {
++                                                      /* match found */
++                                                      wanted_tag_found = 1;
++                                                      break;
++                                              }
++                                      }
++                              }
++                              
++                              if ( ('=' != *p) && wanted_tag_found ) {
++                                      /* end of wanted tag found -> copy */
++                                      
++                                      len = p - tag;
++                                      if ( (sum_len + len + sp_size) < extra_cmdline_size ) {
++                                              if (sp_size) {
++                                                      /* prepend space when have tags already */
++                                                      *t = ' ';
++                                                      ++t;
++                                                      *t = '\0';
++                                                      ++sum_len;
++                                              } else {
++                                                      sp_size = sizeof(char);
++                                              }
++                      
++                                              /* NOTE: tag is not null-terminated so copy only
++                                               * len chars and terminate it directly
++                                               */
++                                              strncpy(t, tag, len);
++                                              /* move pointer to position after copied tag */
++                                              t += len ;
++                                              /* null-terminate */
++                                              *t = '\0';
++                                              /* update summary length */
++                                              sum_len += len;
++                                      } else {
++                                              /* we have no space - skip this tag */
++                                              overflow = 1;
++                                      }
++
++                                      /* reset wanted_tag_found */
++                                      wanted_tag_found = 0;
++                              }
++                              
++                              /* reset tag */
++                              if (!wanted_tag_found) tag = NULL;
++
++                      }
++              }
++
++      } while ('\0' != *p);
++
++      if (overflow) return -sum_len-1;
++      return sum_len;
++}
++
++/*
++ * Function: kexec_execw()
++ * (execve and wait)
++ * kexecboot's replace of system() call without /bin/sh invocation.
++ * During execution  of the command, SIGCHLD will be blocked,
++ * and SIGINT and SIGQUIT will be ignored (like system() does).
++ * Takes 2 args (execve()-like):
++ * - path - full path to executable file
++ * - argv[] - array of args for executed file (command options e.g.)
++ * - envp[] - array of environment strings ("key=value")
++ * Return value:
++ * - command exit status on success
++ * - -1 on error (e.g. fork() failed)
++ */
++int kexec_execw(const char *path, char *const argv[], char *const envp[])
++{
++      pid_t pid;
++      struct sigaction ignore, old_int, old_quit;
++      sigset_t masked, oldmask;
++      int status;
++
++      /* Block SIGCHLD and ignore SIGINT and SIGQUIT */
++      /* Do this before the fork() to avoid races */
++
++      ignore.sa_handler = SIG_IGN;
++      sigemptyset(&ignore.sa_mask);
++      ignore.sa_flags = 0;
++      sigaction(SIGINT, &ignore, &old_int);
++      sigaction(SIGQUIT, &ignore, &old_quit);
++
++      sigemptyset(&masked);
++      sigaddset(&masked, SIGCHLD);
++      sigprocmask(SIG_BLOCK, &masked, &oldmask);
++
++      pid = fork();
++
++      if (pid < 0)
++              /* can't fork */
++              return -1;
++      else if (pid == 0) {
++              /* it is child */
++              sigaction(SIGINT, &old_int, NULL);
++              sigaction(SIGQUIT, &old_quit, NULL);
++              sigprocmask(SIG_SETMASK, &oldmask, NULL);
++
++              /* replace child with executed file */
++              execve(path, (char *const *)argv, (char *const *)envp);
++              /* should not happens but... */
++              _exit(127);
++      }
++
++      /* it is parent */
++
++      /* wait for our child and store status */
++      waitpid(pid, &status, 0);
++
++      /* restore signal handlers */
++      sigaction(SIGINT, &old_int, NULL);
++      sigaction(SIGQUIT, &old_quit, NULL);
++      sigprocmask(SIG_SETMASK, &oldmask, NULL);
++
++      return status;
++}
++
+ void start_kernel(struct boot *boot)
+ {
+-      //kexec --command-line="CMDLINE" -l /mnt/boot/zImage
+-      char command[COMMAND_LINE_SIZE + 60];
+-      mount(boot->device, "/mnt", boot->fstype, MS_RDONLY, NULL);
+-      if( boot->cmdline )
+-              sprintf(command,"/usr/sbin/kexec --command-line=\"%s root=%s rootfstype=%s\" -l %s", 
+-                      boot->cmdline, boot->device, boot->fstype, boot->kernelpath);
+-      else
+-              sprintf(command,"kexec -l %s", boot->kernelpath);
+-      system(command);
+-//    puts(command);          
+-      umount("/mnt");
+-      system("/usr/sbin/kexec -e");
++      /* we use var[] instead of *var because sizeof(var) using */
++      const char mount_point[] = "/mnt";
++      const char kexec_path[] = "/usr/sbin/kexec";
++
++      const char str_cmdline_start[] = "--command-line=";
++      const char str_root[] = " root=";
++      const char str_rootfstype[] = " rootfstype=";
++      const char str_rootwait[] = " rootwait";
++
++      /* empty environment */
++      char *const envp[] = { NULL };
++
++      const char *kexec_load_argv[] = { NULL, "-l", NULL, NULL, NULL };
++      const char *kexec_exec_argv[] = { NULL, "-e", NULL};
++
++      char extra_cmdline_buffer[COMMAND_LINE_SIZE];
++      char *extra_cmdline, *cmdline_arg = NULL;
++      int n, idx;
++      
++      kexec_exec_argv[0] = kexec_path;
++      kexec_load_argv[0] = kexec_path;
++
++      /* --command-line arg generation */
++      idx = 2;        /* kexec_load_argv current option index */
++
++      /* get some parts of cmdline from boot loader (e.g. mtdparts) */
++      n = get_extra_cmdline( extra_cmdline_buffer,
++                      sizeof(extra_cmdline_buffer) );
++      if ( -1 == n ) {
++              /* clean up extra_cmdline on error */
++              extra_cmdline = NULL;
++/*    } else if ( n < -1 ) { */
++              /* Do something when we have no space to get all wanted tags */
++              /* Now do nothing ;) */
++      } else {
++              extra_cmdline = extra_cmdline_buffer;
++      }
++
++      /* fill '--command-line' option */
++      if (boot->cmdline || extra_cmdline || boot->device) {
++              /* allocate space */
++              n = strlenn(str_cmdline_start) + strlenn(boot->cmdline) +
++                              sizeof(char) + strlenn(extra_cmdline) +
++                              strlenn(str_root) + strlenn(boot->device) +
++                              strlenn(str_rootfstype) + strlenn(boot->fstype) +
++                              strlenn(str_rootwait) + sizeof(char);
++              
++              cmdline_arg = (char *)malloc(n);
++              if (NULL == cmdline_arg) {
++                      perror("Can't allocate memory for cmdline_arg");
++                      /*  Should we exit?
++                      exit(-1);
++                      */
++              } else {
++                      strcat(cmdline_arg, str_cmdline_start);
++                      if (extra_cmdline)
++                              strcat(cmdline_arg, extra_cmdline);
++                      if (boot->cmdline && extra_cmdline)
++                              strcat(cmdline_arg, " ");
++                      if (boot->cmdline)
++                              strcat(cmdline_arg, boot->cmdline);
++                      if (boot->device) {
++                              strcat(cmdline_arg, str_root);
++                              strcat(cmdline_arg, boot->device);
++                              if (boot->fstype) {
++                                      strcat(cmdline_arg, str_rootfstype);
++                                      strcat(cmdline_arg, boot->fstype);
++                              }
++                      }
++                      strcat(cmdline_arg, str_rootwait);
++
++                      kexec_load_argv[idx] = cmdline_arg;
++                      ++idx;
++              }
++      }
++
++      /* Append kernelpath as last arg of kexec */
++      kexec_load_argv[idx] = boot->kernelpath;
++
++      /* Debug
++      fprintf(stderr, "%s\n%s\n%s\n%s\n", kexec_load_argv[0],
++                      kexec_load_argv[1], kexec_load_argv[2],
++                      kexec_load_argv[3]); */
++
++      /* Mount boot device */
++      if ( -1 == mount(boot->device, mount_point, boot->fstype,
++                      MS_RDONLY, NULL) ) {
++              perror("Can't mount boot device");
++              exit(-1);
++      }
++
++      /* Load kernel */
++      n = kexec_execw(kexec_path, (char *const *)kexec_load_argv, envp);
++      if (-1 == n) {
++              perror("Kexec can't load kernel");
++              exit(-1);
++      }
++
++      if (cmdline_arg)
++              free(cmdline_arg);
++
++      umount(mount_point);
++
++      /* Boot new kernel */
++      execve(kexec_path, (char *const *)kexec_exec_argv, envp);
+ }
+ int main(int argc, char **argv)
+@@ -219,5 +492,6 @@
+       tcsetattr(fileno(stdin), TCSANOW, &old);
+       fb_destroy(fb);
+       start_kernel(bl->list[choice]);
+-      return 0;
++      /* When we reach this point then some error was occured */
++      return -1;
+ }
diff --git a/packages/kexecboot/files/rootdelay.patch b/packages/kexecboot/files/rootdelay.patch
deleted file mode 100644 (file)
index 19a712a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- kexecboot-0.3/kexecboot.c  2008-08-03 17:08:31.000000000 +0200
-+++ kexecboot/kexecboot.c      2008-08-04 13:35:32.167062391 +0200
-@@ -84,7 +84,7 @@
-       char command[COMMAND_LINE_SIZE + 60];
-       mount(boot->device, "/mnt", boot->fstype, MS_RDONLY, NULL);
-       if( boot->cmdline )
--              sprintf(command,"/usr/sbin/kexec --command-line=\"%s root=%s rootfstype=%s\" -l %s", 
-+              sprintf(command,"/usr/sbin/kexec --command-line=\"%s root=%s rootfstype=%s rootdelay=3\" -l %s", 
-                       boot->cmdline, boot->device, boot->fstype, boot->kernelpath);
-       else
-               sprintf(command,"kexec -l %s", boot->kernelpath);
index 75fb8e8..a6450b0 100644 (file)
@@ -1,8 +1,9 @@
 DESCRIPTON = "A init script that mounts a device and kexecs a new kernel from it."
-PR = "r7"
+PR = "r8"
 RDEPENDS = "kexecboot klibc-utils-static-mount klibc-utils-static-sh klibc-utils-static-sleep"
 
 FBANGLE = "270"
+FBANGLE_c7x0 = "0"
 INPUTDEV = "/dev/event0"
 
 
index f3fb6e3..f94e31b 100644 (file)
@@ -1,21 +1,21 @@
 LICENSE = "GPL"
-PR = "r1"
+PR = "r2"
 DEPENDS = "klibc"
 RDEPENDS = "kexec-static"
+
 inherit autotools
 
 # You can create your own *-img.h by doing
 # ./make-image-header.sh <file>.png HAND
 
 SRC_URI = "http://projects.linuxtogo.org/frs/download.php/221/kexecboot-${PV}.tar.gz \
-          file://rootdelay.patch;patch=1"
-S = "${WORKDIR}/kexecboot-${PV}"
+          file://kexecboot-rewrite.patch;patch=1"
 
+S = "${WORKDIR}/kexecboot-${PV}"
 
 export CC=${TARGET_PREFIX}klcc
 
 # standart oe cflags don't work with klcc
-export CFLAGS=""
-export CPPFLAGS=""
-export LDFLAGS=""
-
+export CFLAGS = ""
+export CPPFLAGS = ""
+export LDFLAGS = ""
index e630a9a..21201da 100644 (file)
@@ -53,7 +53,8 @@ CONFIG_FAIR_USER_SCHED=y
 # CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 35e9b5c..1176bc7 100644 (file)
@@ -72,7 +72,7 @@ CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 6c188e7..b57b4c7 100644 (file)
@@ -53,7 +53,8 @@ CONFIG_FAIR_USER_SCHED=y
 # CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 8b2a31d..e9d5dc1 100644 (file)
@@ -53,7 +53,8 @@ CONFIG_FAIR_USER_SCHED=y
 # CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 0f2557c..1fcf2bb 100644 (file)
@@ -54,7 +54,7 @@ CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 7d41252..a89a82b 100644 (file)
@@ -53,7 +53,8 @@ CONFIG_FAIR_USER_SCHED=y
 # CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index e636b6c..6a4502f 100644 (file)
@@ -53,7 +53,7 @@ CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 42f6740..3724f16 100644 (file)
@@ -72,7 +72,7 @@ CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 9c8f0ae..cc66e0f 100644 (file)
@@ -52,7 +52,8 @@ CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index cc2fc48..3e7f96f 100644 (file)
@@ -53,7 +53,8 @@ CONFIG_FAIR_USER_SCHED=y
 # CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="initramfs.cpio.gz"
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
index 1671a49..5926778 100644 (file)
@@ -4,6 +4,12 @@ LICENSE = "GPL"
 
 DONT_CHECK_KERNELSIZE = ""
 INITRAMFS_IMAGE = "initramfs-kexecboot-image"
+
+# uncomment the following lines if you use u-boot as bootloader
+#KERNEL_IMAGETYPE_c7x0="uImage"
+#KERNEL_IMAGETYPE_akita="uImage"
+#KERNEL_IMAGETYPE_spitz="uImage"
+
 inherit kernel
 PACKAGES = ""
 PROVIDES = ""
index 5d31aae..2be42e6 100644 (file)
@@ -1,11 +1,13 @@
 require linux-kexecboot.inc
 
-PR = "r2"
+PR = "r3"
 DEFAULT_PREFERENCE = "-1"
 DEFAULT_PREFERENCE_qemuarm = "-1"
 DEFAULT_PREFERENCE_qemux86 = "-1"
 DEFAULT_PREFERENCE_spitz = "1"
 DEFAULT_PREFERENCE_collie = "1"
+DEFAULT_PREFERENCE_c7x0 = "1"
+DEFAULT_PREFERENCE_akita = "1"
 
 # Handy URLs
 # git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046