bootconfig: Load boot config from the tail of initrd
Load the extended boot config data from the tail of initrd image. If there is an SKC data there, it has [(u32)size][(u32)checksum] header (in really, this is a footer) at the end of initrd. If the checksum (simple sum of bytes) is match, this starts parsing it from there. Link: http://lkml.kernel.org/r/157867222435.17873.9936667353335606867.stgit@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
		
				
					committed by
					
						 Steven Rostedt (VMware)
						Steven Rostedt (VMware)
					
				
			
			
				
	
			
			
			
						parent
						
							76db5a27a8
						
					
				
				
					commit
					7684b8582c
				
			| @@ -1217,6 +1217,7 @@ endif | ||||
|  | ||||
| config BOOT_CONFIG | ||||
| 	bool "Boot config support" | ||||
| 	depends on BLK_DEV_INITRD | ||||
| 	select LIBXBC | ||||
| 	default y | ||||
| 	help | ||||
|   | ||||
							
								
								
									
										54
									
								
								init/main.c
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								init/main.c
									
									
									
									
									
								
							| @@ -28,6 +28,7 @@ | ||||
| #include <linux/initrd.h> | ||||
| #include <linux/memblock.h> | ||||
| #include <linux/acpi.h> | ||||
| #include <linux/bootconfig.h> | ||||
| #include <linux/console.h> | ||||
| #include <linux/nmi.h> | ||||
| #include <linux/percpu.h> | ||||
| @@ -245,6 +246,58 @@ static int __init loglevel(char *str) | ||||
| 
 | ||||
| early_param("loglevel", loglevel); | ||||
| 
 | ||||
| #ifdef CONFIG_BOOT_CONFIG | ||||
| u32 boot_config_checksum(unsigned char *p, u32 size) | ||||
| { | ||||
| 	u32 ret = 0; | ||||
| 
 | ||||
| 	while (size--) | ||||
| 		ret += *p++; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void __init setup_boot_config(void) | ||||
| { | ||||
| 	u32 size, csum; | ||||
| 	char *data, *copy; | ||||
| 	u32 *hdr; | ||||
| 
 | ||||
| 	if (!initrd_end) | ||||
| 		return; | ||||
| 
 | ||||
| 	hdr = (u32 *)(initrd_end - 8); | ||||
| 	size = hdr[0]; | ||||
| 	csum = hdr[1]; | ||||
| 
 | ||||
| 	if (size >= XBC_DATA_MAX) | ||||
| 		return; | ||||
| 
 | ||||
| 	data = ((void *)hdr) - size; | ||||
| 	if ((unsigned long)data < initrd_start) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (boot_config_checksum((unsigned char *)data, size) != csum) | ||||
| 		return; | ||||
| 
 | ||||
| 	copy = memblock_alloc(size + 1, SMP_CACHE_BYTES); | ||||
| 	if (!copy) { | ||||
| 		pr_err("Failed to allocate memory for boot config\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	memcpy(copy, data, size); | ||||
| 	copy[size] = '\0'; | ||||
| 
 | ||||
| 	if (xbc_init(copy) < 0) | ||||
| 		pr_err("Failed to parse boot config\n"); | ||||
| 	else | ||||
| 		pr_info("Load boot config: %d bytes\n", size); | ||||
| } | ||||
| #else | ||||
| #define setup_boot_config()	do { } while (0) | ||||
| #endif | ||||
| 
 | ||||
| /* Change NUL term back to "=", to make "param" the whole string. */ | ||||
| static int __init repair_env_string(char *param, char *val, | ||||
| 				    const char *unused, void *arg) | ||||
| @@ -595,6 +648,7 @@ asmlinkage __visible void __init start_kernel(void) | ||||
| 	pr_notice("%s", linux_banner); | ||||
| 	early_security_init(); | ||||
| 	setup_arch(&command_line); | ||||
| 	setup_boot_config(); | ||||
| 	setup_command_line(command_line); | ||||
| 	setup_nr_cpu_ids(); | ||||
| 	setup_per_cpu_areas(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user