Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
/gen_init_cpio
/initramfs_data.cpio
/initramfs_inc_data
+229
View File
@@ -0,0 +1,229 @@
# 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/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
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"
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
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
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"
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
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
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"
depends on INITRAMFS_SOURCE != ""
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
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
+85
View File
@@ -0,0 +1,85 @@
# SPDX-License-Identifier: GPL-2.0
#
# kbuild file for usr/ - including initramfs image
#
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
$(obj)/initramfs_data.o: $(obj)/initramfs_inc_data
hostprogs := gen_init_cpio
ramfs-input := $(CONFIG_INITRAMFS_SOURCE)
cpio-data :=
# If CONFIG_INITRAMFS_SOURCE is empty, generate a small initramfs with the
# default contents.
ifeq ($(ramfs-input),)
ramfs-input := $(src)/default_cpio_list
endif
ifeq ($(words $(ramfs-input)),1)
# 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
# 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
endif
# For other cases, generate the initramfs cpio archive based on the contents
# specified by CONFIG_INITRAMFS_SOURCE.
ifeq ($(cpio-data),)
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
-include $(obj)/.initramfs_data.cpio.d
# do not try to update files included in initramfs
$(deps_initramfs): ;
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 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: $(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
+6
View File
@@ -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
+8
View File
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _DUMMY_LIMITS_H
#define _DUMMY_LIMITS_H
#define INT_MAX ((int)(~0U >> 1))
#define INT_MIN (-INT_MAX - 1)
#endif /* _DUMMY_LIMITS_H */
+13
View File
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _DUMMY_STDDEF_H
#define _DUMMY_STDDEF_H
#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif /* _DUMMY_STDDEF_H */
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _DUMMY_STDINT_H
#define _DUMMY_STDINT_H
#include <linux/types.h>
typedef __u64 uint64_t;
typedef __u32 uint32_t;
typedef __u16 uint16_t;
typedef __u8 uint8_t;
typedef __s64 int64_t;
typedef __s32 int32_t;
typedef __s16 int16_t;
typedef __s8 int8_t;
#endif /* _DUMMY_STDINT_H */
+12
View File
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _DUMMY_STRING_H
#define _DUMMY_STRING_H
#include <stddef.h>
#define memset(_s, _c, _n) __builtin_memset(_s, _c, _n)
#define memcpy(_dest, _src, _n) __builtin_memcpy(_dest, _src, _n)
#define strlen(_s) __builtin_strlen(_s)
#endif /* _DUMMY_STRING_H */
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _DUMMY_SYS_SOCKET_H
#define _DUMMY_SYS_SOCKET_H
#include <linux/socket.h>
struct sockaddr {
__kernel_sa_family_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
#endif /* _DUMMY_SYS_SOCKET_H */
+3
View File
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/time.h>
+781
View File
@@ -0,0 +1,781 @@
// 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>
#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)
#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 int push_buf(const char *name, size_t name_len)
{
ssize_t len;
len = write(outfd, name, name_len);
if (len != name_len)
return -1;
offset += name_len;
return 0;
}
static int push_pad(size_t padlen)
{
ssize_t len = 0;
if (!padlen)
return 0;
if (padlen < sizeof(padding))
len = write(outfd, padding, padlen);
if (len != padlen)
return -1;
offset += padlen;
return 0;
}
static int push_rest(const char *name, size_t name_len)
{
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 int cpio_trailer(void)
{
int len;
unsigned int namesize = sizeof(CPIO_TRAILER);
len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "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 */
namesize, /* namesize */
0); /* chksum */
offset += len;
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)
{
int len;
unsigned int namesize, targetsize = strlen(target) + 1;
if (name[0] == '/')
name++;
namesize = strlen(name) + 1;
len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "070701", /* magic */
ino++, /* ino */
S_IFLNK | mode, /* mode */
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
(long) default_mtime, /* mtime */
targetsize, /* filesize */
3, /* major */
1, /* minor */
0, /* rmajor */
0, /* rminor */
namesize, /* namesize */
0); /* chksum */
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)
{
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)
{
int len;
unsigned int namesize;
if (name[0] == '/')
name++;
namesize = strlen(name) + 1;
len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "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 */
namesize, /* namesize */
0); /* chksum */
offset += len;
if (len != CPIO_HDR_LEN ||
push_rest(name, namesize) < 0)
return -1;
return 0;
}
enum generic_types {
GT_DIR,
GT_PIPE,
GT_SOCK
};
struct generic_type {
const char *type;
mode_t mode;
};
static const 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)
{
int len;
unsigned int namesize;
if (dev_type == 'b')
mode |= S_IFBLK;
else
mode |= S_IFCHR;
if (name[0] == '/')
name++;
namesize = strlen(name) + 1;
len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "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 */
namesize, /* namesize */
0); /* chksum */
offset += len;
if (len != CPIO_HDR_LEN ||
push_rest(name, namesize) < 0)
return -1;
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_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)
{
struct stat buf;
unsigned long size;
int file, retval, len;
int rc = -1;
time_t mtime;
int namesize, namepadlen;
unsigned int i;
uint32_t csum = 0;
ssize_t this_read;
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;
}
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;
}
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++) {
if (name[0] == '/')
name++;
namesize = strlen(name) + 1;
/* 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",
do_csum ? "070702" : "070701", /* magic */
ino, /* ino */
mode, /* mode */
(long) uid, /* uid */
(long) gid, /* gid */
nlinks, /* nlink */
(long) mtime, /* mtime */
size, /* filesize */
3, /* major */
1, /* minor */
0, /* rmajor */
0, /* rminor */
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) {
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 += this_read;
size -= this_read;
}
if (push_pad(padlen(offset, 4)) < 0)
goto error;
name += namesize;
}
ino++;
rc = 0;
error:
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>] [-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"
"\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, 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);
}
static const 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:cho:a:");
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);
}
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 '?':
usage(argv[0]);
exit(opt == 'h' ? 0 : 1);
}
}
/*
* 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);
}
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)
ec = cpio_trailer();
exit(ec);
}
+250
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
/*/
+188
View File
@@ -0,0 +1,188 @@
# 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
UAPI_ARCH := $(or $(HEADER_ARCH),$(SRCARCH))
override c_flags = $(KBUILD_USERCFLAGS) $(UAPI_CFLAGS) -Wp,-MMD,$(depfile)
cxx_flags = $(filter-out -Wmissing-prototypes -Wstrict-prototypes -std=%, $(KBUILD_USERCFLAGS)) -std=c++98
# 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
ifneq ($(filter arc openrisc xtensa nios2, $(UAPI_ARCH)),)
no-header-test += linux/bpf_perf_event.h
endif
ifeq ($(UAPI_ARCH),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/%
# The following are not compatible with C++.
#
# Do not add a new header to the list without legitimate reason.
# Please consider to fix the header first.
#
# Sorted alphabetically.
no-header-test-cxx += linux/auto_dev-ioctl.h
no-header-test-cxx += linux/map_to_14segment.h
no-header-test-cxx += linux/map_to_7segment.h
no-header-test-cxx += linux/netfilter/xt_sctp.h
no-header-test-cxx += linux/target_core_user.h
no-header-test-cxx += linux/vhost.h
no-header-test-cxx += linux/vhost_types.h
no-header-test-cxx += linux/virtio_net.h
no-header-test-cxx += linux/virtio_ring.h
no-header-test-cxx += scsi/fc/fc_els.h
ifeq ($(UAPI_ARCH),x86)
no-header-test-cxx += asm/elf.h
endif
# The following are using libc header and types.
#
# Do not add a new header to the list without legitimate reason.
# Please consider to fix the header first.
#
# Sorted alphabetically.
uses-libc += linux/a.out.h
uses-libc += linux/atmbr2684.h
uses-libc += linux/auto_dev-ioctl.h
uses-libc += linux/auto_fs.h
uses-libc += linux/auto_fs4.h
uses-libc += linux/btrfs_tree.h
uses-libc += linux/cec-funcs.h
uses-libc += linux/cec.h
uses-libc += linux/dvb/dmx.h
uses-libc += linux/dvb/video.h
uses-libc += linux/ethtool.h
uses-libc += linux/ethtool_netlink.h
uses-libc += linux/fuse.h
uses-libc += linux/gsmmux.h
uses-libc += linux/icmp.h
uses-libc += linux/idxd.h
uses-libc += linux/if.h
uses-libc += linux/if_arp.h
uses-libc += linux/if_bonding.h
uses-libc += linux/if_pppox.h
uses-libc += linux/if_tunnel.h
uses-libc += linux/input.h
uses-libc += linux/ip6_tunnel.h
uses-libc += linux/joystick.h
uses-libc += linux/llc.h
uses-libc += linux/mctp.h
uses-libc += linux/mdio.h
uses-libc += linux/mii.h
uses-libc += linux/mptcp.h
uses-libc += linux/netdevice.h
uses-libc += linux/netfilter/xt_RATEEST.h
uses-libc += linux/netfilter/xt_hashlimit.h
uses-libc += linux/netfilter/xt_physdev.h
uses-libc += linux/netfilter/xt_rateest.h
uses-libc += linux/netfilter_arp/arp_tables.h
uses-libc += linux/netfilter_arp/arpt_mangle.h
uses-libc += linux/netfilter_bridge.h
uses-libc += linux/netfilter_bridge/ebtables.h
uses-libc += linux/netfilter_ipv4.h
uses-libc += linux/netfilter_ipv4/ip_tables.h
uses-libc += linux/netfilter_ipv6.h
uses-libc += linux/netfilter_ipv6/ip6_tables.h
uses-libc += linux/route.h
uses-libc += linux/shm.h
uses-libc += linux/soundcard.h
uses-libc += linux/string.h
uses-libc += linux/tipc_config.h
uses-libc += linux/uhid.h
uses-libc += linux/uinput.h
uses-libc += linux/vhost.h
uses-libc += linux/vhost_types.h
uses-libc += linux/virtio_ring.h
uses-libc += linux/wireless.h
uses-libc += regulator/regulator.h
uses-libc += scsi/fc/fc_els.h
ifeq ($(UAPI_ARCH),hexagon)
uses-libc += asm/sigcontext.h
endif
ifeq ($(UAPI_ARCH),nios2)
uses-libc += asm/ptrace.h
endif
ifeq ($(UAPI_ARCH),s390)
uses-libc += asm/chpid.h
uses-libc += asm/chsc.h
endif
always-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/dev/null))
# $(cc-option) forces '-x c' which breaks '-x c++' detection.
cc-can-compile-cxx := $(call try-run,$(CC) $(CLANG_FLAGS) -c -x c++ /dev/null -o "$$TMP", 1)
target-libc = $(filter $(uses-libc), $*.h)
target-can-compile = $(filter-out $(no-header-test), $*.h)
target-can-compile-cxx = $(and $(cc-can-compile-cxx), $(target-can-compile), $(filter-out $(no-header-test-cxx), $*.h))
hdrtest-flags = -fsyntax-only -Werror \
-nostdinc -I $(obj) $(if $(target-libc), -I $(srctree)/usr/dummy-include)
# Include the header twice to detect missing include guard.
quiet_cmd_hdrtest = HDRTEST $<
cmd_hdrtest = \
$(CC) $(c_flags) $(hdrtest-flags) -x c /dev/null \
$(if $(target-can-compile), -include $< -include $<); \
$(if $(target-can-compile-cxx), \
$(CC) $(cxx_flags) $(hdrtest-flags) -x c++ /dev/null -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)/*)))
+96
View File
@@ -0,0 +1,96 @@
#!/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();
}
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;
}
}
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;
}
}
+36
View File
@@ -0,0 +1,36 @@
/* 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.
*/
.section .init.ramfs,"a"
__irf_start:
.incbin "usr/initramfs_inc_data"
__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