Message ID | 20191023143427.10865-4-semen.protsenko@linaro.org |
---|---|
State | Changes Requested |
Delegated to: | Tom Rini |
Headers | show |
Series | am57xx: Implement Android 10 boot flow | expand |
Hi Sam, On Wed, 23 Oct 2019 at 08:34, Sam Protsenko <semen.protsenko@linaro.org> wrote: > > This command can be used to extract fields and image payloads from > Android Boot Image. It can be used for example to implement boot flow > where dtb is taken from boot.img (as v2 incorporated dtb inside of > boot.img). Using this command, one can obtain needed dtb file from > boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" > partition) on top of that, providing then the resulting image to bootm > command in order to boot the Android. > > Also right now this command has the sub-command to get an address and > size of recovery dtbo from recovery image. It can be further parsed using > 'dtimg' command and merged into dtb file (for non-A/B devices only, see > [1,2] for details). > > [1] https://source.android.com/devices/bootloader/boot-image-header > [2] https://source.android.com/devices/architecture/dto/partitions > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> > --- > Changes in v2: > - add "set_addr" sub-command > - provide mem mappings for sandbox > - rebase on top of master > > cmd/Kconfig | 8 ++ > cmd/Makefile | 1 + > cmd/bootimg.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 219 insertions(+) > create mode 100644 cmd/bootimg.c Sorry I still think this name 'bootimg' is confusing. How would anyone know that it is specific to Android? How about abootimg? Regards, Simon
Hi Sam, On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > +static int do_bootimg_get_dtb_file(cmd_tbl_t *cmdtp, int flag, int argc, > + char * const argv[]) > +{ > + char *endp; > + char buf[65]; > + u32 index; > + ulong addr; > + u32 size; > + > + if (argc < 3 || argc > 4) > + return CMD_RET_USAGE; > + > + index = simple_strtoul(argv[1], &endp, 0); > + if (*endp != '\0') { > + printf("Error: Wrong index\n"); > + return CMD_RET_FAILURE; > + } > + > + if (!android_image_get_dtb_by_index(bootimg_addr(), index, &addr, > + &size)) As discussed in https://patchwork.ozlabs.org/patch/958594/#2302310, we try to enhance the "dtimg" U-Boot command to be able to identify DT blobs by "id" or "rev" [*] field value. It's quite challenging in this context to avoid conflicting with your recently proposed "bootimg" command, since the latter makes use of the android_image_get_dtb_by_index API, which is subject of modification and/or renaming. I am willing to cooperate to entirely avoid or reconcile the conflict in the best possible way, but for that I need your feedback. [*] https://source.android.google.cn/devices/architecture/dto/partitions
Hi Eugeniu, On Wed, Nov 27, 2019 at 9:17 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote: > > Hi Sam, > > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > > +static int do_bootimg_get_dtb_file(cmd_tbl_t *cmdtp, int flag, int argc, > > + char * const argv[]) > > +{ > > + char *endp; > > + char buf[65]; > > + u32 index; > > + ulong addr; > > + u32 size; > > + > > + if (argc < 3 || argc > 4) > > + return CMD_RET_USAGE; > > + > > + index = simple_strtoul(argv[1], &endp, 0); > > + if (*endp != '\0') { > > + printf("Error: Wrong index\n"); > > + return CMD_RET_FAILURE; > > + } > > + > > + if (!android_image_get_dtb_by_index(bootimg_addr(), index, &addr, > > + &size)) > > As discussed in https://patchwork.ozlabs.org/patch/958594/#2302310, we > try to enhance the "dtimg" U-Boot command to be able to identify DT > blobs by "id" or "rev" [*] field value. > > It's quite challenging in this context to avoid conflicting with your > recently proposed "bootimg" command, since the latter makes use of the > android_image_get_dtb_by_index API, which is subject of modification > and/or renaming. > > I am willing to cooperate to entirely avoid or reconcile the conflict > in the best possible way, but for that I need your feedback. > I'd like this patch series to be applied ASAP (probably before DTBO patches you mention are merged). It's been too long as it is. Once merged and we are unblocked w.r.t. Android boot stuff, we can then look into DTBO changes you mention, and if any C API are changed, we can change those usage overall the U-Boot tree. Hope you agree. I will help you guys to figure out all DTBO related changes further, but please let's get this patch series over with... Thanks! > [*] https://source.android.google.cn/devices/architecture/dto/partitions > > -- > Best Regards, > Eugeniu
Hi Sam, Cc: Aleksandr, Roman As expressed in the attached e-mail, to minimize the headaches extending the argument list of "bootimg" in future, can we please agree on below? On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > +U_BOOT_CMD( > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > + "manipulate Android Boot Image", > + "set_addr <addr>\n" > + " - set the address in RAM where boot image is located\n" > + " ($loadaddr is used by default)\n" > + "bootimg ver <varname>\n" Can we make <varname> optional, with the background provided in [1]? > + " - get header version\n" > + "bootimg get_dtbo <addr_var> [size_var]\n" How about converting <addr_var> to an optional argument too? > + " - get address and size (hex) of recovery DTBO area in the image\n" > + " <addr_var>: variable name to contain DTBO area address\n" > + " [size_var]: variable name to contain DTBO area size\n" > + "bootimg dtb_dump\n" > + " - print info for all files in DTB area\n" > + "bootimg dtb_load_addr <varname>\n" Same as above w.r.t. <varname>. > + " - get load address (hex) of DTB\n" > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" How about converting <addr_var> to an optional argument too? How do you foresee getting a blob entry based on id=<i> and/or rev=<r>? Which of below is your favorite option? - get_dtb_file <index> [--id=<i>] [--rev=<r>] [addr_var] [size_var] where: - in case <i> and/or <r> are provided, <index> tells the command to pick the N's entry in the selection filtered by <i> and <r> - in case neither <i> nor <r> is provided, <index> behaves like in the current patch (selects a blob entry found at absolute index value ${index} in the image) - get_dtb_file [<index>|[--id=<i>|--rev=<r>]] [addr_var] [size_var] To make it clear, some example commands would be: - get_dtb_file <index> => current behavior - get_dtb_file --id=<i> => get _first_ blob entry matching id value <i> - get_dtb_file --rev=<r> => get _first_ blob entry matching rev value <r> - get_dtb_file --id=<i> --rev=<r> => get _first_ blob entry matching id <i> _and_ rev=<r> - get_dtb_file <index> --id=<i> - get_dtb_file <index> --rev=<r> => Wrong usage - get_dtb_file anything else? I think it is crucial to agree on the above, since the very first revision of "bootimg"/"abootimg" may impose strict limitations on how the command can be extended in future. [just noticed your reply shedding more light on a subset of these questions, but still sending this out; please skip if already answered] > + " - get address and size (hex) of DTB file in the image\n" > + " <index>: index of desired DTB file in DTB area\n" > + " <addr_var>: variable name to contain DTB file address\n" > + " [size_var]: variable name to contain DTB file size\n" > +); [1] https://patchwork.ozlabs.org/patch/1202579/ ("cmd: dtimg: Make <varname> an optional argument")
Hi Sam, On Mon, Dec 02, 2019 at 09:07:15PM +0200, Sam Protsenko wrote: > I'd like this patch series to be applied ASAP (probably before DTBO > patches you mention are merged). It's been too long as it is. Once > merged and we are unblocked w.r.t. Android boot stuff, we can then > look into DTBO changes you mention, and if any C API are changed, we > can change those usage overall the U-Boot tree. Hope you agree. I will > help you guys to figure out all DTBO related changes further, but > please let's get this patch series over with... > > Thanks! [to avoid this comment of yours unanswered] I am ready to provide the Reviewed-by for your Android 10 series, as soon as the review points summarized in [*] are taken care of. [*] https://patchwork.ozlabs.org/patch/1182207/#2317118
Hello Sam, Please, see one more suggestion below. On Tue, Dec 03, 2019 at 08:29:10PM +0100, Eugeniu Rosca wrote: > Hi Sam, > Cc: Aleksandr, Roman > > As expressed in the attached e-mail, to minimize the headaches extending > the argument list of "bootimg" in future, can we please agree on below? > > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > > +U_BOOT_CMD( > > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > > + "manipulate Android Boot Image", > > + "set_addr <addr>\n" > > + " - set the address in RAM where boot image is located\n" > > + " ($loadaddr is used by default)\n" > > + "bootimg ver <varname>\n" > > Can we make <varname> optional, with the background provided in [1]? > > > + " - get header version\n" > > + "bootimg get_dtbo <addr_var> [size_var]\n" > > How about converting <addr_var> to an optional argument too? > > > + " - get address and size (hex) of recovery DTBO area in the image\n" > > + " <addr_var>: variable name to contain DTBO area address\n" > > + " [size_var]: variable name to contain DTBO area size\n" > > + "bootimg dtb_dump\n" > > + " - print info for all files in DTB area\n" > > + "bootimg dtb_load_addr <varname>\n" > > Same as above w.r.t. <varname>. > > > + " - get load address (hex) of DTB\n" > > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" How about "get_dte" or "get_dtbe" instead of "get_dtb_file" ? It's shorter and should be easier to remember (dt{b}e = DT{B} Entry).
Hi again, [I would be willing to take this discussion offline, if you consider it too noisy for ML] On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > +U_BOOT_CMD( > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > + "manipulate Android Boot Image", > + "set_addr <addr>\n" > + " - set the address in RAM where boot image is located\n" > + " ($loadaddr is used by default)\n" > + "bootimg ver <varname>\n" > + " - get header version\n" > + "bootimg get_dtbo <addr_var> [size_var]\n" > + " - get address and size (hex) of recovery DTBO area in the image\n" > + " <addr_var>: variable name to contain DTBO area address\n" > + " [size_var]: variable name to contain DTBO area size\n" > + "bootimg dtb_dump\n" > + " - print info for all files in DTB area\n" I now see that "DTBO area" is used intermixed with "DTB area". I think it makes sense to use one of the two consistently and drop the other. Otherwise, users might think there are two distinct areas in the same Android image. > + "bootimg dtb_load_addr <varname>\n" > + " - get load address (hex) of DTB\n" This is actually not something retrieved from the DTB/DTBO area, but from the "dtb_addr" field of the Android Image itself, as defined in https://android.googlesource.com/platform/system/tools/mkbootimg/+/refs/heads/master/include/bootimg/bootimg.h I think this little bit of information is essential, but not sure how to make it more transparent to the user, since purely based on the available help message, I tend to infer that there is connection between "DTB" in "get load address (hex) of DTB" and the "DTBO area", while there is no connection whatsoever. > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" > + " - get address and size (hex) of DTB file in the image\n" > + " <index>: index of desired DTB file in DTB area\n" > + " <addr_var>: variable name to contain DTB file address\n" > + " [size_var]: variable name to contain DTB file size\n" Would it make more sense to use "DTB entry" instead of "DTB file" since this is the wording used in the Google spec/header? Another general comment regarding the current sub-commands: - set_addr - ver - get_dtbo - dtb_dump - dtb_load_addr - get_dtb_file I observe the following (inconsistent) pattern: - <do>_<what> - <what> - <do>_<what> - <what>_<do> - <what>_<do>_<what> - <do>_<what> Looking at the "fdt" command, I find its sub-commands somehow better partitioned and easier to digest/remember: fdt addr [-c] <addr> [<length>] fdt apply <addr> fdt move <fdt> <newaddr> <length> fdt resize [<extrasize>] fdt print <path> [<prop>] fdt list <path> [<prop>] fdt get value <var> <path> <prop> fdt get name <var> <path> <index> fdt get addr <var> <path> <prop> fdt get size <var> <path> [<prop>] fdt set <path> <prop> [<val>] fdt mknode <path> <node> fdt rm <path> [<prop>] fdt header [get <var> <member>] Its syntax seems to be: <command> <do> <what> [options] Would it make sense to borrow this naming style/principle? It could translate to the following for abootimg: abootimg (current sub-command name enclosed in brackets): - addr (set_addr) - ver - dump dtbo (dtb_dump) - get dtbo (get_dtbo) - get dtbe (get_dtb_file) - get dtla (dtb_load_addr) > +);
Hi, On Tue, Dec 3, 2019 at 9:29 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote: > > Hi Sam, > Cc: Aleksandr, Roman > > As expressed in the attached e-mail, to minimize the headaches extending > the argument list of "bootimg" in future, can we please agree on below? > > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > > +U_BOOT_CMD( > > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > > + "manipulate Android Boot Image", > > + "set_addr <addr>\n" > > + " - set the address in RAM where boot image is located\n" > > + " ($loadaddr is used by default)\n" > > + "bootimg ver <varname>\n" > > Can we make <varname> optional, with the background provided in [1]? > Already done in v3 (will send soon). > > + " - get header version\n" > > + "bootimg get_dtbo <addr_var> [size_var]\n" > > How about converting <addr_var> to an optional argument too? > Already done in v3. > > + " - get address and size (hex) of recovery DTBO area in the image\n" > > + " <addr_var>: variable name to contain DTBO area address\n" > > + " [size_var]: variable name to contain DTBO area size\n" > > + "bootimg dtb_dump\n" > > + " - print info for all files in DTB area\n" > > + "bootimg dtb_load_addr <varname>\n" > > Same as above w.r.t. <varname>. > Already done in v3. > > + " - get load address (hex) of DTB\n" > > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" > > How about converting <addr_var> to an optional argument too? Already done in v3. > How do you foresee getting a blob entry based on id=<i> and/or > rev=<r>? Which of below is your favorite option? > > - get_dtb_file <index> [--id=<i>] [--rev=<r>] [addr_var] [size_var] > where: - in case <i> and/or <r> are provided, <index> tells the > command to pick the N's entry in the selection filtered by > <i> and <r> > - in case neither <i> nor <r> is provided, <index> > behaves like in the current patch (selects a blob entry > found at absolute index value ${index} in the image) > > - get_dtb_file [<index>|[--id=<i>|--rev=<r>]] [addr_var] [size_var] > To make it clear, some example commands would be: > - get_dtb_file <index> > => current behavior > - get_dtb_file --id=<i> > => get _first_ blob entry matching id value <i> > - get_dtb_file --rev=<r> > => get _first_ blob entry matching rev value <r> > - get_dtb_file --id=<i> --rev=<r> > => get _first_ blob entry matching id <i> _and_ rev=<r> > - get_dtb_file <index> --id=<i> > - get_dtb_file <index> --rev=<r> > => Wrong usage > > - get_dtb_file anything else? > I already came up with next usage: abootimg get_dtb_file index <num> [addr_var] [size_var] It's already done in v3. Once your patch series is merged, I will add next two sub-commands: abootimg get_dtb_file id <num> [addr_var] [size_var] abootimg get_dtb_file rev <num> [addr_var] [size_var] This way it's extensible. Also please see my review for your patches, esp. for patch 4/4, where I discuss similar matter in context of 'dtimg' command. > I think it is crucial to agree on the above, since the very first > revision of "bootimg"/"abootimg" may impose strict limitations on how > the command can be extended in future. > All those are addressed in v3 now. Along with renaming: 'bootimg' -> 'abootimg'. The only thing remains to be addressed is Kconfig/Makefile decisions you mentioned. Will look into that tomorrow, and either make it as you pointed out or explain why it's good as it is. > [just noticed your reply shedding more light on a subset of these > questions, but still sending this out; please skip if already answered] > > > + " - get address and size (hex) of DTB file in the image\n" > > + " <index>: index of desired DTB file in DTB area\n" > > + " <addr_var>: variable name to contain DTB file address\n" > > + " [size_var]: variable name to contain DTB file size\n" > > +); > > [1] https://patchwork.ozlabs.org/patch/1202579/ > ("cmd: dtimg: Make <varname> an optional argument") > > -- > Best Regards, > Eugeniu
Hi, On Wed, Dec 4, 2019 at 7:33 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote: > > Hello Sam, > Please, see one more suggestion below. > > On Tue, Dec 03, 2019 at 08:29:10PM +0100, Eugeniu Rosca wrote: > > Hi Sam, > > Cc: Aleksandr, Roman > > > > As expressed in the attached e-mail, to minimize the headaches extending > > the argument list of "bootimg" in future, can we please agree on below? > > > > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > > > +U_BOOT_CMD( > > > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > > > + "manipulate Android Boot Image", > > > + "set_addr <addr>\n" > > > + " - set the address in RAM where boot image is located\n" > > > + " ($loadaddr is used by default)\n" > > > + "bootimg ver <varname>\n" > > > > Can we make <varname> optional, with the background provided in [1]? > > > > > + " - get header version\n" > > > + "bootimg get_dtbo <addr_var> [size_var]\n" > > > > How about converting <addr_var> to an optional argument too? > > > > > + " - get address and size (hex) of recovery DTBO area in the image\n" > > > + " <addr_var>: variable name to contain DTBO area address\n" > > > + " [size_var]: variable name to contain DTBO area size\n" > > > + "bootimg dtb_dump\n" > > > + " - print info for all files in DTB area\n" > > > + "bootimg dtb_load_addr <varname>\n" > > > > Same as above w.r.t. <varname>. > > > > > + " - get load address (hex) of DTB\n" > > > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" > > How about "get_dte" or "get_dtbe" instead of "get_dtb_file" ? > It's shorter and should be easier to remember (dt{b}e = DT{B} Entry). > Sorry, I like get_dtb more. It's .dtb file in the end, and it's called exactly "dtb" in boot.img struct. So this is a keeper :) > -- > Best Regards, > Eugeniu
Hi, On Wed, Dec 4, 2019 at 8:25 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote: > > Hi again, > > [I would be willing to take this discussion offline, if you consider it > too noisy for ML] > Agreed. Please find me on freenode IRC, nick: joeskb7. There is #u-boot channel, or #linaro-android, whichever suits you best. > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > > +U_BOOT_CMD( > > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > > + "manipulate Android Boot Image", > > + "set_addr <addr>\n" > > + " - set the address in RAM where boot image is located\n" > > + " ($loadaddr is used by default)\n" > > + "bootimg ver <varname>\n" > > + " - get header version\n" > > + "bootimg get_dtbo <addr_var> [size_var]\n" > > + " - get address and size (hex) of recovery DTBO area in the image\n" > > + " <addr_var>: variable name to contain DTBO area address\n" > > + " [size_var]: variable name to contain DTBO area size\n" > > + "bootimg dtb_dump\n" > > + " - print info for all files in DTB area\n" > > I now see that "DTBO area" is used intermixed with "DTB area". > I think it makes sense to use one of the two consistently and drop the > other. Otherwise, users might think there are two distinct areas in > the same Android image. > Those are, in fact, two different areas in boot.img. "DTBO area" is a payload in boot.img where recovery dtbo file can be placed. "DTB area" is a payload in boot.img where DTB files can be placed (either concatenated or wrapped into DTBO image format). > > + "bootimg dtb_load_addr <varname>\n" > > + " - get load address (hex) of DTB\n" > > This is actually not something retrieved from the DTB/DTBO area, but > from the "dtb_addr" field of the Android Image itself, as defined in > https://android.googlesource.com/platform/system/tools/mkbootimg/+/refs/heads/master/include/bootimg/bootimg.h > > I think this little bit of information is essential, but not sure how to > make it more transparent to the user, since purely based on the > available help message, I tend to infer that there is connection between > "DTB" in "get load address (hex) of DTB" and the "DTBO area", while > there is no connection whatsoever. > Let's keep command usage length reasonable. We are bloating U-Boot footprint too much as it is already... I think user shouldn't care where the load address is obtained from, really. Prefer to keep it short, as it is. > > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" > > + " - get address and size (hex) of DTB file in the image\n" > > + " <index>: index of desired DTB file in DTB area\n" > > + " <addr_var>: variable name to contain DTB file address\n" > > + " [size_var]: variable name to contain DTB file size\n" > > Would it make more sense to use "DTB entry" instead of "DTB file" > since this is the wording used in the Google spec/header? > I'd argue that "DTB file" is more clear for user, than "entry". If you don't have a strong preference on this one, let's keep it as is. > Another general comment regarding the current sub-commands: > - set_addr > - ver > - get_dtbo > - dtb_dump > - dtb_load_addr > - get_dtb_file > > I observe the following (inconsistent) pattern: > - <do>_<what> > - <what> > - <do>_<what> > - <what>_<do> > - <what>_<do>_<what> > - <do>_<what> > > Looking at the "fdt" command, I find its sub-commands > somehow better partitioned and easier to digest/remember: > > fdt addr [-c] <addr> [<length>] > fdt apply <addr> > fdt move <fdt> <newaddr> <length> > fdt resize [<extrasize>] > fdt print <path> [<prop>] > fdt list <path> [<prop>] > fdt get value <var> <path> <prop> > fdt get name <var> <path> <index> > fdt get addr <var> <path> <prop> > fdt get size <var> <path> [<prop>] > fdt set <path> <prop> [<val>] > fdt mknode <path> <node> > fdt rm <path> [<prop>] > fdt header [get <var> <member>] > > Its syntax seems to be: > <command> <do> <what> [options] > > Would it make sense to borrow this naming style/principle? > It could translate to the following for abootimg: > > abootimg (current sub-command name enclosed in brackets): > - addr (set_addr) > - ver > - dump dtbo (dtb_dump) > - get dtbo (get_dtbo) > - get dtbe (get_dtb_file) > - get dtla (dtb_load_addr) > Makes sense. I'll think about it. Thanks for review! > > +); > > -- > Best Regards, > Eugeniu
Hello Sam, I'd like to add my 5 cents regarding separating dtimg start|size into 3 subcommands > dtimg start index <num> <addr> [varname] > dtimg start id <num> <addr> [varname] > dtimg start rev <num> <addr> [varname] > > While I don't see real usecases for combining index with id or rev (if someone applies metainformation to dtb entries for meaningful lookup, identical entries most probably mean copy-paste error), but at the same time I see space for at least two-factor identification (e.g. model and revision). Thus API should allow (but not require) combining id and rev. The same remains relevant for abootimg as well. Thanks, Aleksandr Bulyshchenko On Wed, Dec 4, 2019 at 9:12 PM Sam Protsenko <semen.protsenko@linaro.org> wrote: > Hi, > > On Wed, Dec 4, 2019 at 7:33 PM Eugeniu Rosca <erosca@de.adit-jv.com> > wrote: > > > > Hello Sam, > > Please, see one more suggestion below. > > > > On Tue, Dec 03, 2019 at 08:29:10PM +0100, Eugeniu Rosca wrote: > > > Hi Sam, > > > Cc: Aleksandr, Roman > > > > > > As expressed in the attached e-mail, to minimize the headaches > extending > > > the argument list of "bootimg" in future, can we please agree on below? > > > > > > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: > > > > +U_BOOT_CMD( > > > > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, > > > > + "manipulate Android Boot Image", > > > > + "set_addr <addr>\n" > > > > + " - set the address in RAM where boot image is located\n" > > > > + " ($loadaddr is used by default)\n" > > > > + "bootimg ver <varname>\n" > > > > > > Can we make <varname> optional, with the background provided in [1]? > > > > > > > + " - get header version\n" > > > > + "bootimg get_dtbo <addr_var> [size_var]\n" > > > > > > How about converting <addr_var> to an optional argument too? > > > > > > > + " - get address and size (hex) of recovery DTBO area in the > image\n" > > > > + " <addr_var>: variable name to contain DTBO area address\n" > > > > + " [size_var]: variable name to contain DTBO area size\n" > > > > + "bootimg dtb_dump\n" > > > > + " - print info for all files in DTB area\n" > > > > + "bootimg dtb_load_addr <varname>\n" > > > > > > Same as above w.r.t. <varname>. > > > > > > > + " - get load address (hex) of DTB\n" > > > > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" > > > > How about "get_dte" or "get_dtbe" instead of "get_dtb_file" ? > > It's shorter and should be easier to remember (dt{b}e = DT{B} Entry). > > > > Sorry, I like get_dtb more. It's .dtb file in the end, and it's called > exactly "dtb" in boot.img struct. So this is a keeper :) > > > -- > > Best Regards, > > Eugeniu >
On Thu, Dec 05, 2019 at 04:17:38AM +0200, Aleksandr Bulyshchenko wrote: > Hello Sam, > I'd like to add my 5 cents regarding separating dtimg start|size into 3 > subcommands > > dtimg start index <num> <addr> [varname] > dtimg start id <num> <addr> [varname] > dtimg start rev <num> <addr> [varname] > > While I don't see real usecases for combining index with id or rev (if > someone applies metainformation to dtb entries for meaningful lookup, > identical entries most probably mean copy-paste error), > but at the same time I see space for at least two-factor identification > (e.g. model and revision). > Thus API should allow (but not require) combining id and rev. > The same remains relevant for abootimg as well. [shameless plug] Agreed with Aleksandr. Users will want to provide <id> and <rev> (and possibly cust[0-4] in future) in one go/command launch.
Hi Aleksandr, On Thu, Dec 5, 2019 at 4:17 AM Aleksandr Bulyshchenko <a.bulyshchenko@globallogic.com> wrote: > > Hello Sam, > > I'd like to add my 5 cents regarding separating dtimg start|size into 3 subcommands >> >> dtimg start index <num> <addr> [varname] >> dtimg start id <num> <addr> [varname] >> dtimg start rev <num> <addr> [varname] > > While I don't see real usecases for combining index with id or rev (if someone applies metainformation to dtb entries for meaningful lookup, identical entries most probably mean copy-paste error), > but at the same time I see space for at least two-factor identification (e.g. model and revision). > Thus API should allow (but not require) combining id and rev. > Agreed on id+rev usage. Can we still try and keep the interface as simple as possible, e.g. like this: dtimg start index <num> <addr> [varname] dtimg start id <id_num> <rev_num> <custom_num> <addr> [varname] In case when user wants to use only "id" or only "rev", other bit should be specified as "-": dtimg start id 10 - - <addr> [varname] dtimg start id - 10 - <addr> [varname] It's similar to what is done in 'bootm' command: To boot that kernel without an initrd image,use a '-' for the second argument. This way we can keep away the 'index' usage, making two things possible: 1. Code will be easier (we can provide one function for 'index' case and one function for 'id/rev/custom' case) 2. Easier for us to split the work and avoid dependencies between our patch series If everyone agrees on usage I suggested above, we can go ahead and change it correspondingly for 'dtimg' and 'abootimg' patch series. > The same remains relevant for abootimg as well. > > Thanks, > Aleksandr Bulyshchenko > > On Wed, Dec 4, 2019 at 9:12 PM Sam Protsenko <semen.protsenko@linaro.org> wrote: >> >> Hi, >> >> On Wed, Dec 4, 2019 at 7:33 PM Eugeniu Rosca <erosca@de.adit-jv.com> wrote: >> > >> > Hello Sam, >> > Please, see one more suggestion below. >> > >> > On Tue, Dec 03, 2019 at 08:29:10PM +0100, Eugeniu Rosca wrote: >> > > Hi Sam, >> > > Cc: Aleksandr, Roman >> > > >> > > As expressed in the attached e-mail, to minimize the headaches extending >> > > the argument list of "bootimg" in future, can we please agree on below? >> > > >> > > On Wed, Oct 23, 2019 at 05:34:22PM +0300, Sam Protsenko wrote: >> > > > +U_BOOT_CMD( >> > > > + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, >> > > > + "manipulate Android Boot Image", >> > > > + "set_addr <addr>\n" >> > > > + " - set the address in RAM where boot image is located\n" >> > > > + " ($loadaddr is used by default)\n" >> > > > + "bootimg ver <varname>\n" >> > > >> > > Can we make <varname> optional, with the background provided in [1]? >> > > >> > > > + " - get header version\n" >> > > > + "bootimg get_dtbo <addr_var> [size_var]\n" >> > > >> > > How about converting <addr_var> to an optional argument too? >> > > >> > > > + " - get address and size (hex) of recovery DTBO area in the image\n" >> > > > + " <addr_var>: variable name to contain DTBO area address\n" >> > > > + " [size_var]: variable name to contain DTBO area size\n" >> > > > + "bootimg dtb_dump\n" >> > > > + " - print info for all files in DTB area\n" >> > > > + "bootimg dtb_load_addr <varname>\n" >> > > >> > > Same as above w.r.t. <varname>. >> > > >> > > > + " - get load address (hex) of DTB\n" >> > > > + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" >> > >> > How about "get_dte" or "get_dtbe" instead of "get_dtb_file" ? >> > It's shorter and should be easier to remember (dt{b}e = DT{B} Entry). >> > >> >> Sorry, I like get_dtb more. It's .dtb file in the end, and it's called >> exactly "dtb" in boot.img struct. So this is a keeper :) >> >> > -- >> > Best Regards, >> > Eugeniu
diff --git a/cmd/Kconfig b/cmd/Kconfig index 07060c63a7..d89a91cde4 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -356,6 +356,14 @@ config CMD_DTIMG files should be merged in one dtb further, which needs to be passed to the kernel, as part of a boot process. +config CMD_BOOTIMG + bool "bootimg" + depends on ANDROID_BOOT_IMAGE + help + Android Boot Image manipulation commands. Allows one to extract + images contained in boot.img, like kernel, ramdisk, dtb, etc, and + obtain corresponding meta-information from boot.img. + config CMD_ELF bool "bootelf, bootvx" default y diff --git a/cmd/Makefile b/cmd/Makefile index ac843b4b16..bf15e38f41 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -48,6 +48,7 @@ ifdef CONFIG_POST obj-$(CONFIG_CMD_DIAG) += diag.o endif obj-$(CONFIG_CMD_DTIMG) += dtimg.o +obj-$(CONFIG_CMD_BOOTIMG) += bootimg.o obj-$(CONFIG_CMD_ECHO) += echo.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o diff --git a/cmd/bootimg.c b/cmd/bootimg.c new file mode 100644 index 0000000000..a26a74f124 --- /dev/null +++ b/cmd/bootimg.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 Linaro Ltd. + * Sam Protsenko <semen.protsenko@linaro.org> + */ + +#include <android_image.h> +#include <common.h> +#include <mapmem.h> + +#define bootimg_addr() (_bootimg_addr == -1 ? load_addr : _bootimg_addr) + +/* Please use bootimg_addr() macro to obtain the boot image address */ +static ulong _bootimg_addr = -1; + +static int do_bootimg_set_addr(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + char *endp; + ulong img_addr; + + if (argc != 2) + return CMD_RET_USAGE; + + img_addr = simple_strtoul(argv[1], &endp, 16); + if (*endp != '\0') { + printf("Error: Wrong image address\n"); + return CMD_RET_FAILURE; + } + + _bootimg_addr = img_addr; + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_ver(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + char buf[65]; + int res = CMD_RET_SUCCESS; + + if (argc != 2) + return CMD_RET_USAGE; + + hdr = map_sysmem(bootimg_addr(), sizeof(*hdr)); + if (android_image_check_header(hdr)) { + printf("Error: Boot Image header is incorrect\n"); + res = CMD_RET_FAILURE; + goto exit; + } + + snprintf(buf, sizeof(buf), "%u", hdr->header_version); + env_set(argv[1], buf); + +exit: + unmap_sysmem(hdr); + return res; +} + +static int do_bootimg_get_dtbo(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + char buf[65]; + ulong addr; + u32 size; + + if (argc < 2 || argc > 3) + return CMD_RET_USAGE; + + if (!android_image_get_dtbo(bootimg_addr(), &addr, &size)) + return CMD_RET_FAILURE; + + snprintf(buf, sizeof(buf), "%lx", addr); + env_set(argv[1], buf); + + if (argc == 3) { + snprintf(buf, sizeof(buf), "%x", size); + env_set(argv[2], buf); + } + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_dtb_dump(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc != 1) + return CMD_RET_USAGE; + + if (android_image_print_dtb_contents(bootimg_addr())) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static int do_bootimg_dtb_load_addr(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const struct andr_img_hdr *hdr; + char buf[65]; + int res = CMD_RET_SUCCESS; + + if (argc != 2) + return CMD_RET_USAGE; + + hdr = map_sysmem(bootimg_addr(), sizeof(*hdr)); + if (android_image_check_header(hdr)) { + printf("Error: Boot Image header is incorrect\n"); + res = CMD_RET_FAILURE; + goto exit; + } + + if (hdr->header_version < 2) { + printf("Error: header_version must be >= 2 for this\n"); + res = CMD_RET_FAILURE; + goto exit; + } + + snprintf(buf, sizeof(buf), "%lx", (ulong)hdr->dtb_addr); + env_set(argv[1], buf); + +exit: + unmap_sysmem(hdr); + return res; +} + +static int do_bootimg_get_dtb_file(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + char *endp; + char buf[65]; + u32 index; + ulong addr; + u32 size; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + index = simple_strtoul(argv[1], &endp, 0); + if (*endp != '\0') { + printf("Error: Wrong index\n"); + return CMD_RET_FAILURE; + } + + if (!android_image_get_dtb_by_index(bootimg_addr(), index, &addr, + &size)) + return CMD_RET_FAILURE; + + snprintf(buf, sizeof(buf), "%lx", addr); + env_set(argv[2], buf); + + if (argc == 4) { + snprintf(buf, sizeof(buf), "%x", size); + env_set(argv[3], buf); + } + + return CMD_RET_SUCCESS; +} + +static cmd_tbl_t cmd_bootimg_sub[] = { + U_BOOT_CMD_MKENT(set_addr, 2, 1, do_bootimg_set_addr, "", ""), + U_BOOT_CMD_MKENT(ver, 2, 1, do_bootimg_ver, "", ""), + U_BOOT_CMD_MKENT(get_dtbo, 3, 1, do_bootimg_get_dtbo, "", ""), + U_BOOT_CMD_MKENT(dtb_dump, 1, 1, do_bootimg_dtb_dump, "", ""), + U_BOOT_CMD_MKENT(dtb_load_addr, 2, 1, do_bootimg_dtb_load_addr, "", ""), + U_BOOT_CMD_MKENT(get_dtb_file, 4, 1, do_bootimg_get_dtb_file, "", ""), +}; + +static int do_bootimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *cp; + + cp = find_cmd_tbl(argv[1], cmd_bootimg_sub, + ARRAY_SIZE(cmd_bootimg_sub)); + + /* Strip off leading 'bootimg' command argument */ + argc--; + argv++; + + if (!cp || argc > cp->maxargs) + return CMD_RET_USAGE; + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) + return CMD_RET_SUCCESS; + + return cp->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + bootimg, CONFIG_SYS_MAXARGS, 0, do_bootimg, + "manipulate Android Boot Image", + "set_addr <addr>\n" + " - set the address in RAM where boot image is located\n" + " ($loadaddr is used by default)\n" + "bootimg ver <varname>\n" + " - get header version\n" + "bootimg get_dtbo <addr_var> [size_var]\n" + " - get address and size (hex) of recovery DTBO area in the image\n" + " <addr_var>: variable name to contain DTBO area address\n" + " [size_var]: variable name to contain DTBO area size\n" + "bootimg dtb_dump\n" + " - print info for all files in DTB area\n" + "bootimg dtb_load_addr <varname>\n" + " - get load address (hex) of DTB\n" + "bootimg get_dtb_file <index> <addr_var> [size_var]\n" + " - get address and size (hex) of DTB file in the image\n" + " <index>: index of desired DTB file in DTB area\n" + " <addr_var>: variable name to contain DTB file address\n" + " [size_var]: variable name to contain DTB file size\n" +);
This command can be used to extract fields and image payloads from Android Boot Image. It can be used for example to implement boot flow where dtb is taken from boot.img (as v2 incorporated dtb inside of boot.img). Using this command, one can obtain needed dtb file from boot.img in scripting manner, and then apply needed dtbo's (from "dtbo" partition) on top of that, providing then the resulting image to bootm command in order to boot the Android. Also right now this command has the sub-command to get an address and size of recovery dtbo from recovery image. It can be further parsed using 'dtimg' command and merged into dtb file (for non-A/B devices only, see [1,2] for details). [1] https://source.android.com/devices/bootloader/boot-image-header [2] https://source.android.com/devices/architecture/dto/partitions Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> --- Changes in v2: - add "set_addr" sub-command - provide mem mappings for sandbox - rebase on top of master cmd/Kconfig | 8 ++ cmd/Makefile | 1 + cmd/bootimg.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 cmd/bootimg.c