Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d35ce356 authored by Andrew Boie's avatar Andrew Boie
Browse files

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: default avatarAndrew Boie <andrew.p.boie@intel.com>
parent 2e63e71f
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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
{
@@ -47,6 +48,10 @@ struct boot_img_hdr
    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];
};

/*
+11 −2
Original line number Diff line number Diff line
@@ -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) {