- provide option to build an initramfs out of the current rootfs. Closes #881

This commit is contained in:
Bernhard Reutner-Fischer 2007-07-08 19:22:18 +00:00
parent 402d710eeb
commit 149c552e0f
4 changed files with 263 additions and 0 deletions

View File

@ -10,6 +10,7 @@ source "target/squashfs/Config.in"
source "target/tar/Config.in"
source "target/cpio/Config.in"
source "target/iso9660/Config.in"
source "target/initramfs/Config.in"
comment "bootloader for target device"

View File

@ -0,0 +1,16 @@
config BR2_TARGET_ROOTFS_INITRAMFS
bool "initramfs for initial ramdisk of linux kernel"
default n
help
Build a file which is usable for the gen_init_cpio tool
at linux kernel build.
This file is normally called initramfs_list and can be
generated with gen_initramfs_list.sh script from the root
directory structure.
The file is then used in the kernel build process to generate
the cpio filesystem for the initial ramdisk. Make sure that
you configure this file in kernel build configuration.
The location in the kernel build configuration menu is
Device Drivers -> Block devices -> Initramfs source file(s).
The configuration variable is CONFIG_INITRAMFS_SOURCE

View File

@ -0,0 +1,203 @@
#!/bin/sh
# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
# Released under the terms of the GNU GPL
#
# Generate a newline separated list of entries from the file/directory
# supplied as an argument.
#
# If a file/directory is not supplied then generate a small dummy file.
#
# The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c.
#
default_initramfs() {
cat <<-EOF
# This is a very simple, default initramfs
dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
dir /root 0700 0 0
EOF
}
filetype() {
local argv1="$1"
# symlink test must come before file test
if [ -L "$argv1" ]; then
echo "slink"
elif [ -f "$argv1" ]; then
echo "file"
elif [ -d "$argv1" ]; then
echo "dir"
elif [ -b "$argv1" -o -c "$argv1" ]; then
echo "nod"
elif [ -p "$argv1" ]; then
echo "pipe"
elif [ -S "$argv1" ]; then
echo "sock"
else
echo "invalid"
fi
return 0
}
print_mtime() {
local argv1="$1"
local mymtime="0"
if [ -e "$argv1" ]; then
mymtime=$(find "$argv1" -printf "%T@\n" | sort -r | head -n 1)
fi
echo "# Last modified: $mymtime"
echo
}
parse() {
local location="$1"
local name=$(echo "$location" | sed -e "s,$srcdir,,")
# change '//' into '/'
name=$(echo $name | sed -e 's,/[/]*,/,g')
local mode="$2"
local uid="$3"
local gid="$4"
local ftype=$(filetype "$location")
# remap uid/gid to 0 if necessary
[ "x$uid" != "x" ] && [ $uid -eq $root_uid ] && uid=0
[ "x$gid" != "x" ] && [ $gid -eq $root_gid ] && gid=0
local str="$mode $uid $gid"
[ "$ftype" = "invalid" ] && return 0
[ "$location" = "$srcdir" ] && return 0
case "$ftype" in
"file")
str="$ftype $name $location $str"
;;
"nod")
local devtype=
local maj=$(LC_ALL=C ls -l "$location" | \
awk '{sub(/,/, "", $5); print $5}')
local min=$(LC_ALL=C ls -l "$location" | \
awk '{print $6}')
if [ -b "$location" ]; then
devtype="b"
else
devtype="c"
fi
str="$ftype $name $str $devtype $maj $min"
;;
"slink")
local target=$(LC_ALL=C ls -l "$location" | \
awk '{print $11}')
str="$ftype $name $target $str"
;;
*)
str="$ftype $name $str"
;;
esac
echo "$str"
return 0
}
usage() {
printf "Usage:\n"
printf "$0 [ [-u <root_uid>] [-g <root_gid>] [-d | <cpio_source>] ] . . .\n"
printf "\n"
printf -- "-u <root_uid> User ID to map to user ID 0 (root).\n"
printf " <root_uid> is only meaningful if <cpio_source>\n"
printf " is a directory.\n"
printf -- "-g <root_gid> Group ID to map to group ID 0 (root).\n"
printf " <root_gid> is only meaningful if <cpio_source>\n"
printf " is a directory.\n"
printf "<cpio_source> File list or directory for cpio archive.\n"
printf " If <cpio_source> is not provided then a\n"
printf " a default list will be output.\n"
printf -- "-d Output the default cpio list. If no <cpio_source>\n"
printf " is given then the default cpio list will be output.\n"
printf "\n"
printf "All options may be repeated and are interpreted sequentially\n"
printf "and immediately. -u and -g states are preserved across\n"
printf "<cpio_source> options so an explicit \"-u 0 -g 0\" is required\n"
printf "to reset the root/group mapping.\n"
}
build_list() {
printf "\n#####################\n# $cpio_source\n"
if [ -f "$cpio_source" ]; then
print_mtime "$cpio_source"
cat "$cpio_source"
elif [ -d "$cpio_source" ]; then
srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g;s:/$::')
dirlist=$(find "$srcdir" -printf "%p %m %U %G\n" 2>/dev/null)
# If $dirlist is only one line, then the directory is empty
if [ "$(echo "$dirlist" | wc -l)" -gt 1 ]; then
print_mtime "$cpio_source"
echo "$dirlist" | \
while read x; do
parse $x
done
else
# Failsafe in case directory is empty
default_initramfs
fi
else
echo " $0: Cannot open '$cpio_source'" >&2
exit 1
fi
}
root_uid=0
root_gid=0
while [ $# -gt 0 ]; do
arg="$1"
shift
case "$arg" in
"-u")
root_uid="$1"
shift
;;
"-g")
root_gid="$1"
shift
;;
"-d")
default_list="$arg"
default_initramfs
;;
"-h")
usage
exit 0
;;
*)
case "$arg" in
"-"*)
printf "ERROR: unknown option \"$arg\"\n" >&2
printf "If the filename validly begins with '-', then it must be prefixed\n" >&2
printf "by './' so that it won't be interpreted as an option." >&2
printf "\n" >&2
usage >&2
exit 1
;;
*)
cpio_source="$arg"
build_list
;;
esac
;;
esac
done
# spit out the default cpio list if a source hasn't been specified
[ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs
exit 0

View File

@ -0,0 +1,43 @@
#############################################################
#
# Make a initramfs_list file to be used by gen_init_cpio
# gen_init_cpio is part of the 2.6 linux kernels to build an
# initial ramdisk filesystem based on cpio
#
#############################################################
ifeq ($(strip $(BR2_TARGET_ROOTFS_INITRAMFS)),y)
INITRAMFS_TARGET:=$(IMAGE).initramfs_list
else
INITRAMFS_TARGET:= #nothing
endif
$(INITRAMFS_TARGET) initramfs: host-fakeroot makedevs
-find $(TARGET_DIR) -type f -perm +111 | xargs $(STRIP) 2>/dev/null || true;
rm -rf $(TARGET_DIR)/usr/man
rm -rf $(TARGET_DIR)/usr/info
-/sbin/ldconfig -r $(TARGET_DIR) 2>/dev/null
# Use fakeroot to pretend all target binaries are owned by root
rm -f $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
touch $(STAGING_DIR)/.fakeroot.00000
cat $(STAGING_DIR)/.fakeroot* > $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
echo "chown -R 0:0 $(TARGET_DIR)" >> $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
# Use fakeroot to pretend to create all needed device nodes
echo "$(STAGING_DIR)/bin/makedevs -d $(TARGET_DEVICE_TABLE) $(TARGET_DIR)" \
>> $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
# Use fakeroot so gen_initramfs_list.sh believes the previous fakery
echo "$(CONFIG_SHELL) target/initramfs/gen_initramfs_list.sh -u 0 -g 0 $(TARGET_DIR) > $(INITRAMFS_TARGET)" \
>> $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
chmod a+x $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
$(STAGING_DIR)/usr/bin/fakeroot -- $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
-rm -f $(STAGING_DIR)/_fakeroot.$(notdir $(TAR_TARGET))
initramfs-source:
initramfs-clean:
ifeq ($(strip $(BR2_TARGET_ROOTFS_INITRAMFS)),y)
-rm -f $(INITRAMFS_TARGET)
endif
initramfs-dirclean: