liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

kexec-map-file.patch (5339B)


      1 From 35b8bad0343a4afd9ad914e377e64bd02667c563 Mon Sep 17 00:00:00 2001
      2 From: Daniel Barlow <dan@telent.net>
      3 Date: Sun, 19 Mar 2023 17:30:30 +0000
      4 Subject: [PATCH] add --map-file option to map arbitrary files into physmem
      5 
      6 This is useful e.g. in conjunction with the MTD PHRAM device on
      7 embedded devices: a kernel can be booted with kexec and a root
      8 filesystem entirely in RAM to see if it works before writing it
      9 to flash.
     10 ---
     11  kexec/kexec.8 | 14 ++++++++++++-
     12  kexec/kexec.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
     13  kexec/kexec.h |  4 +++-
     14  3 files changed, 73 insertions(+), 2 deletions(-)
     15 
     16 diff --git a/kexec/kexec.8 b/kexec/kexec.8
     17 index 3a344c5..3140ccb 100644
     18 --- a/kexec/kexec.8
     19 +++ b/kexec/kexec.8
     20 @@ -143,10 +143,17 @@ into the current kernel.
     21  .B \-p\ (\-\-load\-panic)
     22  Load the new kernel for use on panic.
     23  .TP
     24 -.BI \-t\ (\-\-type= type )
     25 +.BI \-m\ (\-\-type= type )
     26  Specify that the new kernel is of this
     27  .I type.
     28  .TP
     29 +.BI \-t\ (\-\-map-file= filename@addr )
     30 +Read
     31 +.I filename
     32 +and arrange for it to be mapped into physical memory at the address
     33 +.I addr.
     34 +This option may be repeated if there are multiple files to map.
     35 +.TP
     36  .BI \-s\ (\-\-kexec-file-syscall)
     37  Specify that the new KEXEC_FILE_LOAD syscall should be used exclusively.
     38  .TP
     39 @@ -206,6 +213,11 @@ Reuse initrd from first boot.
     40  .BI \-\-print-ckr-size
     41  Print crash kernel region size, if available.
     42  
     43 +.PP
     44 +Options taking an
     45 +.I addr
     46 +parameter will accept a memory address written in hexadecimal (with leading
     47 +0x), or octal (leading 0), or decimal (no leading sigil).
     48  
     49  .SH SUPPORTED KERNEL FILE TYPES AND OPTIONS
     50  .B Beoboot-x86
     51 diff --git a/kexec/kexec.c b/kexec/kexec.c
     52 index 36bb2ad..c3b40a4 100644
     53 --- a/kexec/kexec.c
     54 +++ b/kexec/kexec.c
     55 @@ -63,6 +63,13 @@ static unsigned long kexec_flags = 0;
     56  static unsigned long kexec_file_flags = 0;
     57  int kexec_debug = 0;
     58  
     59 +#define MAPPED_FILES_MAX 10 	/* arbitrary number */
     60 +struct mapped_file {
     61 +	const char *filename;
     62 +	unsigned long long phys_address;
     63 +} mapped_files[MAPPED_FILES_MAX] = { { .filename = NULL } };
     64 +
     65 +
     66  void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr)
     67  {
     68  	int i;
     69 @@ -771,6 +778,19 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
     70  	}
     71  	info.kexec_flags |= native_arch;
     72  
     73 +	for(struct mapped_file *m = mapped_files; m->filename; m++) {
     74 +		off_t file_size = 0;
     75 +		char *buf = slurp_file(m->filename, &file_size);
     76 +		add_buffer(&info,
     77 +			   buf, file_size, file_size, sizeof (void *),
     78 +			   m->phys_address,
     79 +			   mem_max, 1);
     80 +		free(m->filename);
     81 +		/* do we free() memory returned by slurp_file()?
     82 +		 * we don't know if it was mmaped, so maybe not
     83 +		 */
     84 +	};
     85 +
     86  	result = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
     87  	if (result < 0) {
     88  		switch (result) {
     89 @@ -1035,6 +1055,8 @@ void usage(void)
     90  	       "                      load code into.\n"
     91  	       "     --mem-max=<addr> Specify the highest memory address to\n"
     92  	       "                      load code into.\n"
     93 +	       "     --map-file=<filename@addr> Map a file into memory for the\n"
     94 +	       "                      new kernel before kexec.\n"
     95  	       "     --reuseinitrd    Reuse initrd from first boot.\n"
     96  	       "     --print-ckr-size Print crash kernel region size.\n"
     97  	       "     --load-preserve-context Load the new kernel and preserve\n"
     98 @@ -1396,6 +1418,33 @@ static void print_crashkernel_region_size(void)
     99  	printf("%" PRIu64 "\n", (start != end) ? (end - start + 1) : 0UL);
    100  }
    101  
    102 +static int add_mapped_file(char * optarg)
    103 +{
    104 +	char *at = strchr(optarg, '@');
    105 +	if(!at)
    106 +		return 1;
    107 +
    108 +	struct mapped_file *m = mapped_files;
    109 +	struct mapped_file *m_end = mapped_files +
    110 +	    ((sizeof mapped_files) / (sizeof mapped_files[0]));
    111 +
    112 +	while(m->filename && m < m_end)
    113 +		m++;
    114 +
    115 +	if(m >= m_end)
    116 +		return 1;
    117 +
    118 +	m->phys_address = strtoull(at + 1, NULL, 0);
    119 +	if(m->phys_address == 0)
    120 +		return 1;
    121 +
    122 +	m->filename = strndup(optarg, at - optarg);
    123 +
    124 +	(m+1)->filename = NULL;
    125 +	return 0;
    126 +}
    127 +
    128 +
    129  int main(int argc, char *argv[])
    130  {
    131  	int has_opt_load = 0;
    132 @@ -1521,6 +1570,14 @@ int main(int argc, char *argv[])
    133  			kexec_file_flags |= KEXEC_FILE_ON_CRASH;
    134  			kexec_flags = KEXEC_ON_CRASH;
    135  			break;
    136 +		case OPT_MAP_FILE:
    137 +			if(add_mapped_file(optarg)) {
    138 +				fprintf(stderr,
    139 +					"Bad option value or too many mapped files in --mapped-file=%s\n",
    140 +					optarg);
    141 +				return 1;
    142 +			}
    143 +			break;
    144  		case OPT_MEM_MIN:
    145  			mem_min = strtoul(optarg, &endptr, 0);
    146  			if (*endptr) {
    147 diff --git a/kexec/kexec.h b/kexec/kexec.h
    148 index 0d820ad..78022b6 100644
    149 --- a/kexec/kexec.h
    150 +++ b/kexec/kexec.h
    151 @@ -224,6 +224,7 @@ extern int file_types;
    152  #define OPT_STATUS		'S'
    153  #define OPT_MEM_MIN             256
    154  #define OPT_MEM_MAX             257
    155 +#define OPT_MAP_FILE		'm'
    156  #define OPT_REUSE_INITRD	258
    157  #define OPT_LOAD_PRESERVE_CONTEXT 259
    158  #define OPT_LOAD_JUMP_BACK_HELPER 260
    159 @@ -258,8 +259,9 @@ extern int file_types;
    160  	{ "debug",		0, 0, OPT_DEBUG }, \
    161  	{ "status",		0, 0, OPT_STATUS }, \
    162  	{ "print-ckr-size",     0, 0, OPT_PRINT_CKR_SIZE }, \
    163 +	{ "map-file",		1, 0, OPT_MAP_FILE }, \
    164  
    165 -#define KEXEC_OPT_STR "h?vdfixyluet:pscaS"
    166 +#define KEXEC_OPT_STR "h?vdfixyluet:pscaSm"
    167  
    168  extern void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr);
    169  extern void die(const char *fmt, ...)
    170 -- 
    171 2.38.1
    172