aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2009-04-29 13:18:13 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2009-04-29 13:18:13 +0000
commit1378536fcf22544533e6df4cbca3c558ffcc01ab (patch)
tree5f9ca9ad44b6432214f453482edc75136efc6a77
downloadmkinitfs-1378536fcf22544533e6df4cbca3c558ffcc01ab.tar.bz2
mkinitfs-1378536fcf22544533e6df4cbca3c558ffcc01ab.tar.xz
initial commit
-rw-r--r--Makefile36
-rw-r--r--files.d/base11
-rw-r--r--files.d/bootchart8
-rwxr-xr-xinitramfs-init308
-rwxr-xr-xmkinitfs179
-rw-r--r--modules.d/ata1
-rw-r--r--modules.d/base1
-rw-r--r--modules.d/cdrom2
-rw-r--r--modules.d/cramfs1
-rw-r--r--modules.d/ide1
-rw-r--r--modules.d/raid1
-rw-r--r--modules.d/scsi2
-rw-r--r--modules.d/usb3
13 files changed, 554 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4693de6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,36 @@
+
+VERSION := 1.1
+
+
+SBIN_FILES := mkinitfs bootchartd
+SHARE_FILES := initramfs-init
+CONF_FILES := mkinitfs.conf \
+ modules.d/ata \
+ modules.d/ide \
+ modules.d/base \
+ modules.d/raid \
+ modules.d/scsi \
+ modules.d/cdrom \
+ modules.d/usb \
+ modules.d/cramfs \
+ files.d/bootchart \
+ files.d/base
+
+DISTFILES := $(SBIN_FILES) $(CONF_FILES) $(SHARE_FILES) Makefile
+
+INSTALL := install
+
+help:
+ @echo "usage: make install [DESTDIR=]"
+
+install:
+ for i in $(SBIN_FILES); do \
+ $(INSTALL) -Dm755 $$i $(DESTDIR)/sbin/$$i || exit 1;\
+ done
+ for i in $(CONF_FILES); do \
+ $(INSTALL) -Dm644 $$i $(DESTDIR)/etc/mkinitfs/$$i || exit 1;\
+ done
+ for i in $(SHARE_FILES); do \
+ $(INSTALL) -D $$i $(DESTDIR)/usr/share/mkinitfs/$$i || exit 1;\
+ done
+
diff --git a/files.d/base b/files.d/base
new file mode 100644
index 0000000..68aa20e
--- /dev/null
+++ b/files.d/base
@@ -0,0 +1,11 @@
+/bin/busybox
+/bin/sh
+/lib/libcrypt-[0-9]*
+/lib/libcrypt.so.*
+/lib/libm-[0-9]*
+/lib/libm.so.*
+/lib/libuClibc-[0-9]*
+/lib/libc.so.*
+/lib/ld-uClibc-[0-9]*
+/lib/ld-uClibc.so*
+/lib/mdev
diff --git a/files.d/bootchart b/files.d/bootchart
new file mode 100644
index 0000000..8adf4df
--- /dev/null
+++ b/files.d/bootchart
@@ -0,0 +1,8 @@
+/usr/bin/ac
+/usr/bin/last
+/usr/bin/lastcomm
+/usr/sbin/dump-utmp
+/usr/sbin/dump-acct
+/usr/sbin/accton
+/usr/sbin/sa
+
diff --git a/initramfs-init b/initramfs-init
new file mode 100755
index 0000000..d9a9d68
--- /dev/null
+++ b/initramfs-init
@@ -0,0 +1,308 @@
+#!/bin/busybox sh
+
+# this is the init script version
+VERSION=1.1
+NEWROOT=/newroot
+SINGLEMODE=no
+
+/bin/busybox --install -s
+
+# basic environment
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# needed devs
+[ -c /dev/null ] || mknod -m 666 /dev/null c 1 3
+
+# basic mounts
+mount -t proc -o noexec,nosuid,nodev proc /proc
+mount -t sysfs -o noexec,nosuid,nodev sysfs /sys
+
+# some helpers
+ebegin() {
+ echo -n " * $*: "
+}
+eend() {
+ local msg
+ if [ "$1" = 0 ] || [ $# -lt 1 ] ; then
+ echo "ok."
+ else
+ shift
+ echo "failed. $*"
+ echo "initramfs emergency recovery shell launched. Type 'exit' to continue boot"
+ /bin/busybox sh
+ fi
+}
+
+scan_drivers() {
+ if [ "$AUTODETECT" != no ] ; then
+ find /sys -name modalias | xargs sort -u | xargs modprobe -a 2> /dev/null
+ fi
+}
+
+find_ovl() {
+ local mnt="$1"
+ local ovl
+ local lines
+
+ # look for apkovl's on mounted media
+ ovl=$( ls -1 "$mnt"/*.apkovl.tar.gz* 2>/dev/null ) || return 1
+ lines=$(echo "$ovl" | wc -l)
+
+ if [ $lines -gt 1 ] ; then
+ echo "ERROR: More than one apkovl file was found on $(basename $mnt). None will be read." >&2
+ return 1
+ fi
+ echo "$ovl"
+}
+
+retry_mount() {
+ # usb might need some time to settle so we retry a few times
+ for i in $(seq 0 19); do
+ mount $@ 2>&1 && return 0
+ sleep 1
+ done
+ return 1
+}
+
+unpack_apkovl() {
+ local ovl="$1"
+ local dest="$2"
+ local suffix=${ovl##*.}
+ local i
+ if [ "$suffix" = "gz" ]; then
+ tar -C "$dest" -zxf "$ovl"
+ return $?
+ fi
+
+ for i in $ALPINE_MNT/*/*/openssl-[0-9]*.apk $ALPINE_MNT/*/openssl-[0-9]*.apk; do
+ [ -f "$i" ] && tar --numeric-owner -C / -zxf $i && break
+ done
+
+ if ! openssl list-cipher-commands | grep "^$suffix$" > /dev/null; then
+ errstr="Cipher $suffix is not supported"
+ return 1
+ fi
+ local count=0
+ # beep
+ echo -e "\007"
+ while [ $count -lt 3 ]; do
+ openssl enc -d -$suffix -in "$ovl" | tar --numeric-owner \
+ -C "$dest" -zx 2>/dev/null && return 0
+ count=$(( $count + 1 ))
+ done
+ return 1
+}
+
+# gotta start from somewhere :)
+echo "Alpine Init $VERSION"
+
+# read the kernel options
+for i in `cat /proc/cmdline` ; do
+ case $i in
+ s|single|1)
+ SINGLEMODE=yes ;;
+ modules=*)
+ MODULES="`echo ${i#modules=} | tr ',' ' '`";;
+ noautodetect)
+ AUTODETECT=no;;
+ *=*) eval KOPT_$i ;;
+ *) eval KOPT_$i=yes ;;
+ esac
+done
+
+# start bootcharting if wanted
+if [ -n "$KOPT_chart" ]; then
+ ebegin "Starting bootchart logging"
+ /sbin/bootchartd start-initfs "$NEWROOT"
+ eend 0
+fi
+
+ALPINE_DEV=${KOPT_alpine_dev%%:*}
+ALPINE_DEV_FS=${KOPT_alpine_dev##*:}
+if [ "$ALPINE_DEV_FS" = "$ALPINE_DEV" ]; then
+ unset ALPINE_DEV_FS
+fi
+ALPINE_MNT=/media/$ALPINE_DEV
+
+# hide kernel messages
+dmesg -n 1
+
+# setup /dev
+ebegin "Starting mdev"
+mount -t tmpfs -o exec,nosuid,mode=0755 mdev /dev
+ln -s sr0 /dev/cdrom
+echo "/sbin/mdev" > /proc/sys/kernel/hotplug
+mdev -s
+RC=$?
+[ -d /dev/pts ] || mkdir -m 755 /dev/pts
+[ -c /dev/ptmx ] || mknod -m 666 /dev/ptmx c 5 2
+mount -t devpts -o gid=5,mode=0620,noexec,nosuid devpts /dev/pts
+[ -d /dev/shm ] || mkdir /dev/shm
+mount -t tmpfs -o nodev,nosuid,noexec shm /dev/shm
+eend $RC
+
+# load available drivers to get access to modloop media
+ebegin "Loading boot drivers"
+[ "$MODULES" ] && modprobe -a $MODULES 2> /dev/null
+if [ -f /etc/modules ] ; then
+ sed 's/\#.*//g' < /etc/modules |
+ while read module args; do
+ modprobe -q $module $args
+ done
+fi
+scan_drivers
+scan_drivers
+eend 0
+
+# check if root=... was set
+if [ -n "$KOPT_root" ]; then
+ if [ "$SINGLEMODE" = "yes" ]; then
+ echo "Entering single mode. Type 'exit' to continue booting."
+ sh
+ fi
+ case "$KOPT_root" in
+ /dev/md*)
+ mknod $KOPT_root b 9 ${KOPT_root#/dev/md}
+ raidautorun "$KOPT_root"
+ ;;
+ esac
+ ebegin "Mounting root"
+ retry_mount $KOPT_root $NEWROOT 2>/dev/null
+ eend $?
+ cat /proc/mounts | while read DEV DIR TYPE OPTS ; do
+ if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then
+ mkdir -p $NEWROOT/$DIR
+ mount -o move $DIR $NEWROOT/$DIR
+ fi
+ done
+ sync
+ exec /bin/busybox switch_root $NEWROOT $chart_init /sbin/init $KOPT_init_args
+ echo "initramfs emergency recovery shell launched"
+ exec /bin/busybox sh
+fi
+
+# locate boot media and mount it
+ebegin "Mounting boot media"
+mkdir -p $ALPINE_MNT
+if [ -n "$ALPINE_DEV_FS" ]; then
+ mount_opts="-t $ALPINE_DEV_FS"
+fi
+
+retry_mount $mount_opts /dev/$ALPINE_DEV $ALPINE_MNT >/dev/null 2>&1
+eend $?
+
+ebegin "Mounting loopback device for kernel modules"
+modprobe loop
+if [ -n "$KOPT_modloop" ]; then
+ modloop=$KOPT_modloop
+else
+ modloop=$KOPT_BOOT_IMAGE.cmg
+fi
+mount -o loop,ro -t cramfs $ALPINE_MNT/$modloop /.modloop
+rc=$?
+if [ "$rc" = 0 ]; then
+ rm -rf /lib/modules
+ ln -sf /.modloop/modules /lib
+fi
+eend $?
+
+if [ -d $ALPINE_MNT/firmware ]; then
+ ebegin "Copying firmware from $ALPINE_MNT/firmware"
+ mkdir -p /lib
+ cp -R -a $ALPINE_MNT/firmware /lib/
+ eend $?
+fi
+
+mkdir -p /etc/apk
+for i in $ALPINE_MNT/*/APK_INDEX.gz $ALPINE_MNT/*/*/APK_INDEX.gz; do
+ [ -r "$i" ] && echo ${i%/APK_INDEX.gz} >> /etc/apk/repositories
+done
+
+# early console?
+if [ "$SINGLEMODE" = "yes" ]; then
+ echo "Entering single mode. Type 'exit' to continue booting."
+ sh
+fi
+
+# more drivers
+ebegin "Loading hardware drivers"
+scan_drivers
+eend 0
+
+mount -t tmpfs tmpfs $NEWROOT
+
+# look for apkovl
+if dmesg | grep '^usb-storage: waiting' >/dev/null; then
+ ebegin "Waiting for USB device to settle"
+ while ! dmesg | grep 'usb-storage: device scan complete' >/dev/null; do
+ sleep 1
+ done
+ eend 0
+fi
+for i in usb floppy cdrom; do
+ mount /media/$i 2>/dev/null || continue
+ ovl=$(find_ovl /media/$i)
+ [ -f "$ovl" ] && break
+ umount /media/$i 2>/dev/null
+done
+if ! [ -f "$ovl" ]; then
+ ovl=$(find_ovl $ALPINE_MNT)
+fi
+
+if [ -f "$ovl" ]; then
+ ebegin "Loading user settings from $ovl"
+ unpack_apkovl "$ovl" $NEWROOT
+ eend $? $errstr
+ umount /media/$i 2>/dev/null &
+ pkgs=$(sed 's/\#.*//' $NEWROOT/etc/lbu/packages.list 2>/dev/null)
+fi
+
+# hack so we get openrc
+pkgs="$pkgs openrc"
+
+# install new root
+ebegin "Installing packages to root filesystem"
+if [ -n "$KOPT_chart" ]; then
+ pkgs="$pkgs acct"
+fi
+apkflags="--initdb --quiet --progress --force"
+if [ -z "$KOPT_keep_apk_new" ]; then
+ apkflags="$apkflags --clean-protected"
+fi
+apk add --root /newroot $apkflags $pkgs >/dev/null
+eend $?
+
+# copy alpine release info
+cp $ALPINE_MNT/.alpine-release $NEWROOT/
+ln -sf /.alpine-release $NEWROOT/etc/alpine-release
+
+# if there is no repositories file, then use the default
+if ! [ -f $NEWROOT/etc/apk/repositories ]; then
+ cp /etc/apk/repositories $NEWROOT/etc/apk/repositories
+fi
+
+# setup bootchart for switch_root
+chart_init=""
+if [ -n "$KOPT_chart" ]; then
+ /sbin/bootchartd stop-initfs "$NEWROOT"
+ chart_init="/sbin/bootchartd start-rootfs"
+fi
+
+# switch over to new root
+cat /proc/mounts | while read DEV DIR TYPE OPTS ; do
+ if [ "$DIR" != "/" -a "$DIR" != "$NEWROOT" -a -d "$DIR" ]; then
+ mkdir -p $NEWROOT/$DIR
+ mount -o move $DIR $NEWROOT/$DIR
+ fi
+done
+ln -sf /.modloop/modules $NEWROOT/lib/modules
+sync
+
+echo ""
+if [ -x $NEWROOT/sbin/init ]; then
+ exec /bin/busybox switch_root $NEWROOT $chart_init /sbin/init $KOPT_init_args
+fi
+
+echo "initramfs emergency recovery shell launched"
+exec /bin/busybox sh
+reboot
diff --git a/mkinitfs b/mkinitfs
new file mode 100755
index 0000000..67b97f2
--- /dev/null
+++ b/mkinitfs
@@ -0,0 +1,179 @@
+#!/bin/sh
+
+_cp() {
+ local i
+ for i in "$@"; do
+ local dest="$tmpdir"/${i%/*}
+ mkdir -p "$dest"
+ cp -flLpR "$i" "$dest" 2>/dev/null || cp -pR "$i" "$dest"
+ done
+}
+
+feature_files() {
+ local dir="$1"
+ local glob file
+ for f in $features; do
+ if [ ! -f "$dir/$f" ]; then
+ continue
+ fi
+ for glob in $(cat "$dir/$f"); do
+ for file in $glob; do
+ echo $glob
+ done
+ done
+ done
+}
+
+initfs_base() {
+ local i= dirs= glob= file=
+ echo "==> initramfs: copying base files" >&2
+ for i in dev proc sys sbin bin .modloop lib/modules media/cdrom \
+ media/floppy media/usb newroot; do
+ dirs="$dirs $tmpdir/$i"
+ done
+ mkdir -p $dirs
+
+ for file in $(feature_files "$filelists_dir"); do
+ _cp $file
+ done
+
+ # copy init
+ cd $startdir
+ install -m755 "$init" "$tmpdir"/init
+}
+
+find_kmod_deps() {
+ awk '
+function recursedeps(k, j) {
+ if (k in visited)
+ return;
+ visited[k] = 1;
+ split(deps[k], dep, " ");
+ for (j in dep)
+ recursedeps(dep[j]);
+ print(k);
+}
+
+BEGIN {
+ if (modulesdep == "")
+ modulesdep="modules.dep";
+ FS = ": ";
+ while ( (getline < modulesdep) > 0) {
+ deps[$1] = $2;
+ }
+}
+
+{
+ mod["/"$0] = 1;
+}
+
+END {
+ for (i in mod)
+ recursedeps(i);
+}' -v modulesdep="$basedir/lib/modules/$kernel/modules.dep"
+}
+
+initfs_kmods() {
+ local glob= file= files= dirs=
+ rm -rf "$tmpdir"/lib/modules
+ cd "$kerneldir" || return 1
+ echo "==> initramfs: copying kernel $kernel modules" >&2
+ files=$(
+ for file in $(feature_files $modulelists_dir); do
+ if ! [ -e ${file} ]; then
+ echo "$file: No such file or directory" >&2
+ continue
+ fi
+ echo $file
+ done | find_kmod_deps)
+ for file in $files; do
+ _cp "$basedir"/lib/modules/$kernel/$file
+ done
+}
+
+initfs_cpio() {
+ echo "==> initramfs: creating $outfile" >&2
+ (cd "$tmpdir" && find . | cpio -o -H newc | gzip) > $outfile
+}
+
+usage() {
+ cat <<EOF
+usage: mkinitfs [-hkL] [-b basedir] [-c configfile] [-i initfile ]
+ [-o outfile] [-t tempdir] [kernelversion]"
+options:
+ -b prefix files and kernel modules with basedir
+ -c use configfile instead of $config
+ -h print this help
+ -i use initfile as init instead of $init
+ -k keep tempdir
+ -L list available features
+ -o set another outfile
+ -t use tempdir when creating initramfs image
+
+EOF
+ exit 1
+}
+
+# main
+
+startdir=$PWD
+config=/etc/mkinitfs/mkinitfs.conf
+init=/usr/share/mkinitfs/initramfs-init
+
+while getopts "b:c:hi:kLo:t:" opt; do
+ case "$opt" in
+ b) basedir="$OPTARG";;
+ c) config="$OPTARG";;
+ h) usage;;
+ i) init=$OPTARG;;
+ k) keeptmp=1;;
+ L) list_features=1;;
+ o) outfile="$OPTARG";;
+ t) tmpdir="$OPTARG";;
+ *) usage;;
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+. "$config"
+filelists_dir=${filelists_dir:-"/etc/mkinitfs/files.d"}
+modulelists_dir=${modules_dir:-"/etc/mkinitfs/modules.d"}
+
+if [ -n "$list_features" ]; then
+ for i in $filelists_dir $modulelists_dir; do
+ ( [ -d "$i" ] && cd $i && ls )
+ done | sort | uniq
+ exit 0
+fi
+
+[ -n "$1" ] && kernel="$1"
+[ -z "$kernel" ] && kernel=$(uname -r)
+kerneldir="$basedir/lib/modules/$kernel"
+if [ -z "$outfile" ]; then
+ outfile="$basedir"/boot/${kernel##*-}.gz
+fi
+
+if [ ! -d "$kerneldir" ]; then
+ echo "$kerneldir does not exist or is not a directory"
+ exit 1
+fi
+
+if [ -z "$tmpdir" ]; then
+ tmpdir=$(mktemp -d /tmp/mkinitfs.XXXXXX)
+else
+ mkdir -p "$tmpdir"
+fi
+
+if [ -z "$keeptmp" ]; then
+ [ -d "$tmpdir" ] && rm -rf "$tmpdir"/*
+fi
+
+initfs_base
+initfs_kmods
+initfs_cpio
+
+# cleanup
+if [ -z "$keeptmp" ]; then
+ [ -d "$tmpdir" ] && rm -rf "$tmpdir"
+fi
+
diff --git a/modules.d/ata b/modules.d/ata
new file mode 100644
index 0000000..2a68a98
--- /dev/null
+++ b/modules.d/ata
@@ -0,0 +1 @@
+kernel/drivers/ata/*.ko
diff --git a/modules.d/base b/modules.d/base
new file mode 100644
index 0000000..9d39ba0
--- /dev/null
+++ b/modules.d/base
@@ -0,0 +1 @@
+kernel/drivers/hid/*
diff --git a/modules.d/cdrom b/modules.d/cdrom
new file mode 100644
index 0000000..038c4a2
--- /dev/null
+++ b/modules.d/cdrom
@@ -0,0 +1,2 @@
+kernel/drivers/cdrom
+kernel/fs/isofs
diff --git a/modules.d/cramfs b/modules.d/cramfs
new file mode 100644
index 0000000..65c9c5f
--- /dev/null
+++ b/modules.d/cramfs
@@ -0,0 +1 @@
+kernel/fs/cramfs
diff --git a/modules.d/ide b/modules.d/ide
new file mode 100644
index 0000000..dec5fc5
--- /dev/null
+++ b/modules.d/ide
@@ -0,0 +1 @@
+kernel/drivers/ide/*.ko
diff --git a/modules.d/raid b/modules.d/raid
new file mode 100644
index 0000000..1c3a38f
--- /dev/null
+++ b/modules.d/raid
@@ -0,0 +1 @@
+kernel/drivers/md/raid*
diff --git a/modules.d/scsi b/modules.d/scsi
new file mode 100644
index 0000000..62a2810
--- /dev/null
+++ b/modules.d/scsi
@@ -0,0 +1,2 @@
+kernel/drivers/scsi/*
+kernel/drivers/message/fusion
diff --git a/modules.d/usb b/modules.d/usb
new file mode 100644
index 0000000..6396750
--- /dev/null
+++ b/modules.d/usb
@@ -0,0 +1,3 @@
+kernel/drivers/usb/host
+kernel/drivers/usb/storage
+kernel/fs/fat