bootconfig: Add bootconfig magic word for indicating bootconfig explicitly
Add bootconfig magic word to the end of bootconfig on initrd image for indicating explicitly the bootconfig is there. Also tools/bootconfig treats wrong size or wrong checksum or parse error as an error, because if there is a bootconfig magic word, there must be a bootconfig. The bootconfig magic word is "#BOOTCONFIG\n", 12 bytes word. Thus the block image of the initrd file with bootconfig is as follows. [Initrd][bootconfig][size][csum][#BOOTCONFIG\n] Link: http://lkml.kernel.org/r/158220112263.26565.3944814205960612841.stgit@devnote2 Suggested-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
Родитель
d8a953ddde
Коммит
85c46b78da
|
@ -102,9 +102,13 @@ Boot Kernel With a Boot Config
|
|||
==============================
|
||||
|
||||
Since the boot configuration file is loaded with initrd, it will be added
|
||||
to the end of the initrd (initramfs) image file. The Linux kernel decodes
|
||||
the last part of the initrd image in memory to get the boot configuration
|
||||
data.
|
||||
to the end of the initrd (initramfs) image file with size, checksum and
|
||||
12-byte magic word as below.
|
||||
|
||||
[initrd][bootconfig][size(u32)][checksum(u32)][#BOOTCONFIG\n]
|
||||
|
||||
The Linux kernel decodes the last part of the initrd image in memory to
|
||||
get the boot configuration data.
|
||||
Because of this "piggyback" method, there is no need to change or
|
||||
update the boot loader and the kernel image itself.
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define BOOTCONFIG_MAGIC "#BOOTCONFIG\n"
|
||||
#define BOOTCONFIG_MAGIC_LEN 12
|
||||
|
||||
/* XBC tree node */
|
||||
struct xbc_node {
|
||||
u16 next;
|
||||
|
|
|
@ -1222,7 +1222,7 @@ config BOOT_CONFIG
|
|||
Extra boot config allows system admin to pass a config file as
|
||||
complemental extension of kernel cmdline when booting.
|
||||
The boot config file must be attached at the end of initramfs
|
||||
with checksum and size.
|
||||
with checksum, size and magic word.
|
||||
See <file:Documentation/admin-guide/bootconfig.rst> for details.
|
||||
|
||||
If unsure, say Y.
|
||||
|
|
|
@ -374,7 +374,11 @@ static void __init setup_boot_config(const char *cmdline)
|
|||
if (!initrd_end)
|
||||
goto not_found;
|
||||
|
||||
hdr = (u32 *)(initrd_end - 8);
|
||||
data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
|
||||
if (memcmp(data, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN))
|
||||
goto not_found;
|
||||
|
||||
hdr = (u32 *)(data - 8);
|
||||
size = hdr[0];
|
||||
csum = hdr[1];
|
||||
|
||||
|
|
|
@ -131,15 +131,26 @@ int load_xbc_from_initrd(int fd, char **buf)
|
|||
struct stat stat;
|
||||
int ret;
|
||||
u32 size = 0, csum = 0, rcsum;
|
||||
char magic[BOOTCONFIG_MAGIC_LEN];
|
||||
|
||||
ret = fstat(fd, &stat);
|
||||
if (ret < 0)
|
||||
return -errno;
|
||||
|
||||
if (stat.st_size < 8)
|
||||
if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
|
||||
return 0;
|
||||
|
||||
if (lseek(fd, -8, SEEK_END) < 0) {
|
||||
if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0) {
|
||||
pr_err("Failed to lseek: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
if (read(fd, magic, BOOTCONFIG_MAGIC_LEN) < 0)
|
||||
return -errno;
|
||||
/* Check the bootconfig magic bytes */
|
||||
if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
|
||||
return 0;
|
||||
|
||||
if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0) {
|
||||
pr_err("Failed to lseek: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
|
@ -150,11 +161,14 @@ int load_xbc_from_initrd(int fd, char **buf)
|
|||
if (read(fd, &csum, sizeof(u32)) < 0)
|
||||
return -errno;
|
||||
|
||||
/* Wrong size, maybe no boot config here */
|
||||
if (stat.st_size < size + 8)
|
||||
return 0;
|
||||
/* Wrong size error */
|
||||
if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
|
||||
pr_err("bootconfig size is too big\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
if (lseek(fd, stat.st_size - 8 - size, SEEK_SET) < 0) {
|
||||
if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
|
||||
SEEK_SET) < 0) {
|
||||
pr_err("Failed to lseek: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
|
@ -163,17 +177,17 @@ int load_xbc_from_initrd(int fd, char **buf)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Wrong Checksum, maybe no boot config here */
|
||||
/* Wrong Checksum */
|
||||
rcsum = checksum((unsigned char *)*buf, size);
|
||||
if (csum != rcsum) {
|
||||
pr_err("checksum error: %d != %d\n", csum, rcsum);
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = xbc_init(*buf);
|
||||
/* Wrong data, maybe no boot config here */
|
||||
/* Wrong data */
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -226,7 +240,8 @@ int delete_xbc(const char *path)
|
|||
} else if (size > 0) {
|
||||
ret = fstat(fd, &stat);
|
||||
if (!ret)
|
||||
ret = ftruncate(fd, stat.st_size - size - 8);
|
||||
ret = ftruncate(fd, stat.st_size
|
||||
- size - 8 - BOOTCONFIG_MAGIC_LEN);
|
||||
if (ret)
|
||||
ret = -errno;
|
||||
} /* Ignore if there is no boot config in initrd */
|
||||
|
@ -295,6 +310,12 @@ int apply_xbc(const char *path, const char *xbc_path)
|
|||
pr_err("Failed to apply a boot config: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
/* Write a magic word of the bootconfig */
|
||||
ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to apply a boot config magic: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
close(fd);
|
||||
free(data);
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ xpass $BOOTCONF -a $TEMPCONF $INITRD
|
|||
new_size=$(stat -c %s $INITRD)
|
||||
|
||||
echo "File size check"
|
||||
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9)
|
||||
xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9 + 12)
|
||||
|
||||
echo "Apply command repeat test"
|
||||
xpass $BOOTCONF -a $TEMPCONF $INITRD
|
||||
|
|
Загрузка…
Ссылка в новой задаче