initramfs: New modular initramfs for booting kernel from various media.
authorAlex Osborne <ato@meshy.org>
Thu, 19 Jul 2007 20:55:15 +0000 (20:55 +0000)
committerPaul Sokolovsky <pmiscml@gmail.com>
Thu, 19 Jul 2007 20:55:15 +0000 (20:55 +0000)
* Design principles:
* This initramfs just mounts roots and runs init on it, nothing else.
* Whenever possible, existing kernel parameters are used. When extended
  boot methods are provided, new parameters mimick/adhere to existing
  conventions.
* System is modular/pluggable - each mount method is in own module with
  more or less well defined interface, it's possible to construct complete
  system with any combination of modules.
* Modules includes: initramfs-module-loop, initramfs-module-nfs, to boot
  from loop devices (including recursive loops) and NFS, correspondingly.

packages/initrdscripts/files/init.sh [new file with mode: 0644]
packages/initrdscripts/files/loopboot.sh [new file with mode: 0644]
packages/initrdscripts/files/nfsboot.sh
packages/initrdscripts/initramfs-module-loop_0.1.bb [new file with mode: 0644]
packages/initrdscripts/initramfs-module-nfs_0.1.bb [new file with mode: 0644]
packages/initrdscripts/initramfs_0.1.bb [new file with mode: 0644]

diff --git a/packages/initrdscripts/files/init.sh b/packages/initrdscripts/files/init.sh
new file mode 100644 (file)
index 0000000..8c9803f
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+MODULE_DIR=/initrd.d
+BOOT_ROOT=
+ROOT_DEVICE=/dev/null
+
+early_setup() {
+    mkdir /proc
+    mount -t proc proc /proc
+    mkdir /mnt
+
+    echo -n "creating device nodes: "
+    grep '^ *[0-9]' /proc/partitions | while read major minor blocks dev
+    do
+        if [ ! -e /dev/$dev ]; then
+            echo -n "$dev "
+            [ -e /dev/$dev ] || mknod /dev/$dev b $major $minor
+        fi
+    done
+    echo
+}
+
+read_args() {
+    CMDLINE=`cat /proc/cmdline`
+    for arg in $CMDLINE; do
+        optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
+        case $arg in
+            root=*)
+                ROOT_DEVICE=$optarg ;;
+            rootdelay=*)
+                rootdelay=$optarg ;;
+        esac
+    done
+}
+
+load_modules() {
+    for module in $MODULE_DIR/*; do
+        source $module
+    done
+}
+
+boot_root() {
+    cd $BOOT_ROOT
+    exec switch_root -c /dev/console $BOOT_ROOT /sbin/init
+}
+
+boot_failed() {
+    echo "No valid root device was specified.  Please add root=/dev/something to"
+    echo "the kernel command-line and try again."
+    echo
+    exec sh
+}
+
+echo "Starting initramfs boot..."
+early_setup
+read_args
+
+if [ -n "$rootdelay" ]; then
+    echo "Waiting $rootdelay seconds for devices to settle..."
+    sleep $rootdelay
+fi
+
+load_modules
+[ -n "$BOOT_ROOT" ] && boot_root
+boot_failed
diff --git a/packages/initrdscripts/files/loopboot.sh b/packages/initrdscripts/files/loopboot.sh
new file mode 100644 (file)
index 0000000..55a1948
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+if [ "$ROOT_DEVICE" = "/dev/loop" ]; then
+    loop_mount() {
+        loopdev=/dev/loop$loop_num
+        mountpt=/mnt/loop$loop_num
+
+        [ -e $loopdev ] || mknod $loopdev b 7 $loop_num
+
+        # if only one argument was specified, let it be path not dev
+        if [ -z "$path" ] && [ -n "$dev" ]; then
+            path="$dev"
+            dev=""
+        fi
+        [ -z "$offset" ] && offset=0
+     
+        if [ -n "$dev" ]; then
+            hostpt=`expr "$dev" : '.*/\([^/]*\)'`
+            [ -z "$hostpt" ] && hostpt="$dev"
+            
+            echo "Mounting $dev on $hostpt"
+            mkdir $hostpt
+            mount $dev $hostpt
+            cd $hostpt
+        fi
+    
+        echo "Loopback setup of $path (offset $offset)"
+        losetup -o "$offset" "$loopdev" "$path"
+
+        echo "Mounting $loopdev on $mountpt"
+        mkdir "$mountpt"
+        mount "$loopdev" "$mountpt"
+        cd "$mountpt"
+        BOOT_ROOT="$mountpt"
+        loop_num=`expr "$loop_num" + 1`
+    }
+
+    modprobe vfat
+    modprobe loop
+    
+    loop_num=0
+    
+    for arg in $CMDLINE; do
+        optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
+        echo $arg xxx $optarg 
+        case $arg in
+            looproot=*)
+                dev=`expr "$optarg" : '\([^:]*\).*'`
+                path=`expr "$optarg" : '[^:]*:\([^:]*\).*'`
+                offset=`expr "$optarg" : '[^:]*:[^:]*:\([^:]*\).*'`
+                loop_mount ;;
+        esac
+    done
+fi 
index b536c40..62a0442 100644 (file)
@@ -1,50 +1,38 @@
 #!/bin/sh
 
