diff options
Diffstat (limited to 'usr')
| -rw-r--r-- | usr/.gitignore | 14 | ||||
| -rw-r--r-- | usr/Kconfig | 180 | ||||
| -rw-r--r-- | usr/Makefile | 96 | ||||
| -rw-r--r-- | usr/default_cpio_list | 6 | ||||
| -rw-r--r-- | usr/dummy-include/stdbool.h | 7 | ||||
| -rw-r--r-- | usr/dummy-include/stdlib.h | 7 | ||||
| -rw-r--r-- | usr/gen_init_cpio.c | 377 | ||||
| -rwxr-xr-x | usr/gen_initramfs.sh | 250 | ||||
| -rw-r--r-- | usr/include/.gitignore | 2 | ||||
| -rw-r--r-- | usr/include/Makefile | 86 | ||||
| -rwxr-xr-x | usr/include/headers_check.pl | 104 | ||||
| -rw-r--r-- | usr/initramfs_data.S | 12 |
12 files changed, 906 insertions, 235 deletions
diff --git a/usr/.gitignore b/usr/.gitignore index 8e48117a3f3d..8996e7a88902 100644 --- a/usr/.gitignore +++ b/usr/.gitignore @@ -1,10 +1,4 @@ -# -# Generated files -# -gen_init_cpio -initramfs_data.cpio -initramfs_data.cpio.gz -initramfs_data.cpio.bz2 -initramfs_data.cpio.lzma -initramfs_list -include +# SPDX-License-Identifier: GPL-2.0-only +/gen_init_cpio +/initramfs_data.cpio +/initramfs_inc_data diff --git a/usr/Kconfig b/usr/Kconfig index 642f503d3e9f..9279a2893ab0 100644 --- a/usr/Kconfig +++ b/usr/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Configuration for initramfs # @@ -17,19 +18,27 @@ config INITRAMFS_SOURCE 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. + See <file:Documentation/driver-api/early-userspace/early_userspace_support.rst> 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 - This setting is only meaningful if the INITRAMFS_SOURCE is - contains a directory. Setting this user ID (UID) to something - other than "0" will cause all files owned by that UID to be - owned by user root in the initial ramdisk image. + 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". @@ -38,140 +47,183 @@ config INITRAMFS_ROOT_GID depends on INITRAMFS_SOURCE!="" default "0" help - This setting is only meaningful if the INITRAMFS_SOURCE is - contains a directory. Setting this group ID (GID) to something - other than "0" will cause all files owned by that GID to be - owned by group root in the initial ramdisk image. + 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 ramdisks compressed using gzip" if EXPERT + bool "Support initial ramdisk/ramfs compressed using gzip" 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 + bool "Support initial ramdisk/ramfs compressed using bzip2" + default y 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 + bool "Support initial ramdisk/ramfs compressed using LZMA" + default y 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 + bool "Support initial ramdisk/ramfs compressed using XZ" + 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 ramdisks compressed using LZO" if EXPERT - default !EXPERT - depends on BLK_DEV_INITRD + bool "Support initial ramdisk/ramfs compressed using LZO" + default y 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 + bool "Support initial ramdisk/ramfs compressed using LZ4" + default y select DECOMPRESS_LZ4 help Support loading of a LZ4 encoded initial ramdisk or cpio buffer If unsure, say N. +config RD_ZSTD + bool "Support initial ramdisk/ramfs compressed using ZSTD" + default y + select DECOMPRESS_ZSTD + help + Support loading of a ZSTD encoded initial ramdisk or cpio buffer. + If unsure, say N. + choice - prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!="" + prompt "Built-in initramfs compression mode" + depends on INITRAMFS_SOURCE != "" help - This option decides by which algorithm the builtin initramfs - will be compressed. Several compression algorithms are + 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. - - If you have any problems with bzip2 or LZMA compressed - initramfs, mail me (Alain Knaff) <alain@knaff.lu>. + 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. - If in doubt, select 'gzip' + Keep in mind that your build system needs to provide the appropriate + compression tool to compress the generated initram cpio file for + embedding. -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 + If in doubt, select 'None' config INITRAMFS_COMPRESSION_GZIP bool "Gzip" depends on RD_GZIP help - The old and tried gzip compression. It provides a good balance - between compression ratio and decompression speed. + 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 - Its 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. + 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. - Decompression speed is between the other choices. - Compression is slowest. The initramfs size is about 33% - smaller with LZMA in comparison to gzip. + 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. 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. + 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 - Its compression ratio is the poorest among the choices. The kernel - size is about 10% bigger than gzip; however its speed - (both compression and decompression) is the fastest. + Its compression ratio is the second poorest amongst the choices. The + kernel size is about 10% bigger than gzip. Despite that, its + decompression speed is the second fastest and its 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_ZSTD + bool "ZSTD" + depends on RD_ZSTD + help + ZSTD is a compression algorithm targeting intermediate compression + with fast decompression speed. It will compress better than GZIP and + decompress around the same speed as LZO, but slower than LZ4. + + If you choose this, keep in mind that you may need to install the zstd + tool to be able to compress the initram. + +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 diff --git a/usr/Makefile b/usr/Makefile index 029ffe6cd0d8..e8f42478a0b7 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -1,69 +1,85 @@ +# SPDX-License-Identifier: GPL-2.0 # # kbuild file for usr/ - including initramfs image # -klibcdirs:; -PHONY += klibcdirs +compress-y := copy +compress-$(CONFIG_INITRAMFS_COMPRESSION_GZIP) := gzip +compress-$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) := bzip2 +compress-$(CONFIG_INITRAMFS_COMPRESSION_LZMA) := lzma +compress-$(CONFIG_INITRAMFS_COMPRESSION_XZ) := xzmisc +compress-$(CONFIG_INITRAMFS_COMPRESSION_LZO) := lzo +compress-$(CONFIG_INITRAMFS_COMPRESSION_LZ4) := lz4 +compress-$(CONFIG_INITRAMFS_COMPRESSION_ZSTD) := zstd +obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o -# Gzip -suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP) = .gz +$(obj)/initramfs_data.o: $(obj)/initramfs_inc_data -# Bzip2 -suffix_$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) = .bz2 +hostprogs := gen_init_cpio -# Lzma -suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZMA) = .lzma +ramfs-input := $(CONFIG_INITRAMFS_SOURCE) +cpio-data := -# XZ -suffix_$(CONFIG_INITRAMFS_COMPRESSION_XZ) = .xz +# If CONFIG_INITRAMFS_SOURCE is empty, generate a small initramfs with the +# default contents. +ifeq ($(ramfs-input),) +ramfs-input := $(src)/default_cpio_list +endif -# Lzo -suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZO) = .lzo +ifeq ($(words $(ramfs-input)),1) -AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/initramfs_data.cpio$(suffix_y)" +# If CONFIG_INITRAMFS_SOURCE specifies a single file, and it is suffixed with +# .cpio, use it directly as an initramfs. +ifneq ($(filter %.cpio,$(ramfs-input)),) +cpio-data := $(ramfs-input) +endif -# Generate builtin.o based on initramfs_data.o -obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o +# If CONFIG_INITRAMFS_SOURCE specifies a single file, and it is suffixed with +# .cpio.*, use it directly as an initramfs, and avoid double compression. +ifeq ($(words $(subst .cpio.,$(space),$(ramfs-input))),2) +cpio-data := $(ramfs-input) +compress-y := copy +endif -# 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$(suffix_y) FORCE +endif -##### -# Generate the initramfs cpio archive +# For other cases, generate the initramfs cpio archive based on the contents +# specified by CONFIG_INITRAMFS_SOURCE. +ifeq ($(cpio-data),) -hostprogs-y := gen_init_cpio -initramfs := $(CONFIG_SHELL) $(srctree)/scripts/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)) +cpio-data := $(obj)/initramfs_data.cpio # .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.d),) - include $(obj)/.initramfs_data.cpio.d -endif +-include $(obj)/.initramfs_data.cpio.d -quiet_cmd_initfs = GEN $@ - cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) - -targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 initramfs_data.cpio.lzma initramfs_data.cpio.xz initramfs_data.cpio.lzo initramfs_data.cpio # do not try to update files included in initramfs $(deps_initramfs): ; -$(deps_initramfs): klibcdirs +quiet_cmd_initfs = GEN $@ + cmd_initfs = \ + $(CONFIG_SHELL) $< -o $@ -l $(obj)/.initramfs_data.cpio.d \ + $(addprefix -u , $(CONFIG_INITRAMFS_ROOT_UID)) \ + $(addprefix -g , $(CONFIG_INITRAMFS_ROOT_GID)) \ + $(if $(KBUILD_BUILD_TIMESTAMP), -d "$(KBUILD_BUILD_TIMESTAMP)") \ + $(ramfs-input) + # We rebuild initramfs_data.cpio if: -# 1) Any included file is newer then initramfs_data.cpio +# 1) Any included file is newer than 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)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs - $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d +# 4) Arguments to gen_initramfs.sh changes +$(obj)/initramfs_data.cpio: $(src)/gen_initramfs.sh $(obj)/gen_init_cpio $(deps_initramfs) FORCE $(call if_changed,initfs) +endif + +$(obj)/initramfs_inc_data: $(cpio-data) FORCE + $(call if_changed,$(compress-y)) + +targets += initramfs_data.cpio initramfs_inc_data + +subdir-$(CONFIG_UAPI_HEADER_TEST) += include diff --git a/usr/default_cpio_list b/usr/default_cpio_list new file mode 100644 index 000000000000..37b3864066e8 --- /dev/null +++ b/usr/default_cpio_list @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# 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 diff --git a/usr/dummy-include/stdbool.h b/usr/dummy-include/stdbool.h new file mode 100644 index 000000000000..54ff9e9c90ac --- /dev/null +++ b/usr/dummy-include/stdbool.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _STDBOOL_H +#define _STDBOOL_H + +#error "Please do not include <stdbool.h> from exported headers" + +#endif /* _STDBOOL_H */ diff --git a/usr/dummy-include/stdlib.h b/usr/dummy-include/stdlib.h new file mode 100644 index 000000000000..e8c21888e371 --- /dev/null +++ b/usr/dummy-include/stdlib.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _STDLIB_H +#define _STDLIB_H + +#error "Please do not include <stdlib.h> from exported headers" + +#endif /* _STDLIB_H */ diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index af8c925e93eb..b7296edc6626 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -1,5 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> @@ -19,64 +23,75 @@ #define xstr(s) #s #define str(s) xstr(s) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define CPIO_HDR_LEN 110 +#define CPIO_TRAILER "TRAILER!!!" +#define padlen(_off, _align) (((_align) - ((_off) & ((_align) - 1))) % (_align)) +/* zero-padding the filename field for data alignment is limited by PATH_MAX */ +static char padding[PATH_MAX]; static unsigned int offset; static unsigned int ino = 721; static time_t default_mtime; +static bool do_file_mtime; +static bool do_csum = false; +static int outfd = STDOUT_FILENO; +static unsigned int dalign; struct file_handler { const char *type; int (*handler)(const char *line); }; -static void push_string(const char *name) +static int push_buf(const char *name, size_t name_len) { - unsigned int name_len = strlen(name) + 1; + ssize_t len; + + len = write(outfd, name, name_len); + if (len != name_len) + return -1; - fputs(name, stdout); - putchar(0); offset += name_len; + return 0; } -static void push_pad (void) +static int push_pad(size_t padlen) { - while (offset & 3) { - putchar(0); - offset++; - } -} + ssize_t len = 0; -static void push_rest(const char *name) -{ - unsigned int name_len = strlen(name) + 1; - unsigned int tmp_ofs; + if (!padlen) + return 0; - fputs(name, stdout); - putchar(0); - offset += name_len; + if (padlen < sizeof(padding)) + len = write(outfd, padding, padlen); + if (len != padlen) + return -1; - tmp_ofs = name_len + 110; - while (tmp_ofs & 3) { - putchar(0); - offset++; - tmp_ofs++; - } + offset += padlen; + return 0; } -static void push_hdr(const char *s) +static int push_rest(const char *name, size_t name_len) { - fputs(s, stdout); - offset += 110; + ssize_t len; + + len = write(outfd, name, name_len); + if (len != name_len) + return -1; + + offset += name_len; + + return push_pad(padlen(name_len + CPIO_HDR_LEN, 4)); } -static void cpio_trailer(void) +static int cpio_trailer(void) { - char s[256]; - const char name[] = "TRAILER!!!"; + int len; + unsigned int namesize = sizeof(CPIO_TRAILER); - sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX" + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", - "070701", /* magic */ + do_csum ? "070702" : "070701", /* magic */ 0, /* ino */ 0, /* mode */ (long) 0, /* uid */ @@ -88,46 +103,58 @@ static void cpio_trailer(void) 0, /* minor */ 0, /* rmajor */ 0, /* rminor */ - (unsigned)strlen(name)+1, /* namesize */ + namesize, /* namesize */ 0); /* chksum */ - push_hdr(s); - push_rest(name); + offset += len; - while (offset % 512) { - putchar(0); - offset++; - } + if (len != CPIO_HDR_LEN || + push_rest(CPIO_TRAILER, namesize) < 0 || + push_pad(padlen(offset, 512)) < 0) + return -1; + + if (fsync(outfd) < 0 && errno != EINVAL) + return -1; + + return 0; } static int cpio_mkslink(const char *name, const char *target, unsigned int mode, uid_t uid, gid_t gid) { - char s[256]; + int len; + unsigned int namesize, targetsize = strlen(target) + 1; if (name[0] == '/') name++; - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" + namesize = strlen(name) + 1; + + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", - "070701", /* magic */ + do_csum ? "070702" : "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 */ + targetsize, /* filesize */ 3, /* major */ 1, /* minor */ 0, /* rmajor */ 0, /* rminor */ - (unsigned)strlen(name) + 1,/* namesize */ + namesize, /* namesize */ 0); /* chksum */ - push_hdr(s); - push_string(name); - push_pad(); - push_string(target); - push_pad(); + offset += len; + + if (len != CPIO_HDR_LEN || + push_buf(name, namesize) < 0 || + push_pad(padlen(offset, 4)) < 0 || + push_buf(target, targetsize) < 0 || + push_pad(padlen(offset, 4)) < 0) + return -1; + return 0; + } static int cpio_mkslink_line(const char *line) @@ -151,13 +178,16 @@ static int cpio_mkslink_line(const char *line) static int cpio_mkgeneric(const char *name, unsigned int mode, uid_t uid, gid_t gid) { - char s[256]; + int len; + unsigned int namesize; if (name[0] == '/') name++; - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" + namesize = strlen(name) + 1; + + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", - "070701", /* magic */ + do_csum ? "070702" : "070701", /* magic */ ino++, /* ino */ mode, /* mode */ (long) uid, /* uid */ @@ -169,10 +199,14 @@ static int cpio_mkgeneric(const char *name, unsigned int mode, 1, /* minor */ 0, /* rmajor */ 0, /* rminor */ - (unsigned)strlen(name) + 1,/* namesize */ + namesize, /* namesize */ 0); /* chksum */ - push_hdr(s); - push_rest(name); + offset += len; + + if (len != CPIO_HDR_LEN || + push_rest(name, namesize) < 0) + return -1; + return 0; } @@ -187,7 +221,7 @@ struct generic_type { mode_t mode; }; -static struct generic_type generic_type_table[] = { +static const struct generic_type generic_type_table[] = { [GT_DIR] = { .type = "dir", .mode = S_IFDIR @@ -240,7 +274,8 @@ 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]; + int len; + unsigned int namesize; if (dev_type == 'b') mode |= S_IFBLK; @@ -249,9 +284,11 @@ static int cpio_mknod(const char *name, unsigned int mode, if (name[0] == '/') name++; - sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" + namesize = strlen(name) + 1; + + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", - "070701", /* magic */ + do_csum ? "070702" : "070701", /* magic */ ino++, /* ino */ mode, /* mode */ (long) uid, /* uid */ @@ -263,10 +300,14 @@ static int cpio_mknod(const char *name, unsigned int mode, 1, /* minor */ maj, /* rmajor */ min, /* rminor */ - (unsigned)strlen(name) + 1,/* namesize */ + namesize, /* namesize */ 0); /* chksum */ - push_hdr(s); - push_rest(name); + offset += len; + + if (len != CPIO_HDR_LEN || + push_rest(name, namesize) < 0) + return -1; + return 0; } @@ -291,19 +332,42 @@ static int cpio_mknod_line(const char *line) return rc; } +static int cpio_mkfile_csum(int fd, unsigned long size, uint32_t *csum) +{ + while (size) { + unsigned char filebuf[65536]; + ssize_t this_read; + size_t i, this_size = MIN(size, sizeof(filebuf)); + + this_read = read(fd, filebuf, this_size); + if (this_read <= 0 || this_read > this_size) + return -1; + + for (i = 0; i < this_read; i++) + *csum += filebuf[i]; + + size -= this_read; + } + /* seek back to the start for data segment I/O */ + if (lseek(fd, 0, SEEK_SET) < 0) + return -1; + + return 0; +} + 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; + unsigned long size; + int file, retval, len; int rc = -1; - int namesize; + time_t mtime; + int namesize, namepadlen; unsigned int i; + uint32_t csum = 0; + ssize_t this_read; mode |= S_IFREG; @@ -319,87 +383,133 @@ static int cpio_mkfile(const char *name, const char *location, goto error; } - filebuf = malloc(buf.st_size); - if (!filebuf) { - fprintf (stderr, "out of memory\n"); + if (do_file_mtime) { + mtime = default_mtime; + } else { + mtime = buf.st_mtime; + if (mtime > 0xffffffff) { + fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n", + location); + mtime = 0xffffffff; + } + + if (mtime < 0) { + fprintf(stderr, "%s: Timestamp negative, clipping.\n", + location); + mtime = 0; + } + } + + if (buf.st_size > 0xffffffff) { + fprintf(stderr, "%s: Size exceeds maximum cpio file size\n", + location); goto error; } - retval = read (file, filebuf, buf.st_size); - if (retval < 0) { - fprintf (stderr, "Can not read %s file\n", location); + if (do_csum && cpio_mkfile_csum(file, buf.st_size, &csum) < 0) { + fprintf(stderr, "Failed to checksum file %s\n", location); goto error; } size = 0; + namepadlen = 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" + + /* data goes on last link, after any alignment padding */ + if (i == nlinks) + size = buf.st_size; + + if (dalign && size > dalign) { + namepadlen = padlen(offset + CPIO_HDR_LEN + namesize, + dalign); + if (namesize + namepadlen > PATH_MAX) { + fprintf(stderr, + "%s: best-effort alignment %u missed\n", + name, dalign); + namepadlen = 0; + } + } + + len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX" "%08lX%08X%08X%08X%08X%08X%08X", - "070701", /* magic */ + do_csum ? "070702" : "070701", /* magic */ ino, /* ino */ mode, /* mode */ (long) uid, /* uid */ (long) gid, /* gid */ nlinks, /* nlink */ - (long) buf.st_mtime, /* mtime */ + (long) mtime, /* mtime */ size, /* filesize */ 3, /* major */ 1, /* minor */ 0, /* rmajor */ 0, /* rminor */ - namesize, /* namesize */ - 0); /* chksum */ - push_hdr(s); - push_string(name); - push_pad(); + namesize + namepadlen, /* namesize */ + size ? csum : 0); /* chksum */ + offset += len; + + if (len != CPIO_HDR_LEN || + push_buf(name, namesize) < 0 || + push_pad(namepadlen ? namepadlen : padlen(offset, 4)) < 0) + goto error; if (size) { - if (fwrite(filebuf, size, 1, stdout) != 1) { + this_read = copy_file_range(file, NULL, outfd, NULL, size, 0); + if (this_read > 0) { + if (this_read > size) + goto error; + offset += this_read; + size -= this_read; + } + /* short or failed copy falls back to read/write... */ + } + + while (size) { + unsigned char filebuf[65536]; + size_t this_size = MIN(size, sizeof(filebuf)); + + this_read = read(file, filebuf, this_size); + if (this_read <= 0 || this_read > this_size) { + fprintf(stderr, "Can not read %s file\n", location); + goto error; + } + + if (write(outfd, filebuf, this_read) != this_read) { fprintf(stderr, "writing filebuf failed\n"); goto error; } - offset += size; - push_pad(); + offset += this_read; + size -= this_read; } + if (push_pad(padlen(offset, 4)) < 0) + goto error; name += namesize; } ino++; rc = 0; - + error: - if (filebuf) free(filebuf); - if (file >= 0) close(file); + if (file >= 0) + close(file); return rc; } static char *cpio_replace_env(char *new_location) { char expanded[PATH_MAX + 1]; - char env_var[PATH_MAX + 1]; - char *start; - char *end; - - for (start = NULL; (start = strstr(new_location, "${")); ) { - end = strchr(start, '}'); - if (start < end) { - *env_var = *expanded = '\0'; - strncat(env_var, start + 2, end - start - 2); - strncat(expanded, new_location, start - new_location); - strncat(expanded, getenv(env_var), - PATH_MAX - strlen(expanded)); - strncat(expanded, end + 1, - PATH_MAX - strlen(expanded)); - strncpy(new_location, expanded, PATH_MAX); - new_location[PATH_MAX] = 0; - } else - break; + 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; @@ -460,7 +570,7 @@ static int cpio_mkfile_line(const char *line) static void usage(const char *prog) { fprintf(stderr, "Usage:\n" - "\t%s [-t <timestamp>] <cpio_list>\n" + "\t%s [-t <timestamp>] [-c] [-o <output_file>] [-a <data_align>] <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" @@ -494,12 +604,18 @@ static void usage(const char *prog) "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", + "as mtime for symlinks, directories, regular and special files.\n" + "The default is to use the current time for all files, but\n" + "preserve modification time for regular files.\n" + "-c: calculate and store 32-bit checksums for file data.\n" + "<output_file>: write cpio to this file instead of stdout\n" + "<data_align>: attempt to align file data by zero-padding the\n" + "filename field up to data_align. Must be a multiple of 4.\n" + "Alignment is best-effort; PATH_MAX limits filename padding.\n", prog); } -struct file_handler file_handler_table[] = { +static const struct file_handler file_handler_table[] = { { .type = "file", .handler = cpio_mkfile_line, @@ -537,7 +653,7 @@ int main (int argc, char *argv[]) default_mtime = time(NULL); while (1) { - int opt = getopt(argc, argv, "t:h"); + int opt = getopt(argc, argv, "t:cho:a:"); char *invalid; if (opt == -1) @@ -551,6 +667,29 @@ int main (int argc, char *argv[]) usage(argv[0]); exit(1); } + do_file_mtime = true; + break; + case 'c': + do_csum = true; + break; + case 'o': + outfd = open(optarg, + O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC, + 0600); + if (outfd < 0) { + fprintf(stderr, "failed to open %s\n", optarg); + usage(argv[0]); + exit(1); + } + break; + case 'a': + dalign = strtoul(optarg, &invalid, 10); + if (!*optarg || *invalid || (dalign & 3)) { + fprintf(stderr, "Invalid data_align: %s\n", + optarg); + usage(argv[0]); + exit(1); + } break; case 'h': case '?': @@ -559,6 +698,16 @@ int main (int argc, char *argv[]) } } + /* + * Timestamps after 2106-02-07 06:28:15 UTC have an ascii hex time_t + * representation that exceeds 8 chars and breaks the cpio header + * specification. Negative timestamps similarly exceed 8 chars. + */ + if (default_mtime > 0xffffffff || default_mtime < 0) { + fprintf(stderr, "ERROR: Timestamp out of range for cpio format\n"); + exit(1); + } + if (argc - optind != 1) { usage(argv[0]); exit(1); @@ -626,7 +775,7 @@ int main (int argc, char *argv[]) } } if (ec == 0) - cpio_trailer(); + ec = cpio_trailer(); exit(ec); } diff --git a/usr/gen_initramfs.sh b/usr/gen_initramfs.sh new file mode 100755 index 000000000000..7eba2fddf0ef --- /dev/null +++ b/usr/gen_initramfs.sh @@ -0,0 +1,250 @@ +#!/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. +# 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>] [-l <dep_list>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ... + -o <file> Create initramfs file named <file> by using gen_init_cpio + -l <dep_list> Create dependency list named <dep_list> + -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. + -d <date> Use date for all file mtime values + <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. + +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 +} + +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 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}" >> $cpio_list + echo "" >> $cpio_list +} + +list_parse() { + if [ -z "$dep_list" -o -L "$1" ]; then + return + fi + echo "$1" | sed 's/:/\\:/g; s/$/ \\/' >> $dep_list +} + +# 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}" >> $cpio_list + + 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 +} + +header() { + printf "\n#####################\n# $1\n" >> $cpio_list +} + +# process one directory (incl sub-directories) +dir_filelist() { + header "$1" + + srcdir=$(echo "$1" | sed -e 's://*:/:g') + dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LC_ALL=C sort) + + # If $dirlist is only one line, then the directory is empty + if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then + print_mtime "$1" + + echo "${dirlist}" | \ + while read x; do + list_parse $x + parse $x + done + fi +} + +input_file() { + source="$1" + if [ -f "$1" ]; then + # If a regular file is specified, assume it is in + # gen_init_cpio format + header "$1" + print_mtime "$1" >> $cpio_list + cat "$1" >> $cpio_list + if [ -n "$dep_list" ]; then + echo "$1 \\" >> $dep_list + cat "$1" | while read type dir file perm ; do + if [ "$type" = "file" ]; then + echo "$file \\" >> $dep_list + fi + done + fi + elif [ -d "$1" ]; then + # If a directory is specified then add all files in it to fs + dir_filelist "$1" + else + echo " ${prog}: Cannot open '$1'" >&2 + exit 1 + fi +} + +prog=$0 +root_uid=0 +root_gid=0 +dep_list= +timestamp= +cpio_list=$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX) +# gen_init_cpio writes to stdout by default +output="" + +trap "rm -f $cpio_list" EXIT + +while [ $# -gt 0 ]; do + arg="$1" + shift + case "$arg" in + "-l") # files included in initramfs - used by kbuild + dep_list="$1" + echo "deps_initramfs := \\" > $dep_list + shift + ;; + "-o") # generate cpio image named $1 + output="-o $1" + shift + ;; + "-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") # date for file mtimes + timestamp="$(date -d"$1" +%s || :)" + if test -n "$timestamp"; then + timestamp="-t $timestamp" + fi + shift + ;; + "-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 +# we are careful to delete tmp files +usr/gen_init_cpio $output $timestamp $cpio_list diff --git a/usr/include/.gitignore b/usr/include/.gitignore new file mode 100644 index 000000000000..17b0ba1bd325 --- /dev/null +++ b/usr/include/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +/*/ diff --git a/usr/include/Makefile b/usr/include/Makefile new file mode 100644 index 000000000000..d8a508042fed --- /dev/null +++ b/usr/include/Makefile @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# Unlike the kernel space, exported headers are written in standard C. +# - Forbid C++ style comments +# - Use '__inline__', '__asm__' instead of 'inline', 'asm' +# +# -std=c90 (equivalent to -ansi) catches the violation of those. +# We cannot go as far as adding -Wpedantic since it emits too many warnings. +UAPI_CFLAGS := -std=c90 -Werror=implicit-function-declaration + +override c_flags = $(KBUILD_USERCFLAGS) $(UAPI_CFLAGS) -Wp,-MMD,$(depfile) -I $(obj) -I $(srctree)/usr/dummy-include + +# The following are excluded for now because they fail to build. +# +# Do not add a new header to the blacklist without legitimate reason. +# Please consider to fix the header first. +# +# Sorted alphabetically. +no-header-test += asm/ucontext.h +no-header-test += drm/vmwgfx_drm.h +no-header-test += linux/am437x-vpfe.h +no-header-test += linux/coda.h +no-header-test += linux/cyclades.h +no-header-test += linux/errqueue.h +no-header-test += linux/hdlc/ioctl.h +no-header-test += linux/ivtv.h +no-header-test += linux/matroxfb.h +no-header-test += linux/omap3isp.h +no-header-test += linux/omapfb.h +no-header-test += linux/patchkey.h +no-header-test += linux/phonet.h +no-header-test += linux/sctp.h +no-header-test += linux/sysctl.h +no-header-test += linux/usb/audio.h +no-header-test += linux/v4l2-mediabus.h +no-header-test += linux/v4l2-subdev.h +no-header-test += linux/videodev2.h +no-header-test += linux/vm_sockets.h +no-header-test += sound/asequencer.h +no-header-test += sound/asoc.h +no-header-test += sound/asound.h +no-header-test += sound/compress_offload.h +no-header-test += sound/emu10k1.h +no-header-test += sound/sfnt_info.h +no-header-test += xen/evtchn.h +no-header-test += xen/gntdev.h +no-header-test += xen/privcmd.h + +# More headers are broken in some architectures + +ifeq ($(SRCARCH),arc) +no-header-test += linux/bpf_perf_event.h +endif + +ifeq ($(SRCARCH),openrisc) +no-header-test += linux/bpf_perf_event.h +endif + +ifeq ($(SRCARCH),powerpc) +no-header-test += linux/bpf_perf_event.h +endif + +ifeq ($(SRCARCH),sparc) +no-header-test += asm/uctx.h +no-header-test += asm/fbio.h +endif + +# asm-generic/*.h is used by asm/*.h, and should not be included directly +no-header-test += asm-generic/% + +always-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/dev/null)) + +# Include the header twice to detect missing include guard. +quiet_cmd_hdrtest = HDRTEST $< + cmd_hdrtest = \ + $(CC) $(c_flags) -fsyntax-only -Werror -x c /dev/null \ + $(if $(filter-out $(no-header-test), $*.h), -include $< -include $<); \ + $(PERL) $(src)/headers_check.pl $(obj) $<; \ + touch $@ + +$(obj)/%.hdrtest: $(obj)/%.h $(src)/headers_check.pl FORCE + $(call if_changed_dep,hdrtest) + +# Since GNU Make 4.3, $(patsubst $(obj)/%/,%,$(wildcard $(obj)/*/)) works. +# To support older Make versions, use a somewhat tedious way. +clean-files += $(filter-out Makefile headers_check.pl, $(notdir $(wildcard $(obj)/*))) diff --git a/usr/include/headers_check.pl b/usr/include/headers_check.pl new file mode 100755 index 000000000000..af5a513eaa00 --- /dev/null +++ b/usr/include/headers_check.pl @@ -0,0 +1,104 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# +# headers_check.pl execute a number of trivial consistency checks +# +# Usage: headers_check.pl dir [files...] +# dir: dir to look for included files +# files: list of files to check +# +# The script reads the supplied files line by line and: +# +# 1) for each include statement it checks if the +# included file actually exists. +# Only include files located in asm* and linux* are checked. +# The rest are assumed to be system include files. +# +# 2) It is checked that prototypes does not use "extern" +# +# 3) Check for leaked CONFIG_ symbols + +use warnings; +use strict; +use File::Basename; + +my ($dir, @files) = @ARGV; + +my $ret = 0; +my $line; +my $lineno = 0; +my $filename; + +foreach my $file (@files) { + $filename = $file; + + open(my $fh, '<', $filename) + or die "$filename: $!\n"; + $lineno = 0; + while ($line = <$fh>) { + $lineno++; + &check_include(); + &check_asm_types(); + &check_declarations(); + # Dropped for now. Too much noise &check_config(); + } + close $fh; +} +exit $ret; + +sub check_include +{ + if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) { + my $inc = $1; + my $found; + $found = stat($dir . "/" . $inc); + if (!$found) { + printf STDERR "$filename:$lineno: included file '$inc' is not exported\n"; + $ret = 1; + } + } +} + +sub check_declarations +{ + # soundcard.h is what it is + if ($line =~ m/^void seqbuf_dump\(void\);/) { + return; + } + # drm headers are being C++ friendly + if ($line =~ m/^extern "C"/) { + return; + } + if ($line =~ m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { + printf STDERR "$filename:$lineno: " . + "userspace cannot reference function or " . + "variable defined in the kernel\n"; + $ret = 1; + } +} + +sub check_config +{ + if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) { + printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n"; + } +} + +my $linux_asm_types; +sub check_asm_types +{ + if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { + return; + } + if ($lineno == 1) { + $linux_asm_types = 0; + } elsif ($linux_asm_types >= 1) { + return; + } + if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) { + $linux_asm_types = 1; + printf STDERR "$filename:$lineno: " . + "include of <linux/types.h> is preferred over <asm/types.h>\n"; + $ret = 1; + } +} diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S index c14322d1c0cf..cd67edc38797 100644 --- a/usr/initramfs_data.S +++ b/usr/initramfs_data.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* initramfs_data includes the compressed binary that is the filesystem used for early user space. @@ -9,7 +10,7 @@ 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.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. @@ -21,16 +22,13 @@ 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) +.incbin "usr/initramfs_inc_data" __irf_end: .section .init.ramfs.info,"a" -.globl VMLINUX_SYMBOL(__initramfs_size) -VMLINUX_SYMBOL(__initramfs_size): +.globl __initramfs_size +__initramfs_size: #ifdef CONFIG_64BIT .quad __irf_end - __irf_start #else |
