浏览代码

fs/initramfs: refactor with fs/cpio

An initramfs is in fact the same as a cpio archive, but embedded in
the kernel.  So instead of duplicating the cpio infrastructure,
we can simply build images/rootfs.cpio and link that into the
kernel.

Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Arnout Vandecappelle (Essensium/Mind) 14 年之前
父节点
当前提交
13a3afc536
共有 5 个文件被更改,包括 25 次插入250 次删除
  1. 7 6
      fs/initramfs/Config.in
  2. 0 203
      fs/initramfs/gen_initramfs_list.sh
  3. 0 7
      fs/initramfs/init
  4. 11 24
      fs/initramfs/initramfs.mk
  5. 7 10
      linux/linux.mk

+ 7 - 6
fs/initramfs/Config.in

@@ -1,20 +1,21 @@
 config BR2_TARGET_ROOTFS_INITRAMFS
 config BR2_TARGET_ROOTFS_INITRAMFS
 	bool "initramfs for initial ramdisk of linux kernel"
 	bool "initramfs for initial ramdisk of linux kernel"
 	depends on BR2_LINUX_KERNEL
 	depends on BR2_LINUX_KERNEL
+	select BR2_TARGET_ROOTFS_CPIO
 	help
 	help
 	  Integrate the root filesystem generated by Buildroot as an
 	  Integrate the root filesystem generated by Buildroot as an
 	  initramfs inside the kernel image. This integration will
 	  initramfs inside the kernel image. This integration will
 	  take place automatically.
 	  take place automatically.
 
 
-	  The rootfs.initramfs file generated in the images/ directory
-	  is only a text file describing the contents of the initramfs
-	  in a format understood by the CONFIG_INITRAMFS_SOURCE kernel
-	  configuration option.
+	  A rootfs.cpio file will be generated in the images/ directory.
+	  This is the archive that will be included in the kernel image.
+	  The rootfs in the kernel will always be gzip'ed, regardless
+	  of how buildroot's cpio archive is configured.
 
 
-	  Note that enabling initramfs together with other filesystem
+	  Note that enabling initramfs together with another filesystem
 	  formats doesn't make sense: you would end up having two
 	  formats doesn't make sense: you would end up having two
 	  identical root filesystems, one embedded inside the kernel
 	  identical root filesystems, one embedded inside the kernel
-	  image, and one separatly.
+	  image, and one separately.
 
 
 comment "initramfs requires a Linux kernel to be built"
 comment "initramfs requires a Linux kernel to be built"
 	depends on !BR2_LINUX_KERNEL
 	depends on !BR2_LINUX_KERNEL

+ 0 - 203
fs/initramfs/gen_initramfs_list.sh

@@ -1,203 +0,0 @@
-#!/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

+ 0 - 7
fs/initramfs/init

@@ -1,7 +0,0 @@
-#!/bin/sh
-# devtmpfs does not get automounted for initramfs
-/bin/mount -t devtmpfs devtmpfs /dev
-exec 0</dev/console
-exec 1>/dev/console
-exec 2>/dev/console
-exec /sbin/init $*

+ 11 - 24
fs/initramfs/initramfs.mk

@@ -1,36 +1,23 @@
 #############################################################
 #############################################################
 #
 #
-# 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
+# Build a kernel with an integrated initial ramdisk
+# filesystem based on cpio.
 #
 #
 #############################################################
 #############################################################
 
 
-ifeq ($(BR2_ROOTFS_DEVICE_CREATION_STATIC),y)
+ROOTFS_INITRAMFS_DEPENDENCIES += rootfs-cpio
 
 
-define ROOTFS_INITRAMFS_ADD_INIT
-	if [ ! -e $(TARGET_DIR)/init ]; then \
-		ln -sf sbin/init $(TARGET_DIR)/init; \
-	fi
-endef
+ROOTFS_INITRAMFS_POST_TARGETS += linux26-rebuild-with-initramfs
 
 
-else
-# devtmpfs does not get automounted when initramfs is used.
-# Add a pre-init script to mount it before running init
-define ROOTFS_INITRAMFS_ADD_INIT
-	if [ ! -e $(TARGET_DIR)/init ]; then \
-		$(INSTALL) -m 0755 fs/initramfs/init $(TARGET_DIR)/init; \
-	fi
-endef
 
 
-endif # BR2_ROOTFS_DEVICE_CREATION_STATIC
+# The generic fs infrastructure isn't very useful here.
 
 
-ROOTFS_INITRAMFS_PRE_GEN_HOOKS += ROOTFS_INITRAMFS_ADD_INIT
+rootfs-initramfs: $(ROOTFS_INITRAMFS_DEPENDENCIES) $(ROOTFS_INITRAMFS_POST_TARGETS)
 
 
-define ROOTFS_INITRAMFS_CMD
-	$(SHELL) fs/initramfs/gen_initramfs_list.sh -u 0 -g 0 $(TARGET_DIR) > $$@
-endef
+rootfs-initramfs-show-depends:
+	@echo $(ROOTFS_INITRAMFS_DEPENDENCIES)
 
 
-ROOTFS_INITRAMFS_POST_TARGETS += linux26-rebuild-with-initramfs
+ifeq ($(BR2_TARGET_ROOTFS_INITRAMFS),y)
+TARGETS += rootfs-initramfs
+endif
 
 
-$(eval $(call ROOTFS_TARGET,initramfs))