-echo "Starting initramfs boot..."
-mkdir /proc
-mount -t proc proc /proc
-
-for arg in `cat /proc/cmdline`; do
-    echo $arg
-    optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
-    echo $optarg
-    case $arg in
-        root=*)
-            root=$optarg ;;
-        nfsroot=*)
-            nfsroot=$optarg ;;
-        ip=*)
-            ip=$optarg ;;
+if [ "$ROOT_DEVICE" = "/dev/nfs" ]; then
+    for arg in $CMDLINE; do
+        echo $arg
+        optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
+        echo $optarg
+        case $arg in
+            nfsroot=*)
+                nfsroot=$optarg ;;
+            ip=*)
+                ip=$optarg ;;
+        esac
+    done
+    
+    echo $ip | (IFS=: read client_ip server_ip gw_ip netmask hostname device autoconf; \
+    echo client_ip=$client_ip;
+    echo server_ip=$server_ip;
+    echo gw_ip=$gw_ip;
+    echo netmask=$netmask;
+    echo hostname=$hostname;
+    echo device=$device;
+    echo autoconf=$autoconf;
+    
+    case "$device" in
+        usb*)
+       echo "USB"
+       modprobe g_ether
+       ;;
     esac
-done
-
-echo $ip | (IFS=: read client_ip server_ip gw_ip netmask hostname device autoconf; \
-echo client_ip=$client_ip;
-echo server_ip=$server_ip;
-echo gw_ip=$gw_ip;
-echo netmask=$netmask;
-echo hostname=$hostname;
-echo device=$device;
-echo autoconf=$autoconf;
-
-case "x$device" in
-    usb*)
-       echo "USB"
-       modprobe g_ether
-       ;;
-esac
+    
+    ifconfig $device $client_ip
+    )
 
-ifconfig $device $client_ip
-)
-
-mkdir /mnt
-if [ "x$root" = "x/dev/nfs" ]; then
     echo "booting from NFS: $nfsroot"
     mount -t nfs $nfsroot /mnt
-else
-    echo "booting from: $root"
-    mount $root /mnt
+    BOOT_ROOT=/mnt
 fi
-
-cd /mnt
-exec switch_root -c /dev/console /mnt /sbin/init
diff --git a/packages/initrdscripts/initramfs-module-loop_0.1.bb b/packages/initrdscripts/initramfs-module-loop_0.1.bb
new file mode 100644 (file)
index 0000000..ce8f368
--- /dev/null
@@ -0,0 +1,8 @@
+SRC_URI = "file://loopboot.sh"
+PR = "r0"
+
+do_install() {
+        install -m 0755 ${WORKDIR}/loopboot.sh ${D}/initrd.d/loop
+}
+
+FILES_${PN} += " /initrd.d/loop "
diff --git a/packages/initrdscripts/initramfs-module-nfs_0.1.bb b/packages/initrdscripts/initramfs-module-nfs_0.1.bb
new file mode 100644 (file)
index 0000000..90b80a3
--- /dev/null
@@ -0,0 +1,8 @@
+SRC_URI = "file://nfsboot.sh"
+PR = "r0"
+
+do_install() {
+        install -m 0755 ${WORKDIR}/nfsboot.sh ${D}/initrd.d/nfs
+}
+
+FILES_${PN} += " /initrd.d/nfs "
diff --git a/packages/initrdscripts/initramfs_0.1.bb b/packages/initrdscripts/initramfs_0.1.bb
new file mode 100644 (file)
index 0000000..c7e44ea
--- /dev/null
@@ -0,0 +1,8 @@
+SRC_URI = "file://init.sh"
+PR = "r0"
+
+do_install() {
+        install -m 0755 ${WORKDIR}/init.sh ${D}/init
+}
+
+FILES_${PN} += " /init "