[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v7] uboot-script-gen: Dynamically compute addr and size when loading binaries
On Sat, 26 Apr 2025, dmkhn@xxxxxxxxx wrote: > On Fri, Apr 25, 2025 at 04:35:06PM -0700, Stefano Stabellini wrote: > > From: Andrei Cherechesu <andrei.cherechesu@xxxxxxxxxxx> > > > > Normally, the Imagebuilder would precompute the sizes of the loaded > > binaries and addresses where they are loaded before generating the > > script, and the sizes and addresses that needed to be provided to > > Xen via /chosen would be hardcoded in the boot script. > > > > Added an option via "-s" parameter to avoid hardcoding any > > address in the boot script, and dynamically compute the > > loading addresses for binaries. The first loading address is based > > on the MEMORY_START parameter and after loading each binary, > > the loading address and the size of the binary are stored in > > variables with corresponding names. Then, the loading address > > for the next binary is computed and aligned to 0x200000. > > > > If the "-s" parameter is not used, the normal flow is executed, > > where the loading addresses and sizes for each binaries are > > precomputed and hardcoded inside the script, but the loading > > addresses and sizes for each binary are now also stored for eventual > > later use. > > > > Reserved memory regions are left TBD in the -s case. > > > > Link: > > https://lists.xenproject.org/archives/html/xen-devel/2022-09/msg01862.html > > Signed-off-by: Andrei Cherechesu <andrei.cherechesu@xxxxxxx> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx> > > Reviewed-by: Denis Mukhin <dmukhin@xxxxxxxx> Thanks Denis! I'll keep your R-b even if I made a couple of changes to address Andrei's comment > > --- > > Changes in v7: > > - use $() > > - better description and alphabetical order > > - use heredoc > > > > Changes in v6: > > - make initial ${memaddr} setting depending on CALC > > > > This patch adds quite a bit of complexity which is the reason why I > > didn't originally commit it. Now that we are enabling ImageBuilder in > > Yocto, it turns out this patch is required because Yocto invokes > > ImageBuilder before all the binaries are ready and available. > > > > Andrei, sorry for taking so long to realize why it is essential, but we > > are getting there now. > > > > The changes I made to the original patch are purely to make it simpler > > to maintain. > > --- > > > > diff --git a/README.md b/README.md > > index f8039ec..28c9e6b 100644 > > --- a/README.md > > +++ b/README.md > > @@ -356,6 +356,8 @@ Where:\ > > can only be used in combination with the -k option. This adds the > > public key into the dtb. Then one can add this dtb back into the > > u-boot bin or elf.\ > > +-s addresses and sizes are calculated dynamically from U-Boot, hence > > + binaries don't need to be available at the time of invocation.\ > > > > ### Signed FIT images > > > > diff --git a/scripts/uboot-script-gen b/scripts/uboot-script-gen > > index 638154a..73d9600 100755 > > --- a/scripts/uboot-script-gen > > +++ b/scripts/uboot-script-gen > > @@ -1,8 +1,11 @@ > > #!/bin/bash > > > > offset=$((2*1024*1024)) > > +PADDING_MASK=$(printf "0x%X\n" $(($offset - 1))) > > +PADDING_MASK_INV=$(printf "0x%X\n" $((~$PADDING_MASK))) > > filesize=0 > > prog_req=(mkimage file fdtput mktemp awk od) > > +CALC="" > > > > function cleanup_and_return_err() > > { > > @@ -100,17 +103,40 @@ function dt_set() > > fi > > } > > > > +function dt_set_calc() > > +{ > > + local path=$1 > > + local var=$2 > > + local name_var=$3 > > + > > + local addr_var="$name_var"_addr > > + local size_var="$name_var"_size > > + > > + cat >> $UBOOT_SOURCE <<- EOF > > + setexpr addr_hi \${$addr_var} / 0x100000000 > > + setexpr addr_lo \${$addr_var} \& 0xFFFFFFFF > > + setexpr size_hi \${$size_var} / 0x100000000 > > + setexpr size_lo \${$size_var} \& 0xFFFFFFFF > > + fdt set $path $var <0x\${addr_hi} 0x\${addr_lo} 0x\${size_hi} > > 0x\${size_lo}> > > + EOF > > +} > > + > > function add_device_tree_kernel() > > { > > local path=$1 > > - local addr=$2 > > - local size=$3 > > - local bootargs=$4 > > + local name=$2 > > + local addr=$3 > > + local size=$4 > > + local bootargs=$5 > > local node_name="module@${addr#0x}" > > > > dt_mknode "$path" "$node_name" > > dt_set "$path/$node_name" "compatible" "str_a" "multiboot,kernel > > multiboot,module" > > - dt_set "$path/$node_name" "reg" "hex" "$(split_addr_size $addr $size)" > > + if test "$CALC"; then > > + dt_set_calc "$path/$node_name" "reg" $name > > + else > > + dt_set "$path/$node_name" "reg" "hex" "$(split_addr_size $addr > > $size)" > > + fi > > dt_set "$path/$node_name" "bootargs" "str" "$bootargs" > > } > > > > @@ -118,26 +144,36 @@ function add_device_tree_kernel() > > function add_device_tree_ramdisk() > > { > > local path=$1 > > - local addr=$2 > > - local size=$3 > > + local name=$2 > > + local addr=$3 > > + local size=$4 > > local node_name="module@${addr#0x}" > > > > dt_mknode "$path" "$node_name" > > dt_set "$path/$node_name" "compatible" "str_a" "multiboot,ramdisk > > multiboot,module" > > - dt_set "$path/$node_name" "reg" "hex" "$(split_addr_size $addr $size)" > > + if test "$CALC"; then > > + dt_set_calc "$path/$node_name" "reg" $name > > + else > > + dt_set "$path/$node_name" "reg" "hex" "$(split_addr_size $addr > > $size)" > > + fi > > } > > > > > > function add_device_tree_passthrough() > > { > > local path=$1 > > - local addr=$2 > > - local size=$3 > > + local name=$2 > > + local addr=$3 > > + local size=$4 > > local node_name="module@${addr#0x}" > > > > dt_mknode "$path" "$node_name" > > dt_set "$path/$node_name" "compatible" "str_a" "multiboot,device-tree > > multiboot,module" > > - dt_set "$path/$node_name" "reg" "hex" "$(split_addr_size $addr $size)" > > + if test "$CALC"; then > > + dt_set_calc "$path/$node_name" "reg" $name > > + else > > + dt_set "$path/$node_name" "reg" "hex" "$(split_addr_size $addr > > $size)" > > + fi > > } > > > > function add_device_tree_mem() > > @@ -358,7 +394,11 @@ function xen_device_tree_editing() > > > > dt_mknode "/chosen" "$node_name" > > dt_set "/chosen/$node_name" "compatible" "str_a" "xen,xsm-policy > > xen,multiboot-module multiboot,module" > > - dt_set "/chosen/$node_name" "reg" "hex" "$(split_addr_size > > $xen_policy_addr $xen_policy_size)" > > + if test "$CALC"; then > > + dt_set_calc "/chosen/$node_name" "reg" "xen_policy" > > + else > > + dt_set "/chosen/$node_name" "reg" "hex" "$(split_addr_size > > $xen_policy_addr $xen_policy_size)" > > + fi > > fi > > > > if test "$DOM0_KERNEL" > > @@ -367,7 +407,11 @@ function xen_device_tree_editing() > > > > dt_mknode "/chosen" "$node_name" > > dt_set "/chosen/$node_name" "compatible" "str_a" "xen,linux-zimage > > xen,multiboot-module multiboot,module" > > - dt_set "/chosen/$node_name" "reg" "hex" "$(split_addr_size > > $dom0_kernel_addr $dom0_kernel_size)" > > + if test "$CALC"; then > > + dt_set_calc "/chosen/$node_name" "reg" "dom0_linux" > > + else > > + dt_set "/chosen/$node_name" "reg" "hex" "$(split_addr_size > > $dom0_kernel_addr $dom0_kernel_size)" > > + fi > > dt_set "/chosen" "xen,dom0-bootargs" "str" "$DOM0_CMD" > > fi > > > > @@ -377,7 +421,11 @@ function xen_device_tree_editing() > > > > dt_mknode "/chosen" "$node_name" > > dt_set "/chosen/$node_name" "compatible" "str_a" "xen,linux-initrd > > xen,multiboot-module multiboot,module" > > - dt_set "/chosen/$node_name" "reg" "hex" "$(split_addr_size > > $ramdisk_addr $ramdisk_size)" > > + if test "$CALC"; then > > + dt_set_calc "/chosen/$node_name" "reg" "dom0_ramdisk" > > + else > > + dt_set "/chosen/$node_name" "reg" "hex" "$(split_addr_size > > $ramdisk_addr $ramdisk_size)" > > + fi > > fi > > > > i=0 > > @@ -464,14 +512,14 @@ function xen_device_tree_editing() > > > > xen_dt_domu_add_vcpu_nodes "/chosen/domU$i" $i ${DOMU_VCPUS[$i]} > > > > - add_device_tree_kernel "/chosen/domU$i" ${domU_kernel_addr[$i]} > > ${domU_kernel_size[$i]} "${DOMU_CMD[$i]}" > > + add_device_tree_kernel "/chosen/domU$i" "domU${i}_kernel" > > ${domU_kernel_addr[$i]} ${domU_kernel_size[$i]} "${DOMU_CMD[$i]}" > > if test "${domU_ramdisk_addr[$i]}" > > then > > - add_device_tree_ramdisk "/chosen/domU$i" > > ${domU_ramdisk_addr[$i]} ${domU_ramdisk_size[$i]} > > + add_device_tree_ramdisk "/chosen/domU$i" "domU${i}_ramdisk" > > ${domU_ramdisk_addr[$i]} ${domU_ramdisk_size[$i]} > > fi > > if test "${domU_passthrough_dtb_addr[$i]}" > > then > > - add_device_tree_passthrough "/chosen/domU$i" > > ${domU_passthrough_dtb_addr[$i]} ${domU_passthrough_dtb_size[$i]} > > + add_device_tree_passthrough "/chosen/domU$i" "domU${i}_fdt" > > ${domU_passthrough_dtb_addr[$i]} ${domU_passthrough_dtb_size[$i]} > > fi > > i=$(( $i + 1 )) > > done > > @@ -504,7 +552,11 @@ function device_tree_editing() > > > > if test $UBOOT_SOURCE > > then > > - echo "fdt addr $device_tree_addr" >> $UBOOT_SOURCE > > + if test "$CALC"; then > > + echo "fdt addr \${host_fdt_addr}" >> $UBOOT_SOURCE > > + else > > + echo "fdt addr $device_tree_addr" >> $UBOOT_SOURCE > > + fi > > echo "fdt resize 1024" >> $UBOOT_SOURCE > > > > if test $NUM_DT_OVERLAY && test $NUM_DT_OVERLAY -gt 0 > > @@ -512,7 +564,11 @@ function device_tree_editing() > > i=0 > > while test $i -lt $NUM_DT_OVERLAY > > do > > - echo "fdt apply ${dt_overlay_addr[$i]}" >> $UBOOT_SOURCE > > + if test "$CALC"; then > > + echo "fdt apply \${host_fdto${i}_addr}" >> > > $UBOOT_SOURCE > > + else > > + echo "fdt apply ${dt_overlay_addr[$i]}" >> > > $UBOOT_SOURCE > > + fi > > i=$(( $i + 1 )) > > done > > fi > > @@ -530,8 +586,12 @@ function fill_reserved_spaces_from_dtb() > > { > > if [ ! -f $DEVICE_TREE ] > > then > > - echo "File $DEVICE_TREE doesn't exist, exiting"; > > - cleanup_and_return_err > > + if test "$CALC"; then > > + return > > + else > > + echo "File $DEVICE_TREE doesn't exist, exiting"; > > + cleanup_and_return_err > > + fi > > fi > > > > # Check if reserved-memory node exists > > @@ -613,7 +673,7 @@ function get_image_size() > > printf "%u" $effective_size > > } > > > > -function add_size() > > +function add_size_from_file() > > { > > local filename=$1 > > local size=`stat -L --printf="%s" $filename` > > @@ -645,6 +705,26 @@ function add_size() > > filesize=$size > > } > > > > +function add_size_calculate() > > +{ > > + local fit_scr_name=$1 > > + > > + cat >> $UBOOT_SOURCE <<- EOF > > + setenv "$fit_scr_name"_addr \${memaddr} > > + setenv "$fit_scr_name"_size \${filesize} > > + setexpr memaddr \${memaddr} \+ \${filesize} > > + setexpr memaddr \${memaddr} \+ $PADDING_MASK > > + setexpr memaddr \${memaddr} \& $PADDING_MASK_INV > > + EOF > > + > > + # TODO: missing ${RESERVED_MEM_SPACES[@]} check > > + > > + # The following are updated to avoid collisions in node names, but > > + # they are not actively used. > > + memaddr=$((memaddr + offset)) > > + filesize=$offset > > +} > > + > > function load_file() > > { > > local filename=$1 > > @@ -657,10 +737,16 @@ function load_file() > > if test "$FIT" > > then > > echo "imxtract \$fit_addr $fit_scr_name $memaddr" >> $UBOOT_SOURCE > > + add_size_from_file $filename > > else > > - echo "$LOAD_CMD $memaddr > > ${prepend_path:+$prepend_path/}$relative_path" >> $UBOOT_SOURCE > > + if test "$CALC"; then > > + echo "$LOAD_CMD \${memaddr} > > ${prepend_path:+$prepend_path/}$relative_path" >> $UBOOT_SOURCE > > + add_size_calculate $fit_scr_name > > + else > > + echo "$LOAD_CMD $memaddr > > ${prepend_path:+$prepend_path/}$relative_path" >> $UBOOT_SOURCE > > + add_size_from_file $filename > > + fi > > fi > > - add_size $filename > > } > > > > function check_file_type() > > @@ -670,8 +756,13 @@ function check_file_type() > > > > if [ ! -f $filename ] > > then > > - echo "File $filename doesn't exist, exiting"; > > - cleanup_and_return_err > > + if test "$CALC" > > + then > > + return > > + else > > + echo "File $filename doesn't exist, exiting"; > > + cleanup_and_return_err > > + fi > > fi > > > > # if file doesn't know what it is, it outputs data, so include that > > @@ -705,8 +796,13 @@ function check_compressed_file_type() > > > > if [ ! -f $filename ] > > then > > - echo "File $filename doesn't exist, exiting"; > > - cleanup_and_return_err > > + if test "$CALC" > > + then > > + return > > + else > > + echo "File $filename doesn't exist, exiting"; > > + cleanup_and_return_err > > + fi > > fi > > > > file_type=$( file -L $filename ) > > @@ -872,6 +968,12 @@ function linux_config() > > generate_uboot_images() > > { > > local arch=$(file -L $XEN | grep -E 'ARM64|Aarch64') > > + > > + if test "$CALC" > > + then > > + echo "bootm is not compatible with -s" > > + cleanup_and_return_err > > + fi > > > > if test "$arch" > > then > > @@ -997,7 +1099,11 @@ bitstream_load_and_config() > > if test "$UBOOT_SOURCE" > > then > > # we assume the FPGA device is 0 here > > - echo "fpga load 0 $bitstream_addr $bitstream_size" >> > > "$UBOOT_SOURCE" > > + if test "$CALC"; then > > + echo "fpga load 0 \${fpga_bitstream_addr} > > \${fpga_bitstream_size}" >> "$UBOOT_SOURCE" > > + else > > + echo "fpga load 0 $bitstream_addr $bitstream_size" >> > > "$UBOOT_SOURCE" > > + fi > > fi > > fi > > } > > @@ -1271,7 +1377,7 @@ function print_help > > { > > script=`basename "$0"` > > echo "usage:" > > - echo " $script -c CONFIG_FILE -d DIRECTORY [-t LOAD_CMD] [-o FILE] [-k > > KEY_DIR/HINT [-u U-BOOT_DTB]] [-e] [-f] [-p PREPEND_PATH]" > > + echo " $script -c CONFIG_FILE -d DIRECTORY [-t LOAD_CMD] [-o FILE] [-k > > KEY_DIR/HINT [-u U-BOOT_DTB]] [-e] [-f] [-p PREPEND_PATH] [-s]" > > echo " $script -h" > > echo "where:" > > echo " CONFIG_FILE - configuration file" > > @@ -1289,13 +1395,14 @@ function print_help > > echo " -f - enable generating a FIT image" > > echo " PREPEND_PATH - path to be appended before file names to match > > deploy location within rootfs" > > echo " -h - prints out the help message and exits " > > + echo " -s - let U-Boot calculate binary images load addresses/sizes > > dynamically" > > echo "Defaults:" > > echo " CONFIG_FILE=$cfg_file, UBOOT_TYPE=\"LOAD_CMD\" env var, > > DIRECTORY=$uboot_dir" > > echo "Example:" > > echo " $script -c ../config -d ./build42 -t \"scsi load 1:1\"" > > } > > > > -while getopts ":c:t:d:ho:k:u:fp:" opt; do > > +while getopts ":c:t:d:ho:k:u:fp:s" opt; do > > case ${opt} in > > t ) > > case $OPTARG in > > @@ -1340,6 +1447,9 @@ while getopts ":c:t:d:ho:k:u:fp:" opt; do > > p ) > > prepend_path="$OPTARG" > > ;; > > + s ) > > + CALC=y > > + ;; > > h ) > > print_help > > exit 0 > > @@ -1533,6 +1643,10 @@ uboot_addr=$memaddr > > # 2MB are enough for a uboot script > > memaddr=$(( $memaddr + $offset )) > > memaddr=`printf "0x%X\n" $memaddr` > > +if test "$CALC" > > +then > > + echo "setenv memaddr $memaddr" >> $UBOOT_SOURCE > > +fi > > > > fill_reserved_spaces_from_dtb > > > > @@ -1583,7 +1697,11 @@ fi > > > > if [ "$BOOT_CMD" != "none" ] > > then > > - echo "$BOOT_CMD $kernel_addr $([ "$BOOT_CMD" = "bootefi" ] || echo > > '-') $device_tree_addr" >> $UBOOT_SOURCE > > + if test "$CALC"; then > > + echo "$BOOT_CMD \${host_kernel_addr} $([ "$BOOT_CMD" = "bootefi" ] > > || echo '-') \${host_fdt_addr}" >> $UBOOT_SOURCE > > + else > > + echo "$BOOT_CMD $kernel_addr $([ "$BOOT_CMD" = "bootefi" ] || echo > > '-') $device_tree_addr" >> $UBOOT_SOURCE > > + fi > > else > > # skip boot command but store load addresses to be used later > > echo "setenv host_kernel_addr $kernel_addr" >> $UBOOT_SOURCE >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |