aboutsummaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
Diffstat (limited to 'usr')
-rw-r--r--usr/.gitignore2
-rw-r--r--usr/Kconfig54
-rw-r--r--usr/Makefile46
-rw-r--r--usr/gen_init_cpio.c103
-rw-r--r--usr/initramfs_data.S22
5 files changed, 185 insertions, 42 deletions
diff --git a/usr/.gitignore b/usr/.gitignore
index 69b2e89fa16..8e48117a3f3 100644
--- a/usr/.gitignore
+++ b/usr/.gitignore
@@ -4,5 +4,7 @@
gen_init_cpio
initramfs_data.cpio
initramfs_data.cpio.gz
+initramfs_data.cpio.bz2
+initramfs_data.cpio.lzma
initramfs_list
include
diff --git a/usr/Kconfig b/usr/Kconfig
index 86cecb59dd0..2d4c77eecf2 100644
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -44,3 +44,57 @@ config INITRAMFS_ROOT_GID
owned by group root in the initial ramdisk image.
If you are not sure, leave it set to "0".
+
+config RD_GZIP
+ bool "Support initial ramdisks compressed using gzip" if EXPERT
+ default y
+ depends on BLK_DEV_INITRD
+ select DECOMPRESS_GZIP
+ help
+ Support loading of a gzip encoded initial ramdisk or cpio buffer.
+ If unsure, say Y.
+
+config RD_BZIP2
+ bool "Support initial ramdisks compressed using bzip2" if EXPERT
+ default !EXPERT
+ depends on BLK_DEV_INITRD
+ select DECOMPRESS_BZIP2
+ help
+ Support loading of a bzip2 encoded initial ramdisk or cpio buffer
+ If unsure, say N.
+
+config RD_LZMA
+ bool "Support initial ramdisks compressed using LZMA" if EXPERT
+ default !EXPERT
+ depends on BLK_DEV_INITRD
+ select DECOMPRESS_LZMA
+ help
+ Support loading of a LZMA encoded initial ramdisk or cpio buffer
+ If unsure, say N.
+
+config RD_XZ
+ bool "Support initial ramdisks compressed using XZ" if EXPERT
+ default !EXPERT
+ depends on BLK_DEV_INITRD
+ select DECOMPRESS_XZ
+ help
+ Support loading of a XZ encoded initial ramdisk or cpio buffer.
+ If unsure, say N.
+
+config RD_LZO
+ bool "Support initial ramdisks compressed using LZO" if EXPERT
+ default !EXPERT
+ depends on BLK_DEV_INITRD
+ select DECOMPRESS_LZO
+ help
+ Support loading of a LZO encoded initial ramdisk or cpio buffer
+ If unsure, say N.
+
+config RD_LZ4
+ bool "Support initial ramdisks compressed using LZ4" if EXPERT
+ default !EXPERT
+ depends on BLK_DEV_INITRD
+ select DECOMPRESS_LZ4
+ help
+ Support loading of a LZ4 encoded initial ramdisk or cpio buffer
+ If unsure, say N.
diff --git a/usr/Makefile b/usr/Makefile
index 201f27f8cba..e767f019acc 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -6,13 +6,33 @@ klibcdirs:;
PHONY += klibcdirs
+# Bzip2
+suffix_$(CONFIG_RD_BZIP2) = .bz2
+
+# Lzma
+suffix_$(CONFIG_RD_LZMA) = .lzma
+
+# XZ
+suffix_$(CONFIG_RD_XZ) = .xz
+
+# Lzo
+suffix_$(CONFIG_RD_LZO) = .lzo
+
+# Lz4
+suffix_$(CONFIG_RD_LZ4) = .lz4
+
+# Gzip
+suffix_$(CONFIG_RD_GZIP) = .gz
+
+AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/initramfs_data.cpio$(suffix_y)"
+
# Generate builtin.o based on initramfs_data.o
obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
-# initramfs_data.o contains the initramfs_data.cpio.gz image.
+# initramfs_data.o contains the compressed initramfs_data.cpio image.
# The image is included using .incbin, a dependency which is not
# tracked automatically.
-$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE
+$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE
#####
# Generate the initramfs cpio archive
@@ -25,28 +45,30 @@ ramfs-args := \
$(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
$(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
-# .initramfs_data.cpio.gz.d is used to identify all files included
+# .initramfs_data.cpio.d is used to identify all files included
# in initramfs and to detect if any files are added/removed.
# Removed files are identified by directory timestamp being updated
# The dependency list is generated by gen_initramfs.sh -l
-ifneq ($(wildcard $(obj)/.initramfs_data.cpio.gz.d),)
- include $(obj)/.initramfs_data.cpio.gz.d
+ifneq ($(wildcard $(obj)/.initramfs_data.cpio.d),)
+ include $(obj)/.initramfs_data.cpio.d
endif
quiet_cmd_initfs = GEN $@
cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input)
-targets := initramfs_data.cpio.gz
+targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 \
+ initramfs_data.cpio.lzma initramfs_data.cpio.xz \
+ initramfs_data.cpio.lzo initramfs_data.cpio.lz4 \
+ initramfs_data.cpio
# do not try to update files included in initramfs
$(deps_initramfs): ;
$(deps_initramfs): klibcdirs
-# We rebuild initramfs_data.cpio.gz if:
-# 1) Any included file is newer then initramfs_data.cpio.gz
+# We rebuild initramfs_data.cpio if:
+# 1) Any included file is newer then initramfs_data.cpio
# 2) There are changes in which files are included (added or deleted)
-# 3) If gen_init_cpio are newer than initramfs_data.cpio.gz
+# 3) If gen_init_cpio are newer than initramfs_data.cpio
# 4) arguments to gen_initramfs.sh changes
-$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
- $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.gz.d
+$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
+ $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d
$(call if_changed,initfs)
-
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 7abc07f0fcd..225ad244cf8 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -22,6 +22,7 @@
static unsigned int offset;
static unsigned int ino = 721;
+static time_t default_mtime;
struct file_handler {
const char *type;
@@ -102,8 +103,9 @@ static int cpio_mkslink(const char *name, const char *target,
unsigned int mode, uid_t uid, gid_t gid)
{
char s[256];
- time_t mtime = time(NULL);
+ if (name[0] == '/')
+ name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
@@ -112,7 +114,7 @@ static int cpio_mkslink(const char *name, const char *target,
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
(unsigned)strlen(target)+1, /* filesize */
3, /* major */
1, /* minor */
@@ -150,8 +152,9 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
char s[256];
- time_t mtime = time(NULL);
+ if (name[0] == '/')
+ name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
@@ -160,7 +163,7 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
(long) uid, /* uid */
(long) gid, /* gid */
2, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
@@ -238,13 +241,14 @@ static int cpio_mknod(const char *name, unsigned int mode,
unsigned int maj, unsigned int min)
{
char s[256];
- time_t mtime = time(NULL);
if (dev_type == 'b')
mode |= S_IFBLK;
else
mode |= S_IFCHR;
+ if (name[0] == '/')
+ name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
@@ -253,7 +257,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
@@ -299,22 +303,22 @@ static int cpio_mkfile(const char *name, const char *location,
int retval;
int rc = -1;
int namesize;
- int i;
+ unsigned int i;
mode |= S_IFREG;
- retval = stat (location, &buf);
- if (retval) {
- fprintf (stderr, "File %s could not be located\n", location);
- goto error;
- }
-
file = open (location, O_RDONLY);
if (file < 0) {
fprintf (stderr, "File %s could not be opened for reading\n", location);
goto error;
}
+ retval = fstat(file, &buf);
+ if (retval) {
+ fprintf(stderr, "File %s could not be stat()'ed\n", location);
+ goto error;
+ }
+
filebuf = malloc(buf.st_size);
if (!filebuf) {
fprintf (stderr, "out of memory\n");
@@ -332,6 +336,8 @@ static int cpio_mkfile(const char *name, const char *location,
/* data goes on last link */
if (i == nlinks) size = buf.st_size;
+ if (name[0] == '/')
+ name++;
namesize = strlen(name) + 1;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08lX%08X%08X%08X%08X%08X%08X",
@@ -354,7 +360,10 @@ static int cpio_mkfile(const char *name, const char *location,
push_pad();
if (size) {
- fwrite(filebuf, size, 1, stdout);
+ if (fwrite(filebuf, size, 1, stdout) != 1) {
+ fprintf(stderr, "writing filebuf failed\n");
+ goto error;
+ }
offset += size;
push_pad();
}
@@ -370,6 +379,23 @@ error:
return rc;
}
+static char *cpio_replace_env(char *new_location)
+{
+ char expanded[PATH_MAX + 1];
+ char *start, *end, *var;
+
+ while ((start = strstr(new_location, "${")) &&
+ (end = strchr(start + 2, '}'))) {
+ *start = *end = 0;
+ var = getenv(start + 2);
+ snprintf(expanded, sizeof expanded, "%s%s%s",
+ new_location, var ? var : "", end + 1);
+ strcpy(new_location, expanded);
+ }
+
+ return new_location;
+}
+
static int cpio_mkfile_line(const char *line)
{
char name[PATH_MAX + 1];
@@ -415,16 +441,17 @@ static int cpio_mkfile_line(const char *line)
} else {
dname = name;
}
- rc = cpio_mkfile(dname, location, mode, uid, gid, nlinks);
+ rc = cpio_mkfile(dname, cpio_replace_env(location),
+ mode, uid, gid, nlinks);
fail:
if (dname_len) free(dname);
return rc;
}
-void usage(const char *prog)
+static void usage(const char *prog)
{
fprintf(stderr, "Usage:\n"
- "\t%s <cpio_list>\n"
+ "\t%s [-t <timestamp>] <cpio_list>\n"
"\n"
"<cpio_list> is a file containing newline separated entries that\n"
"describe the files to be included in the initramfs archive:\n"
@@ -439,6 +466,7 @@ void usage(const char *prog)
"\n"
"<name> name of the file/dir/nod/etc in the archive\n"
"<location> location of the file in the current filesystem\n"
+ " expands shell variables quoted with ${}\n"
"<target> link target\n"
"<mode> mode/permissions of the file\n"
"<uid> user id (0=root)\n"
@@ -454,7 +482,11 @@ void usage(const char *prog)
"nod /dev/console 0600 0 0 c 5 1\n"
"dir /root 0700 0 0\n"
"dir /sbin 0755 0 0\n"
- "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n",
+ "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n"
+ "\n"
+ "<timestamp> is time in seconds since Epoch that will be used\n"
+ "as mtime for symlinks, special files and directories. The default\n"
+ "is to use the current time for these entries.\n",
prog);
}
@@ -492,17 +524,42 @@ int main (int argc, char *argv[])
char *args, *type;
int ec = 0;
int line_nr = 0;
+ const char *filename;
- if (2 != argc) {
+ default_mtime = time(NULL);
+ while (1) {
+ int opt = getopt(argc, argv, "t:h");
+ char *invalid;
+
+ if (opt == -1)
+ break;
+ switch (opt) {
+ case 't':
+ default_mtime = strtol(optarg, &invalid, 10);
+ if (!*optarg || *invalid) {
+ fprintf(stderr, "Invalid timestamp: %s\n",
+ optarg);
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'h':
+ case '?':
+ usage(argv[0]);
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ if (argc - optind != 1) {
usage(argv[0]);
exit(1);
}
-
- if (!strcmp(argv[1], "-"))
+ filename = argv[optind];
+ if (!strcmp(filename, "-"))
cpio_list = stdin;
- else if (! (cpio_list = fopen(argv[1], "r"))) {
+ else if (!(cpio_list = fopen(filename, "r"))) {
fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
- argv[1], strerror(errno));
+ filename, strerror(errno));
usage(argv[0]);
exit(1);
}
diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
index c2e1ad424f4..c14322d1c0c 100644
--- a/usr/initramfs_data.S
+++ b/usr/initramfs_data.S
@@ -11,11 +11,7 @@
-T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
ld -m elf_i386 -r -o built-in.o initramfs_data.o
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
+ For including the .init.ramfs sections, see include/asm-generic/vmlinux.lds.
The above example is for i386 - the parameters vary from architectures.
Eventually look up LDFLAGS_BLOB in an older version of the
@@ -25,6 +21,18 @@ SECTIONS
in the ELF header, as required by certain architectures.
*/
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.gz"
+#include <linux/stringify.h>
+#include <asm-generic/vmlinux.lds.h>
+.section .init.ramfs,"a"
+__irf_start:
+.incbin __stringify(INITRAMFS_IMAGE)
+__irf_end:
+.section .init.ramfs.info,"a"
+.globl VMLINUX_SYMBOL(__initramfs_size)
+VMLINUX_SYMBOL(__initramfs_size):
+#ifdef CONFIG_64BIT
+ .quad __irf_end - __irf_start
+#else
+ .long __irf_end - __irf_start
+#endif