Initial commit: Linux kernel 4.19 for Unplugged OS

This commit is contained in:
ziv committed 2025-10-06 13:52:42 +00:00
commit d30235b04c
80519 files changed
+35800681

No files matched your search

+235
View File
@@ -0,0 +1,235 @@
# SPDX-License-Identifier: GPL-2.0
#
# Configuration for initramfs
#
config INITRAMFS_SOURCE
string "Initramfs source file(s)"
default ""
help
This can be either a single cpio archive with a .cpio suffix or a
space-separated list of directories and files for building the
initramfs image. A cpio archive should contain a filesystem archive
to be used as an initramfs image. Directories should contain a
filesystem layout to be included in the initramfs image. Files
should contain entries according to the format described by the
"usr/gen_init_cpio" program in the kernel tree.
When multiple directories and files are specified then the
initramfs image will be the aggregate of all of them.
See <file:Documentation/early-userspace/README> for more details.
If you are not sure, leave it blank.
config INITRAMFS_FORCE
bool "Ignore the initramfs passed by the bootloader"
depends on CMDLINE_EXTEND || CMDLINE_FORCE
help
This option causes the kernel to ignore the initramfs image
(or initrd image) passed to it by the bootloader. This is
analogous to CMDLINE_FORCE, which is found on some architectures,
and is useful if you cannot or don't want to change the image
your bootloader passes to the kernel.
config INITRAMFS_ROOT_UID
int "User ID to map to 0 (user root)"
depends on INITRAMFS_SOURCE!=""
default "0"
help
If INITRAMFS_SOURCE points to a directory, files owned by this UID
(-1 = current user) will be owned by root in the resulting image.
If you are not sure, leave it set to "0".
config INITRAMFS_ROOT_GID
int "Group ID to map to 0 (group root)"
depends on INITRAMFS_SOURCE!=""
default "0"
help
If INITRAMFS_SOURCE points to a directory, files owned by this GID
(-1 = current group) will be owned by root in the resulting image.
If you are not sure, leave it set to "0".
config RD_GZIP
bool "Support initial ramdisk/ramfs compressed using gzip"
depends on BLK_DEV_INITRD
default y
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 ramdisk/ramfs compressed using bzip2"
default y
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 ramdisk/ramfs compressed using LZMA"
default y
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 ramdisk/ramfs compressed using XZ"
depends on BLK_DEV_INITRD
default y
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 ramdisk/ramfs compressed using LZO"
default y
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 ramdisk/ramfs compressed using LZ4"
default y
depends on BLK_DEV_INITRD
select DECOMPRESS_LZ4
help
Support loading of a LZ4 encoded initial ramdisk or cpio buffer
If unsure, say N.
choice
prompt "Built-in initramfs compression mode"
depends on INITRAMFS_SOURCE!=""
optional
help
This option allows you to decide by which algorithm the builtin
initramfs will be compressed. Several compression algorithms are
available, which differ in efficiency, compression and
decompression speed. Compression speed is only relevant
when building a kernel. Decompression speed is relevant at
each boot. Also the memory usage during decompression may become
relevant on memory constrained systems. This is usually based on the
dictionary size of the algorithm with algorithms like XZ and LZMA
featuring large dictionary sizes.
High compression options are mostly useful for users who are
low on RAM, since it reduces the memory consumption during
boot.
Keep in mind that your build system needs to provide the appropriate
compression tool to compress the generated initram cpio file for
embedding.
If in doubt, select 'None'
config INITRAMFS_COMPRESSION_GZIP
bool "Gzip"
depends on RD_GZIP
help
Use the old and well tested gzip compression algorithm. Gzip provides
a good balance between compression ratio and decompression speed and
has a reasonable compression speed. It is also more likely to be
supported by your build system as the gzip tool is present by default
on most distros.
config INITRAMFS_COMPRESSION_BZIP2
bool "Bzip2"
depends on RD_BZIP2
help
It's compression ratio and speed is intermediate. Decompression speed
is slowest among the choices. The initramfs size is about 10% smaller
with bzip2, in comparison to gzip. Bzip2 uses a large amount of
memory. For modern kernels you will need at least 8MB RAM or more for
booting.
If you choose this, keep in mind that you need to have the bzip2 tool
available to be able to compress the initram.
config INITRAMFS_COMPRESSION_LZMA
bool "LZMA"
depends on RD_LZMA
help
This algorithm's compression ratio is best but has a large dictionary
size which might cause issues in memory constrained systems.
Decompression speed is between the other choices. Compression is
slowest. The initramfs size is about 33% smaller with LZMA in
comparison to gzip.
If you choose this, keep in mind that you may need to install the xz
or lzma tools to be able to compress the initram.
config INITRAMFS_COMPRESSION_XZ
bool "XZ"
depends on RD_XZ
help
XZ uses the LZMA2 algorithm and has a large dictionary which may cause
problems on memory constrained systems. The initramfs size is about
30% smaller with XZ in comparison to gzip. Decompression speed is
better than that of bzip2 but worse than gzip and LZO. Compression is
slow.
If you choose this, keep in mind that you may need to install the xz
tool to be able to compress the initram.
config INITRAMFS_COMPRESSION_LZO
bool "LZO"
depends on RD_LZO
help
It's compression ratio is the second poorest amongst the choices. The
kernel size is about 10% bigger than gzip. Despite that, it's
decompression speed is the second fastest and it's compression speed
is quite fast too.
If you choose this, keep in mind that you may need to install the lzop
tool to be able to compress the initram.
config INITRAMFS_COMPRESSION_LZ4
bool "LZ4"
depends on RD_LZ4
help
It's compression ratio is the poorest amongst the choices. The kernel
size is about 15% bigger than gzip; however its decompression speed
is the fastest.
If you choose this, keep in mind that most distros don't provide lz4
by default which could cause a build failure.
config INITRAMFS_COMPRESSION_NONE
bool "None"
help
Do not compress the built-in initramfs at all. This may sound wasteful
in space, but, you should be aware that the built-in initramfs will be
compressed at a later stage anyways along with the rest of the kernel,
on those architectures that support this. However, not compressing the
initramfs may lead to slightly higher memory consumption during a
short time at boot, while both the cpio image and the unpacked
filesystem image will be present in memory simultaneously
endchoice
config INITRAMFS_COMPRESSION
depends on INITRAMFS_SOURCE!=""
string
default "" if INITRAMFS_COMPRESSION_NONE
default ".gz" if INITRAMFS_COMPRESSION_GZIP
default ".bz2" if INITRAMFS_COMPRESSION_BZIP2
default ".lzma" if INITRAMFS_COMPRESSION_LZMA
default ".xz" if INITRAMFS_COMPRESSION_XZ
default ".lzo" if INITRAMFS_COMPRESSION_LZO
default ".lz4" if INITRAMFS_COMPRESSION_LZ4
default ".gz" if RD_GZIP
default ".lz4" if RD_LZ4
default ".lzo" if RD_LZO
default ".xz" if RD_XZ
default ".lzma" if RD_LZMA
default ".bz2" if RD_BZIP2
default ""
+61
View File
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0
#
# kbuild file for usr/ - including initramfs image
#
klibcdirs:;
PHONY += klibcdirs
suffix_y = $(subst $\",,$(CONFIG_INITRAMFS_COMPRESSION))
datafile_y = initramfs_data.cpio$(suffix_y)
datafile_d_y = .$(datafile_y).d
AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/$(datafile_y)"
# clean rules do not have CONFIG_INITRAMFS_COMPRESSION. So clean up after all
# possible compression formats.
clean-files += initramfs_data.cpio*
# Generate builtin.o based on initramfs_data.o
obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
# 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)/$(datafile_y) FORCE
#####
# Generate the initramfs cpio archive
hostprogs-y := gen_init_cpio
initramfs := $(CONFIG_SHELL) $(srctree)/$(src)/gen_initramfs_list.sh
ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \
$(shell echo $(CONFIG_INITRAMFS_SOURCE)),-d)
ramfs-args := \
$(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
$(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
# $(datafile_d_y) 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)/$(datafile_d_y)),)
include $(obj)/$(datafile_d_y)
endif
quiet_cmd_initfs = GEN $@
cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input)
targets := $(datafile_y)
# do not try to update files included in initramfs
$(deps_initramfs): ;
$(deps_initramfs): klibcdirs
# 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
# 4) arguments to gen_initramfs.sh changes
$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
$(Q)$(initramfs) -l $(ramfs-input) > $(obj)/$(datafile_d_y)
$(call if_changed,initfs)
+624
View File
@@ -0,0 +1,624 @@
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
/*
* Original work by Jeff Garzik
*
* External file lists, symlink, pipe and fifo support by Thayne Harbaugh
* Hard link support by Luciano Rocha
*/
#define xstr(s) #s
#define str(s) xstr(s)
static unsigned int offset;
static unsigned int ino = 721;
static time_t default_mtime;
struct file_handler {
const char *type;
int (*handler)(const char *line);
};
static void push_string(const char *name)
{
unsigned int name_len = strlen(name) + 1;
fputs(name, stdout);
putchar(0);
offset += name_len;
}
static void push_pad (void)
{
while (offset & 3) {
putchar(0);
offset++;
}
}
static void push_rest(const char *name)
{
unsigned int name_len = strlen(name) + 1;
unsigned int tmp_ofs;
fputs(name, stdout);
putchar(0);
offset += name_len;
tmp_ofs = name_len + 110;
while (tmp_ofs & 3) {
putchar(0);
offset++;
tmp_ofs++;
}
}
static void push_hdr(const char *s)
{
fputs(s, stdout);
offset += 110;
}
static void cpio_trailer(void)
{
char s[256];
const char name[] = "TRAILER!!!";
sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
0, /* ino */
0, /* mode */
(long) 0, /* uid */
(long) 0, /* gid */
1, /* nlink */
(long) 0, /* mtime */
0, /* filesize */
0, /* major */
0, /* minor */
0, /* rmajor */
0, /* rminor */
(unsigned)strlen(name)+1, /* namesize */
0); /* chksum */
push_hdr(s);
push_rest(name);
while (offset % 512) {
putchar(0);
offset++;
}
}
static int cpio_mkslink(const char *name, const char *target,
unsigned int mode, uid_t uid, gid_t gid)
{
char s[256];
if (name[0] == '/')
name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
ino++, /* ino */
S_IFLNK | mode, /* mode */
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
(long) default_mtime, /* mtime */
(unsigned)strlen(target)+1, /* filesize */
3, /* major */
1, /* minor */
0, /* rmajor */
0, /* rminor */
(unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
push_hdr(s);
push_string(name);
push_pad();
push_string(target);
push_pad();
return 0;
}
static int cpio_mkslink_line(const char *line)
{
char name[PATH_MAX + 1];
char target[PATH_MAX + 1];
unsigned int mode;
int uid;
int gid;
int rc = -1;
if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, target, &mode, &uid, &gid)) {
fprintf(stderr, "Unrecognized dir format '%s'", line);
goto fail;
}
rc = cpio_mkslink(name, target, mode, uid, gid);
fail:
return rc;
}
static int cpio_mkgeneric(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
char s[256];
if (name[0] == '/')
name++;
sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
"070701", /* magic */
ino++, /* ino */
mode, /* mode */
(long) uid, /* uid */
(long) gid, /* gid */
2, /* nlink */
(long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
0, /* rmajor */
0, /* rminor */
(unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
push_hdr(s);
push_rest(name);
return 0;
}
enum generic_types {
GT_DIR,
GT_PIPE,
GT_SOCK
};
struct generic_type {
const char *type;
mode_t mode;
};
static struct generic_type generic_type_table[] = {
[GT_DIR] = {
.type = "dir",
.mode = S_IFDIR
},
[GT_PIPE] = {
.type = "pipe",
.mode = S_IFIFO
},
[GT_SOCK] = {
.type = "sock",
.mode = S_IFSOCK
}
};
static int cpio_mkgeneric_line(const char *line, enum generic_types gt)
{
char name[PATH_MAX + 1];
unsigned int mode;
int uid;
int gid;
int rc = -1;
if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
fprintf(stderr, "Unrecognized %s format '%s'",
line, generic_type_table[gt].type);
goto fail;
}
mode |= generic_type_table[gt].mode;
rc = cpio_mkgeneric(name, mode, uid, gid);
fail:
return rc;
}
static int cpio_mkdir_line(const char *line)
{
return cpio_mkgeneric_line(line, GT_DIR);
}
static int cpio_mkpipe_line(const char *line)
{
return cpio_mkgeneric_line(line, GT_PIPE);
}
static int cpio_mksock_line(const char *line)
{
return cpio_mkgeneric_line(line, GT_SOCK);
}
static int cpio_mknod(const char *name, unsigned int mode,
uid_t uid, gid_t gid, char dev_type,
unsigned int maj, unsigned int min)
{
char s[256];
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 */
ino++, /* ino */
mode, /* mode */
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
(long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
maj, /* rmajor */
min, /* rminor */
(unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
push_hdr(s);
push_rest(name);
return 0;
}
static int cpio_mknod_line(const char *line)
{
char name[PATH_MAX + 1];
unsigned int mode;
int uid;
int gid;
char dev_type;
unsigned int maj;
unsigned int min;
int rc = -1;
if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
fprintf(stderr, "Unrecognized nod format '%s'", line);
goto fail;
}
rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min);
fail:
return rc;
}
static int cpio_mkfile(const char *name, const char *location,
unsigned int mode, uid_t uid, gid_t gid,
unsigned int nlinks)
{
char s[256];
char *filebuf = NULL;
struct stat buf;
long size;
int file = -1;
int retval;
int rc = -1;
int namesize;
unsigned int i;
mode |= S_IFREG;
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");
goto error;
}
retval = read (file, filebuf, buf.st_size);
if (retval < 0) {
fprintf (stderr, "Can not read %s file\n", location);
goto error;
}
size = 0;
for (i = 1; i <= nlinks; i++) {
/* 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",
"070701", /* magic */
ino, /* ino */
mode, /* mode */
(long) uid, /* uid */
(long) gid, /* gid */
nlinks, /* nlink */
(long) buf.st_mtime, /* mtime */
size, /* filesize */
3, /* major */
1, /* minor */
0, /* rmajor */
0, /* rminor */
namesize, /* namesize */
0); /* chksum */
push_hdr(s);
push_string(name);
push_pad();
if (size) {
if (fwrite(filebuf, size, 1, stdout) != 1) {
fprintf(stderr, "writing filebuf failed\n");
goto error;
}
offset += size;
push_pad();
}
name += namesize;
}
ino++;
rc = 0;
error:
if (filebuf) free(filebuf);
if (file >= 0) close(file);
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];
char *dname = NULL; /* malloc'ed buffer for hard links */
char location[PATH_MAX + 1];
unsigned int mode;
int uid;
int gid;
int nlinks = 1;
int end = 0, dname_len = 0;
int rc = -1;
if (5 > sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX)
"s %o %d %d %n",
name, location, &mode, &uid, &gid, &end)) {
fprintf(stderr, "Unrecognized file format '%s'", line);
goto fail;
}
if (end && isgraph(line[end])) {
int len;
int nend;
dname = malloc(strlen(line));
if (!dname) {
fprintf (stderr, "out of memory (%d)\n", dname_len);
goto fail;
}
dname_len = strlen(name) + 1;
memcpy(dname, name, dname_len);
do {
nend = 0;
if (sscanf(line + end, "%" str(PATH_MAX) "s %n",
name, &nend) < 1)
break;
len = strlen(name) + 1;
memcpy(dname + dname_len, name, len);
dname_len += len;
nlinks++;
end += nend;
} while (isgraph(line[end]));
} else {
dname = name;
}
rc = cpio_mkfile(dname, cpio_replace_env(location),
mode, uid, gid, nlinks);
fail:
if (dname_len) free(dname);
return rc;
}
static void usage(const char *prog)
{
fprintf(stderr, "Usage:\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"
"\n"
"# a comment\n"
"file <name> <location> <mode> <uid> <gid> [<hard links>]\n"
"dir <name> <mode> <uid> <gid>\n"
"nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
"slink <name> <target> <mode> <uid> <gid>\n"
"pipe <name> <mode> <uid> <gid>\n"
"sock <name> <mode> <uid> <gid>\n"
"\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"
"<gid> group id (0=root)\n"
"<dev_type> device type (b=block, c=character)\n"
"<maj> major number of nod\n"
"<min> minor number of nod\n"
"<hard links> space separated list of other links to file\n"
"\n"
"example:\n"
"# A simple initramfs\n"
"dir /dev 0755 0 0\n"
"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"
"\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);
}
struct file_handler file_handler_table[] = {
{
.type = "file",
.handler = cpio_mkfile_line,
}, {
.type = "nod",
.handler = cpio_mknod_line,
}, {
.type = "dir",
.handler = cpio_mkdir_line,
}, {
.type = "slink",
.handler = cpio_mkslink_line,
}, {
.type = "pipe",
.handler = cpio_mkpipe_line,
}, {
.type = "sock",
.handler = cpio_mksock_line,
}, {
.type = NULL,
.handler = NULL,
}
};
#define LINE_SIZE (2 * PATH_MAX + 50)
int main (int argc, char *argv[])
{
FILE *cpio_list;
char line[LINE_SIZE];
char *args, *type;
int ec = 0;
int line_nr = 0;
const char *filename;
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);
}
filename = argv[optind];
if (!strcmp(filename, "-"))
cpio_list = stdin;
else if (!(cpio_list = fopen(filename, "r"))) {
fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
filename, strerror(errno));
usage(argv[0]);
exit(1);
}
while (fgets(line, LINE_SIZE, cpio_list)) {
int type_idx;
size_t slen = strlen(line);
line_nr++;
if ('#' == *line) {
/* comment - skip to next line */
continue;
}
if (! (type = strtok(line, " \t"))) {
fprintf(stderr,
"ERROR: incorrect format, could not locate file type line %d: '%s'\n",
line_nr, line);
ec = -1;
break;
}
if ('\n' == *type) {
/* a blank line */
continue;
}
if (slen == strlen(type)) {
/* must be an empty line */
continue;
}
if (! (args = strtok(NULL, "\n"))) {
fprintf(stderr,
"ERROR: incorrect format, newline required line %d: '%s'\n",
line_nr, line);
ec = -1;
}
for (type_idx = 0; file_handler_table[type_idx].type; type_idx++) {
int rc;
if (! strcmp(line, file_handler_table[type_idx].type)) {
if ((rc = file_handler_table[type_idx].handler(args))) {
ec = rc;
fprintf(stderr, " line %d\n", line_nr);
}
break;
}
}
if (NULL == file_handler_table[type_idx].type) {
fprintf(stderr, "unknown file type line %d: '%s'\n",
line_nr, line);
}
}
if (ec == 0)
cpio_trailer();
exit(ec);
}
+328
View File
@@ -0,0 +1,328 @@
#!/bin/sh
# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
#
# Released under the terms of the GNU GPL
#
# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
# the cpio archive, and then compresses it.
# The script may also be used to generate the inputfile used for gen_init_cpio
# This script assumes that gen_init_cpio is located in usr/ directory
# error out on errors
set -e
usage() {
cat << EOF
Usage:
$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
-o <file> Create compressed initramfs file named <file> using
gen_init_cpio and compressor depending on the extension
-u <uid> User ID to map to user ID 0 (root).
<uid> is only meaningful if <cpio_source> is a
directory. "squash" forces all files to uid 0.
-g <gid> Group ID to map to group ID 0 (root).
<gid> is only meaningful if <cpio_source> is a
directory. "squash" forces all files to gid 0.
<cpio_source> File list or directory for cpio archive.
If <cpio_source> is a .cpio file it will be used
as direct input to initramfs.
-d Output the default cpio list.
All options except -o and -l may be repeated and are interpreted
sequentially and immediately. -u and -g states are preserved across
<cpio_source> options so an explicit "-u 0 -g 0" is required
to reset the root/group mapping.
EOF
}
# awk style field access
# $1 - field number; rest is argument string
field() {
shift $1 ; echo $1
}
list_default_initramfs() {
# echo usr/kinit/kinit
:
}
default_initramfs() {
cat <<-EOF >> ${output}
# 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
# file /kinit usr/kinit/kinit 0755 0 0
# slink /init kinit 0755 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
}
list_print_mtime() {
:
}
print_mtime() {
local my_mtime="0"
if [ -e "$1" ]; then
my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
fi
echo "# Last modified: ${my_mtime}" >> ${output}
echo "" >> ${output}
}
list_parse() {
if [ -L "$1" ]; then
return
fi
echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
}
# for each file print a line in following format
# <filetype> <name> <path to file> <octal mode> <uid> <gid>
# for links, devices etc the format differs. See gen_init_cpio for details
parse() {
local location="$1"
local name="/${location#${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
[ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
[ "$root_gid" = "squash" ] && gid=0 || [ "$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 dev=`LC_ALL=C ls -l "${location}"`
local maj=`field 5 ${dev}`
local min=`field 6 ${dev}`
maj=${maj%,}
[ -b "${location}" ] && dev="b" || dev="c"
str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
;;
"slink")
local target=`readlink "${location}"`
str="${ftype} ${name} ${target} ${str}"
;;
*)
str="${ftype} ${name} ${str}"
;;
esac
echo "${str}" >> ${output}
return 0
}
unknown_option() {
printf "ERROR: unknown option \"$arg\"\n" >&2
printf "If the filename validly begins with '-', " >&2
printf "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
}
list_header() {
:
}
header() {
printf "\n#####################\n# $1\n" >> ${output}
}
# process one directory (incl sub-directories)
dir_filelist() {
${dep_list}header "$1"
srcdir=$(echo "$1" | sed -e 's://*:/:g')
dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort)
# If $dirlist is only one line, then the directory is empty
if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
${dep_list}print_mtime "$1"
echo "${dirlist}" | \
while read x; do
${dep_list}parse ${x}
done
fi
}
# if only one file is specified and it is .cpio file then use it direct as fs
# if a directory is specified then add all files in given direcotry to fs
# if a regular file is specified assume it is in gen_initramfs format
input_file() {
source="$1"
if [ -f "$1" ]; then
${dep_list}header "$1"
is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
cpio_file=$1
echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
[ ! -z ${dep_list} ] && echo "$1"
return 0
fi
if [ -z ${dep_list} ]; then
print_mtime "$1" >> ${output}
cat "$1" >> ${output}
else
echo "$1 \\"
cat "$1" | while read type dir file perm ; do
if [ "$type" = "file" ]; then
echo "$file \\";
fi
done
fi
elif [ -d "$1" ]; then
dir_filelist "$1"
else
echo " ${prog}: Cannot open '$1'" >&2
exit 1
fi
}
prog=$0
root_uid=0
root_gid=0
dep_list=
cpio_file=
cpio_list=
output="/dev/stdout"
output_file=""
is_cpio_compressed=
compr="gzip -n -9 -f"
arg="$1"
case "$arg" in
"-l") # files included in initramfs - used by kbuild
dep_list="list_"
echo "deps_initramfs := $0 \\"
shift
;;
"-o") # generate compressed cpio image named $1
shift
output_file="$1"
cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
output=${cpio_list}
echo "$output_file" | grep -q "\.gz$" \
&& [ -x "`which gzip 2> /dev/null`" ] \
&& compr="gzip -n -9 -f"
echo "$output_file" | grep -q "\.bz2$" \
&& [ -x "`which bzip2 2> /dev/null`" ] \
&& compr="bzip2 -9 -f"
echo "$output_file" | grep -q "\.lzma$" \
&& [ -x "`which lzma 2> /dev/null`" ] \
&& compr="lzma -9 -f"
echo "$output_file" | grep -q "\.xz$" \
&& [ -x "`which xz 2> /dev/null`" ] \
&& compr="xz --check=crc32 --lzma2=dict=1MiB"
echo "$output_file" | grep -q "\.lzo$" \
&& [ -x "`which lzop 2> /dev/null`" ] \
&& compr="lzop -9 -f"
echo "$output_file" | grep -q "\.lz4$" \
&& [ -x "`which lz4 2> /dev/null`" ] \
&& compr="lz4 -l -9 -f"
echo "$output_file" | grep -q "\.cpio$" && compr="cat"
shift
;;
esac
while [ $# -gt 0 ]; do
arg="$1"
shift
case "$arg" in
"-u") # map $1 to uid=0 (root)
root_uid="$1"
[ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
shift
;;
"-g") # map $1 to gid=0 (root)
root_gid="$1"
[ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
shift
;;
"-d") # display default initramfs list
default_list="$arg"
${dep_list}default_initramfs
;;
"-h")
usage
exit 0
;;
*)
case "$arg" in
"-"*)
unknown_option
;;
*) # input file/dir - process it
input_file "$arg" "$#"
;;
esac
;;
esac
done
# If output_file is set we will generate cpio archive and compress it
# we are careful to delete tmp files
if [ ! -z ${output_file} ]; then
if [ -z ${cpio_file} ]; then
timestamp=
if test -n "$KBUILD_BUILD_TIMESTAMP"; then
timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
if test -n "$timestamp"; then
timestamp="-t $timestamp"
fi
fi
cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
else
cpio_tfile=${cpio_file}
fi
rm ${cpio_list}
if [ "${is_cpio_compressed}" = "compressed" ]; then
cat ${cpio_tfile} > ${output_file}
else
(cat ${cpio_tfile} | ${compr} - > ${output_file}) \
|| (rm -f ${output_file} ; false)
fi
[ -z ${cpio_file} ] && rm ${cpio_tfile}
fi
exit 0
+39
View File
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
initramfs_data includes the compressed binary that is the
filesystem used for early user space.
Note: Older versions of "as" (prior to binutils 2.11.90.0.23
released on 2001-07-14) dit not support .incbin.
If you are forced to use older binutils than that then the
following trick can be applied to create the resulting binary:
ld -m elf_i386 --format binary --oformat elf32-i386 -r \
-T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
ld -m elf_i386 -r -o built-in.a initramfs_data.o
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
arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
Using .incbin has the advantage over ld that the correct flags are set
in the ELF header, as required by certain architectures.
*/
#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 __initramfs_size
__initramfs_size:
#ifdef CONFIG_64BIT
.quad __irf_end - __irf_start
#else
.long __irf_end - __irf_start
#endif