mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									d8a953ddde
								
							
						
					
					
						commit
						85c46b78da
					
				
					 6 changed files with 49 additions and 17 deletions
				
			
		| 
						 | 
					@ -102,9 +102,13 @@ Boot Kernel With a Boot Config
 | 
				
			||||||
==============================
 | 
					==============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Since the boot configuration file is loaded with initrd, it will be added
 | 
					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
 | 
					to the end of the initrd (initramfs) image file with size, checksum and
 | 
				
			||||||
the last part of the initrd image in memory to get the boot configuration
 | 
					12-byte magic word as below.
 | 
				
			||||||
data.
 | 
					
 | 
				
			||||||
 | 
					[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
 | 
					Because of this "piggyback" method, there is no need to change or
 | 
				
			||||||
update the boot loader and the kernel image itself.
 | 
					update the boot loader and the kernel image itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,9 @@
 | 
				
			||||||
#include <linux/kernel.h>
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BOOTCONFIG_MAGIC	"#BOOTCONFIG\n"
 | 
				
			||||||
 | 
					#define BOOTCONFIG_MAGIC_LEN	12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* XBC tree node */
 | 
					/* XBC tree node */
 | 
				
			||||||
struct xbc_node {
 | 
					struct xbc_node {
 | 
				
			||||||
	u16 next;
 | 
						u16 next;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1222,7 +1222,7 @@ config BOOT_CONFIG
 | 
				
			||||||
	  Extra boot config allows system admin to pass a config file as
 | 
						  Extra boot config allows system admin to pass a config file as
 | 
				
			||||||
	  complemental extension of kernel cmdline when booting.
 | 
						  complemental extension of kernel cmdline when booting.
 | 
				
			||||||
	  The boot config file must be attached at the end of initramfs
 | 
						  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.
 | 
						  See <file:Documentation/admin-guide/bootconfig.rst> for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  If unsure, say Y.
 | 
						  If unsure, say Y.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -374,7 +374,11 @@ static void __init setup_boot_config(const char *cmdline)
 | 
				
			||||||
	if (!initrd_end)
 | 
						if (!initrd_end)
 | 
				
			||||||
		goto not_found;
 | 
							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];
 | 
						size = hdr[0];
 | 
				
			||||||
	csum = hdr[1];
 | 
						csum = hdr[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,15 +131,26 @@ int load_xbc_from_initrd(int fd, char **buf)
 | 
				
			||||||
	struct stat stat;
 | 
						struct stat stat;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	u32 size = 0, csum = 0, rcsum;
 | 
						u32 size = 0, csum = 0, rcsum;
 | 
				
			||||||
 | 
						char magic[BOOTCONFIG_MAGIC_LEN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = fstat(fd, &stat);
 | 
						ret = fstat(fd, &stat);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return -errno;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stat.st_size < 8)
 | 
						if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
 | 
				
			||||||
		return 0;
 | 
							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);
 | 
							pr_err("Failed to lseek: %d\n", -errno);
 | 
				
			||||||
		return -errno;
 | 
							return -errno;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -150,11 +161,14 @@ int load_xbc_from_initrd(int fd, char **buf)
 | 
				
			||||||
	if (read(fd, &csum, sizeof(u32)) < 0)
 | 
						if (read(fd, &csum, sizeof(u32)) < 0)
 | 
				
			||||||
		return -errno;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wrong size, maybe no boot config here */
 | 
						/* Wrong size error  */
 | 
				
			||||||
	if (stat.st_size < size + 8)
 | 
						if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
 | 
				
			||||||
		return 0;
 | 
							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);
 | 
							pr_err("Failed to lseek: %d\n", -errno);
 | 
				
			||||||
		return -errno;
 | 
							return -errno;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -163,17 +177,17 @@ int load_xbc_from_initrd(int fd, char **buf)
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wrong Checksum, maybe no boot config here */
 | 
						/* Wrong Checksum */
 | 
				
			||||||
	rcsum = checksum((unsigned char *)*buf, size);
 | 
						rcsum = checksum((unsigned char *)*buf, size);
 | 
				
			||||||
	if (csum != rcsum) {
 | 
						if (csum != rcsum) {
 | 
				
			||||||
		pr_err("checksum error: %d != %d\n", csum, rcsum);
 | 
							pr_err("checksum error: %d != %d\n", csum, rcsum);
 | 
				
			||||||
		return 0;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = xbc_init(*buf);
 | 
						ret = xbc_init(*buf);
 | 
				
			||||||
	/* Wrong data, maybe no boot config here */
 | 
						/* Wrong data */
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return 0;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return size;
 | 
						return size;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -226,7 +240,8 @@ int delete_xbc(const char *path)
 | 
				
			||||||
	} else if (size > 0) {
 | 
						} else if (size > 0) {
 | 
				
			||||||
		ret = fstat(fd, &stat);
 | 
							ret = fstat(fd, &stat);
 | 
				
			||||||
		if (!ret)
 | 
							if (!ret)
 | 
				
			||||||
			ret = ftruncate(fd, stat.st_size - size - 8);
 | 
								ret = ftruncate(fd, stat.st_size
 | 
				
			||||||
 | 
										- size - 8 - BOOTCONFIG_MAGIC_LEN);
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			ret = -errno;
 | 
								ret = -errno;
 | 
				
			||||||
	} /* Ignore if there is no boot config in initrd */
 | 
						} /* 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);
 | 
							pr_err("Failed to apply a boot config: %d\n", ret);
 | 
				
			||||||
		return 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);
 | 
						close(fd);
 | 
				
			||||||
	free(data);
 | 
						free(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ xpass $BOOTCONF -a $TEMPCONF $INITRD
 | 
				
			||||||
new_size=$(stat -c %s $INITRD)
 | 
					new_size=$(stat -c %s $INITRD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "File size check"
 | 
					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"
 | 
					echo "Apply command repeat test"
 | 
				
			||||||
xpass $BOOTCONF -a $TEMPCONF $INITRD
 | 
					xpass $BOOTCONF -a $TEMPCONF $INITRD
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue