-
Notifications
You must be signed in to change notification settings - Fork 520
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #557 from amazonlinux/kernel
Include "kheaders" and build a kernel-devel RPM
- Loading branch information
Showing
8 changed files
with
804 additions
and
0 deletions.
There are no files selected for viewing
294 changes: 294 additions & 0 deletions
294
packages/kernel/0008-Provide-in-kernel-headers-to-make-extending-kernel-e.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,294 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: "Joel Fernandes (Google)" <[email protected]> | ||
Date: Fri, 26 Apr 2019 15:04:29 -0400 | ||
Subject: [PATCH 1/6] Provide in-kernel headers to make extending kernel easier | ||
|
||
Introduce in-kernel headers which are made available as an archive | ||
through proc (/proc/kheaders.tar.xz file). This archive makes it | ||
possible to run eBPF and other tracing programs that need to extend the | ||
kernel for tracing purposes without any dependency on the file system | ||
having headers. | ||
|
||
A github PR is sent for the corresponding BCC patch at: | ||
https://github.com/iovisor/bcc/pull/2312 | ||
|
||
On Android and embedded systems, it is common to switch kernels but not | ||
have kernel headers available on the file system. Further once a | ||
different kernel is booted, any headers stored on the file system will | ||
no longer be useful. This is an issue even well known to distros. | ||
By storing the headers as a compressed archive within the kernel, we can | ||
avoid these issues that have been a hindrance for a long time. | ||
|
||
The best way to use this feature is by building it in. Several users | ||
have a need for this, when they switch debug kernels, they do not want to | ||
update the filesystem or worry about it where to store the headers on | ||
it. However, the feature is also buildable as a module in case the user | ||
desires it not being part of the kernel image. This makes it possible to | ||
load and unload the headers from memory on demand. A tracing program can | ||
load the module, do its operations, and then unload the module to save | ||
kernel memory. The total memory needed is 3.3MB. | ||
|
||
By having the archive available at a fixed location independent of | ||
filesystem dependencies and conventions, all debugging tools can | ||
directly refer to the fixed location for the archive, without concerning | ||
with where the headers on a typical filesystem which significantly | ||
simplifies tooling that needs kernel headers. | ||
|
||
The code to read the headers is based on /proc/config.gz code and uses | ||
the same technique to embed the headers. | ||
|
||
Other approaches were discussed such as having an in-memory mountable | ||
filesystem, but that has drawbacks such as requiring an in-kernel xz | ||
decompressor which we don't have today, and requiring usage of 42 MB of | ||
kernel memory to host the decompressed headers at anytime. Also this | ||
approach is simpler than such approaches. | ||
|
||
Reviewed-by: Masahiro Yamada <[email protected]> | ||
Signed-off-by: Joel Fernandes (Google) <[email protected]> | ||
Signed-off-by: Greg Kroah-Hartman <[email protected]> | ||
(cherry picked from commit 43d8ce9d65a54846d378545770991e65838981e0) | ||
--- | ||
init/Kconfig | 10 +++++ | ||
kernel/.gitignore | 1 + | ||
kernel/Makefile | 10 +++++ | ||
kernel/gen_ikh_data.sh | 89 ++++++++++++++++++++++++++++++++++++++++++ | ||
kernel/kheaders.c | 74 +++++++++++++++++++++++++++++++++++ | ||
5 files changed, 184 insertions(+) | ||
create mode 100755 kernel/gen_ikh_data.sh | ||
create mode 100644 kernel/kheaders.c | ||
|
||
diff --git a/init/Kconfig b/init/Kconfig | ||
index 47035b5a46f6..1b52fbedbfdb 100644 | ||
--- a/init/Kconfig | ||
+++ b/init/Kconfig | ||
@@ -533,6 +533,16 @@ config IKCONFIG_PROC | ||
This option enables access to the kernel configuration file | ||
through /proc/config.gz. | ||
|
||
+config IKHEADERS_PROC | ||
+ tristate "Enable kernel header artifacts through /proc/kheaders.tar.xz" | ||
+ depends on PROC_FS | ||
+ help | ||
+ This option enables access to the kernel header and other artifacts that | ||
+ are generated during the build process. These can be used to build eBPF | ||
+ tracing programs, or similar programs. If you build the headers as a | ||
+ module, a module called kheaders.ko is built which can be loaded on-demand | ||
+ to get access to the headers. | ||
+ | ||
config LOG_BUF_SHIFT | ||
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" | ||
range 12 25 | ||
diff --git a/kernel/.gitignore b/kernel/.gitignore | ||
index b3097bde4e9c..084572ac1290 100644 | ||
--- a/kernel/.gitignore | ||
+++ b/kernel/.gitignore | ||
@@ -3,5 +3,6 @@ | ||
# | ||
config_data.h | ||
config_data.gz | ||
+kheaders.md5 | ||
timeconst.h | ||
hz.bc | ||
diff --git a/kernel/Makefile b/kernel/Makefile | ||
index df5e3ca30acd..d8e581bed66f 100644 | ||
--- a/kernel/Makefile | ||
+++ b/kernel/Makefile | ||
@@ -74,6 +74,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o | ||
obj-$(CONFIG_USER_NS) += user_namespace.o | ||
obj-$(CONFIG_PID_NS) += pid_namespace.o | ||
obj-$(CONFIG_IKCONFIG) += configs.o | ||
+obj-$(CONFIG_IKHEADERS_PROC) += kheaders.o | ||
obj-$(CONFIG_SMP) += stop_machine.o | ||
obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o | ||
obj-$(CONFIG_AUDIT) += audit.o auditfilter.o | ||
@@ -128,3 +129,12 @@ $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE | ||
targets += config_data.h | ||
$(obj)/config_data.h: $(obj)/config_data.gz FORCE | ||
$(call filechk,ikconfiggz) | ||
+ | ||
+$(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz | ||
+ | ||
+quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz | ||
+cmd_genikh = $(srctree)/kernel/gen_ikh_data.sh $@ | ||
+$(obj)/kheaders_data.tar.xz: FORCE | ||
+ $(call cmd,genikh) | ||
+ | ||
+clean-files := kheaders_data.tar.xz kheaders.md5 | ||
diff --git a/kernel/gen_ikh_data.sh b/kernel/gen_ikh_data.sh | ||
new file mode 100755 | ||
index 000000000000..591a94f7b387 | ||
--- /dev/null | ||
+++ b/kernel/gen_ikh_data.sh | ||
@@ -0,0 +1,89 @@ | ||
+#!/bin/bash | ||
+# SPDX-License-Identifier: GPL-2.0 | ||
+ | ||
+# This script generates an archive consisting of kernel headers | ||
+# for CONFIG_IKHEADERS_PROC. | ||
+set -e | ||
+spath="$(dirname "$(readlink -f "$0")")" | ||
+kroot="$spath/.." | ||
+outdir="$(pwd)" | ||
+tarfile=$1 | ||
+cpio_dir=$outdir/$tarfile.tmp | ||
+ | ||
+# Script filename relative to the kernel source root | ||
+# We add it to the archive because it is small and any changes | ||
+# to this script will also cause a rebuild of the archive. | ||
+sfile="$(realpath --relative-to $kroot "$(readlink -f "$0")")" | ||
+ | ||
+src_file_list=" | ||
+include/ | ||
+arch/$SRCARCH/include/ | ||
+$sfile | ||
+" | ||
+ | ||
+obj_file_list=" | ||
+include/ | ||
+arch/$SRCARCH/include/ | ||
+" | ||
+ | ||
+# Support incremental builds by skipping archive generation | ||
+# if timestamps of files being archived are not changed. | ||
+ | ||
+# This block is useful for debugging the incremental builds. | ||
+# Uncomment it for debugging. | ||
+# iter=1 | ||
+# if [ ! -f /tmp/iter ]; then echo 1 > /tmp/iter; | ||
+# else; iter=$(($(cat /tmp/iter) + 1)); fi | ||
+# find $src_file_list -type f | xargs ls -lR > /tmp/src-ls-$iter | ||
+# find $obj_file_list -type f | xargs ls -lR > /tmp/obj-ls-$iter | ||
+ | ||
+# include/generated/compile.h is ignored because it is touched even when none | ||
+# of the source files changed. This causes pointless regeneration, so let us | ||
+# ignore them for md5 calculation. | ||
+pushd $kroot > /dev/null | ||
+src_files_md5="$(find $src_file_list -type f | | ||
+ grep -v "include/generated/compile.h" | | ||
+ xargs ls -lR | md5sum | cut -d ' ' -f1)" | ||
+popd > /dev/null | ||
+obj_files_md5="$(find $obj_file_list -type f | | ||
+ grep -v "include/generated/compile.h" | | ||
+ xargs ls -lR | md5sum | cut -d ' ' -f1)" | ||
+ | ||
+if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi | ||
+if [ -f kernel/kheaders.md5 ] && | ||
+ [ "$(cat kernel/kheaders.md5|head -1)" == "$src_files_md5" ] && | ||
+ [ "$(cat kernel/kheaders.md5|head -2|tail -1)" == "$obj_files_md5" ] && | ||
+ [ "$(cat kernel/kheaders.md5|tail -1)" == "$tarfile_md5" ]; then | ||
+ exit | ||
+fi | ||
+ | ||
+if [ "${quiet}" != "silent_" ]; then | ||
+ echo " GEN $tarfile" | ||
+fi | ||
+ | ||
+rm -rf $cpio_dir | ||
+mkdir $cpio_dir | ||
+ | ||
+pushd $kroot > /dev/null | ||
+for f in $src_file_list; | ||
+ do find "$f" ! -name "*.cmd" ! -name ".*"; | ||
+done | cpio --quiet -pd $cpio_dir | ||
+popd > /dev/null | ||
+ | ||
+# The second CPIO can complain if files already exist which can | ||
+# happen with out of tree builds. Just silence CPIO for now. | ||
+for f in $obj_file_list; | ||
+ do find "$f" ! -name "*.cmd" ! -name ".*"; | ||
+done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1 | ||
+ | ||
+# Remove comments except SDPX lines | ||
+find $cpio_dir -type f -print0 | | ||
+ xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' | ||
+ | ||
+tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null | ||
+ | ||
+echo "$src_files_md5" > kernel/kheaders.md5 | ||
+echo "$obj_files_md5" >> kernel/kheaders.md5 | ||
+echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5 | ||
+ | ||
+rm -rf $cpio_dir | ||
diff --git a/kernel/kheaders.c b/kernel/kheaders.c | ||
new file mode 100644 | ||
index 000000000000..70ae6052920d | ||
--- /dev/null | ||
+++ b/kernel/kheaders.c | ||
@@ -0,0 +1,74 @@ | ||
+// SPDX-License-Identifier: GPL-2.0 | ||
+/* | ||
+ * Provide kernel headers useful to build tracing programs | ||
+ * such as for running eBPF tracing tools. | ||
+ * | ||
+ * (Borrowed code from kernel/configs.c) | ||
+ */ | ||
+ | ||
+#include <linux/kernel.h> | ||
+#include <linux/module.h> | ||
+#include <linux/proc_fs.h> | ||
+#include <linux/init.h> | ||
+#include <linux/uaccess.h> | ||
+ | ||
+/* | ||
+ * Define kernel_headers_data and kernel_headers_data_end, within which the | ||
+ * compressed kernel headers are stored. The file is first compressed with xz. | ||
+ */ | ||
+ | ||
+asm ( | ||
+" .pushsection .rodata, \"a\" \n" | ||
+" .global kernel_headers_data \n" | ||
+"kernel_headers_data: \n" | ||
+" .incbin \"kernel/kheaders_data.tar.xz\" \n" | ||
+" .global kernel_headers_data_end \n" | ||
+"kernel_headers_data_end: \n" | ||
+" .popsection \n" | ||
+); | ||
+ | ||
+extern char kernel_headers_data; | ||
+extern char kernel_headers_data_end; | ||
+ | ||
+static ssize_t | ||
+ikheaders_read_current(struct file *file, char __user *buf, | ||
+ size_t len, loff_t *offset) | ||
+{ | ||
+ return simple_read_from_buffer(buf, len, offset, | ||
+ &kernel_headers_data, | ||
+ &kernel_headers_data_end - | ||
+ &kernel_headers_data); | ||
+} | ||
+ | ||
+static const struct file_operations ikheaders_file_ops = { | ||
+ .read = ikheaders_read_current, | ||
+ .llseek = default_llseek, | ||
+}; | ||
+ | ||
+static int __init ikheaders_init(void) | ||
+{ | ||
+ struct proc_dir_entry *entry; | ||
+ | ||
+ /* create the current headers file */ | ||
+ entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL, | ||
+ &ikheaders_file_ops); | ||
+ if (!entry) | ||
+ return -ENOMEM; | ||
+ | ||
+ proc_set_size(entry, | ||
+ &kernel_headers_data_end - | ||
+ &kernel_headers_data); | ||
+ return 0; | ||
+} | ||
+ | ||
+static void __exit ikheaders_cleanup(void) | ||
+{ | ||
+ remove_proc_entry("kheaders.tar.xz", NULL); | ||
+} | ||
+ | ||
+module_init(ikheaders_init); | ||
+module_exit(ikheaders_cleanup); | ||
+ | ||
+MODULE_LICENSE("GPL v2"); | ||
+MODULE_AUTHOR("Joel Fernandes"); | ||
+MODULE_DESCRIPTION("Echo the kernel header artifacts used to build the kernel"); | ||
-- | ||
2.17.1 | ||
|
36 changes: 36 additions & 0 deletions
36
packages/kernel/0009-kernel-Makefile-don-t-assume-that-kernel-gen_ikh_dat.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Andrew Morton <[email protected]> | ||
Date: Tue, 14 May 2019 15:40:43 -0700 | ||
Subject: [PATCH 2/6] kernel/Makefile: don't assume that kernel/gen_ikh_data.sh | ||
is executable | ||
|
||
If the user downloads and applies patch-5.1.gz using patch(1), the x bit | ||
on kernel/gen_ikh_data.sh is not set. | ||
|
||
/bin/sh: 1: ./kernel/gen_ikh_data.sh: Permission denied | ||
|
||
Fix this by using CONFIG_SHELL. | ||
|
||
Signed-off-by: Andrew Morton <[email protected]> | ||
Signed-off-by: Linus Torvalds <[email protected]> | ||
(cherry picked from commit acb2ec3dd003b50b6fb5772057a08ec0dc45d42a) | ||
--- | ||
kernel/Makefile | 2 +- | ||
1 file changed, 1 insertion(+), 1 deletion(-) | ||
|
||
diff --git a/kernel/Makefile b/kernel/Makefile | ||
index d8e581bed66f..576f5293df7c 100644 | ||
--- a/kernel/Makefile | ||
+++ b/kernel/Makefile | ||
@@ -133,7 +133,7 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE | ||
$(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz | ||
|
||
quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz | ||
-cmd_genikh = $(srctree)/kernel/gen_ikh_data.sh $@ | ||
+cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_ikh_data.sh $@ | ||
$(obj)/kheaders_data.tar.xz: FORCE | ||
$(call cmd,genikh) | ||
|
||
-- | ||
2.17.1 | ||
|
Oops, something went wrong.