+ 7 - 10
linux/linux.mk

@@ -126,13 +126,13 @@ define LINUX_CONFIGURE_CMDS
 		$(call KCONFIG_ENABLE_OPT,CONFIG_AEABI,$(@D)/.config),
 		$(call KCONFIG_ENABLE_OPT,CONFIG_AEABI,$(@D)/.config),
 		$(call KCONFIG_DISABLE_OPT,CONFIG_AEABI,$(@D)/.config))
 		$(call KCONFIG_DISABLE_OPT,CONFIG_AEABI,$(@D)/.config))
 	# As the kernel gets compiled before root filesystems are
 	# As the kernel gets compiled before root filesystems are
-	# built, we create a fake initramfs file list. It'll be
-	# replaced later by the real list, and the kernel will be
+	# built, we create a fake cpio file. It'll be
+	# replaced later by the real cpio archive, and the kernel will be
 	# rebuilt using the linux26-rebuild-with-initramfs target.
 	# rebuilt using the linux26-rebuild-with-initramfs target.
 	$(if $(BR2_TARGET_ROOTFS_INITRAMFS),
 	$(if $(BR2_TARGET_ROOTFS_INITRAMFS),
-		touch $(BINARIES_DIR)/rootfs.initramfs
+		touch $(BINARIES_DIR)/rootfs.cpio
 		$(call KCONFIG_ENABLE_OPT,CONFIG_BLK_DEV_INITRD,$(@D)/.config)
 		$(call KCONFIG_ENABLE_OPT,CONFIG_BLK_DEV_INITRD,$(@D)/.config)
-		$(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_SOURCE,\"$(BINARIES_DIR)/rootfs.initramfs\",$(@D)/.config)
+		$(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_SOURCE,\"$(BINARIES_DIR)/rootfs.cpio\",$(@D)/.config)
 		$(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_UID,0,$(@D)/.config)
 		$(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_UID,0,$(@D)/.config)
 		$(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_GID,0,$(@D)/.config)
 		$(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_GID,0,$(@D)/.config)
 		$(call KCONFIG_DISABLE_OPT,CONFIG_INITRAMFS_COMPRESSION_NONE,$(@D)/.config)
 		$(call KCONFIG_DISABLE_OPT,CONFIG_INITRAMFS_COMPRESSION_NONE,$(@D)/.config)
@@ -190,13 +190,10 @@ linux-savedefconfig linux26-savedefconfig: dirs $(LINUX_DIR)/.stamp_configured
 	$(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) \
 	$(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) \
 		$(subst linux-,,$(subst linux26-,,$@))
 		$(subst linux-,,$(subst linux26-,,$@))
 
 
-# Support for rebuilding the kernel after the initramfs file list has
-# been generated in $(BINARIES_DIR)/rootfs.initramfs.
-$(LINUX_DIR)/.stamp_initramfs_rebuilt: $(LINUX_DIR)/.stamp_target_installed $(LINUX_DIR)/.stamp_images_installed $(BINARIES_DIR)/rootfs.initramfs
+# Support for rebuilding the kernel after the cpio archive has
+# been generated in $(BINARIES_DIR)/rootfs.cpio.
+$(LINUX_DIR)/.stamp_initramfs_rebuilt: $(LINUX_DIR)/.stamp_target_installed $(LINUX_DIR)/.stamp_images_installed $(BINARIES_DIR)/rootfs.cpio
 	@$(call MESSAGE,"Rebuilding kernel with initramfs")
 	@$(call MESSAGE,"Rebuilding kernel with initramfs")
-	# Remove the previously generated initramfs which was empty,
-	# to make sure the kernel will actually regenerate it.
-	$(RM) -f $(@D)/usr/initramfs_data.cpio*
 	# Build the kernel.
 	# Build the kernel.
 	$(TARGET_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_IMAGE_NAME)
 	$(TARGET_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_IMAGE_NAME)
 	# Copy the kernel image to its final destination
 	# Copy the kernel image to its final destination