diff options
author | Andrew Boie <andrew.p.boie@intel.com> | 2013-08-21 15:48:40 -0700 |
---|---|---|
committer | Andrew Boie <andrew.p.boie@intel.com> | 2013-09-09 13:13:33 -0700 |
commit | d35ce3563b4d86702cec4c8f7031fb8a1c55cac2 (patch) | |
tree | dcbbb0894f475de81940203e2e8a7f7a2587efc9 /mkbootimg | |
parent | 2e63e71f3116f0330b3bf61dde7deca235dd40ac (diff) | |
download | system_core-d35ce3563b4d86702cec4c8f7031fb8a1c55cac2.tar.gz system_core-d35ce3563b4d86702cec4c8f7031fb8a1c55cac2.tar.bz2 system_core-d35ce3563b4d86702cec4c8f7031fb8a1c55cac2.zip |
mkbootimg: support longer kernel command lines
We can't simply increase the value of BOOT_ARGS_SIZE since that
would break past binary compatibility; the offset of 'id' would
change. This can cause serious problems with incremental OTA updates.
Instead, define a supplemental field which stores command line
information beyond the first 512 bytes. A value of 1024 was chosen
to keep the total size of struct boot_img_hdr under the smallest
page size of 2048 bytes.
Even if the extra_cmdline field is used, the original cmdline
field is still always NULL-terminated to avoid issues with older
bootloaders that haven't been updated.
Change-Id: I887e6f1db351a5b71a61e3a03363cf8856123d74
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Diffstat (limited to 'mkbootimg')
-rw-r--r-- | mkbootimg/bootimg.h | 7 | ||||
-rw-r--r-- | mkbootimg/mkbootimg.c | 13 |
2 files changed, 17 insertions, 3 deletions
diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h index 242ab35db..9171d85a7 100644 --- a/mkbootimg/bootimg.h +++ b/mkbootimg/bootimg.h @@ -24,6 +24,7 @@ typedef struct boot_img_hdr boot_img_hdr; #define BOOT_MAGIC_SIZE 8 #define BOOT_NAME_SIZE 16 #define BOOT_ARGS_SIZE 512 +#define BOOT_EXTRA_ARGS_SIZE 1024 struct boot_img_hdr { @@ -43,10 +44,14 @@ struct boot_img_hdr unsigned unused[2]; /* future expansion: should be 0 */ unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ - + unsigned char cmdline[BOOT_ARGS_SIZE]; unsigned id[8]; /* timestamp / checksum / sha1 / etc */ + + /* Supplemental command line data; kept here to maintain + * binary compatibility with older versions of mkbootimg */ + unsigned char extra_cmdline[BOOT_EXTRA_ARGS_SIZE]; }; /* diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c index 34a879b5a..d598f0395 100644 --- a/mkbootimg/mkbootimg.c +++ b/mkbootimg/mkbootimg.c @@ -114,6 +114,7 @@ int main(int argc, char **argv) unsigned ramdisk_offset = 0x01000000; unsigned second_offset = 0x00f00000; unsigned tags_offset = 0x00000100; + size_t cmdlen; argc--; argv++; @@ -192,11 +193,19 @@ int main(int argc, char **argv) memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); - if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { + cmdlen = strlen(cmdline); + if(cmdlen > (BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 2)) { fprintf(stderr,"error: kernel commandline too large\n"); return 1; } - strcpy((char*)hdr.cmdline, cmdline); + /* Even if we need to use the supplemental field, ensure we + * are still NULL-terminated */ + strncpy((char *)hdr.cmdline, cmdline, BOOT_ARGS_SIZE - 1); + hdr.cmdline[BOOT_ARGS_SIZE - 1] = '\0'; + if (cmdlen >= (BOOT_ARGS_SIZE - 1)) { + cmdline += (BOOT_ARGS_SIZE - 1); + strncpy((char *)hdr.extra_cmdline, cmdline, BOOT_EXTRA_ARGS_SIZE); + } kernel_data = load_file(kernel_fn, &hdr.kernel_size); if(kernel_data == 0) { |