Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ass:labs-2025:03:tasks:01 [2025/08/06 11:56]
florin.stancu created
ass:labs-2025:03:tasks:01 [2025/08/06 12:56] (current)
florin.stancu
Line 1: Line 1:
-==== 01. Simplifying ​booting our Linux ====+==== 01. Automatically ​booting our Linux ====
  
 You are probably be tired of using u-boot CLI to load the Linux FIT uImage into RAM and booting it manually. You are probably be tired of using u-boot CLI to load the Linux FIT uImage into RAM and booting it manually.
 Surely, there must be something to be done to automate this... and you're right! Let's learn to do this! Surely, there must be something to be done to automate this... and you're right! Let's learn to do this!
  
-TODO+First, boot your board into ''​u-boot''​ prompt. Enter ''​env print''​... ​
  
 +<spoiler env print output...>​
 +<code bash>
 +arch=arm
 +auth_os=auth_cntr ${cntr_addr}
 +baudrate=115200
 +board=imx93_frdm
 +board_name=imx93_frdm
 +boot_a_script=load ${devtype} ${devnum}:​${distro_bootpart} ${scriptaddr} ${prefix}${script};​ source ${scriptaddr}
 +boot_efi_binary=load ${devtype} ${devnum}:​${distro_bootpart} ${kernel_addr_r} efi/​boot/​bootaa64.efi;​ if fdt addr -q ${fdt_addr_r};​ then bootefi ${kernel_addr_r} ${fdt_addr_r};​else bootefi ${kernel_addr_r} ${fdtcontroladdr};​fi
 +boot_efi_bootmgr=if fdt addr -q ${fdt_addr_r};​ then bootefi bootmgr ${fdt_addr_r};​else bootefi bootmgr;fi
 +boot_extlinux=sysboot ${devtype} ${devnum}:​${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
 +boot_fit=no
 +boot_net_usb_start=usb start
 +boot_os=booti ${loadaddr} - ${fdt_addr_r};​
 +boot_prefixes=/​ /boot/
 +boot_script_dhcp=boot.scr.uimg
 +boot_scripts=boot.scr.uimg boot.scr
 +boot_syslinux_conf=extlinux/​extlinux.conf
 +boot_targets=mmc0 mmc1 usb0
 +bootargs=console=ttyLP0,​115200 earlycon,​115200 rdinit=/​linuxrc clk_ignore_unused
 +bootcmd=run sr_ir_v2_cmd;​run distro_bootcmd;​run bsp_bootcmd
 +bootcmd_mfg=run mfgtool_args;​if iminfo ${initrd_addr};​ then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr};​ else booti ${loadaddr} ${initrd_addr} ${fdt_addr};​ fi; else echo "Run fastboot ..."; fastboot auto; fi;
 +bootcmd_mmc0=devnum=0;​ run mmc_boot
 +bootcmd_mmc1=devnum=1;​ run mmc_boot
 +bootcmd_usb0=devnum=0;​ run usb_boot
 +bootdelay=2
 +bootm_size=0x10000000
 +bootscript=echo Running bootscript from mmc ...; source
 +bsp_bootcmd=echo Running BSP bootcmd ...; mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript;​ then run bootscript; else if test ${sec_boot} = yes; then if run loadcntr; then run mmcboot; else run netboot; fi; else if run loadimage; then run mmcboot; else run netboot; fi; fi; fi; fi;
 +cntr_addr=0x98000000
 +cntr_file=os_cntr_signed.bin
 +console=ttyLP0,​115200 earlycon
 +cpu=armv8
 +distro_bootcmd=for target in ${boot_targets};​ do run bootcmd_${target};​ done
 +efi_dtb_prefixes=/​ /dtb/ /​dtb/​current/​
 +emmc_dev=0
 +ethprime=eth1
 +fdt_addr=0x83000000
 +fdt_addr_r=0x83000000
 +fdt_high=0xffffffffffffffff
 +fdtfile=imx93-11x11-frdm.dtb
 +image=Image
 +initrd_addr=0x83800000
 +initrd_high=0xffffffffffffffff
 +jh_mmcboot=setenv fdtfile ${jh_root_dtb};​ setenv jh_clk clk_ignore_unused mem=1248MB kvm-arm.mode=nvhe;​ if run loadimage; then run mmcboot;​else run jh_netboot; fi;
 +jh_netboot=setenv fdtfile ${jh_root_dtb};​ setenv jh_clk clk_ignore_unused mem=1248MB kvm-arm.mode=nvhe;​ run netboot;
 +jh_root_dtb=imx93-11x11-frdm-root.dtb
 +kboot=booti
 +kernel_addr_r=0x80400000
 +load_efi_dtb=load ${devtype} ${devnum}:​${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
 +loadaddr=0x80400000
 +loadbootscript=fatload mmc ${mmcdev}:​${mmcpart} ${loadaddr} ${script};
 +loadcntr=fatload mmc ${mmcdev}:​${mmcpart} ${cntr_addr} ${cntr_file}
 +loadfdt=fatload mmc ${mmcdev}:​${mmcpart} ${fdt_addr_r} ${fdtfile}
 +loadimage=fatload mmc ${mmcdev}:​${mmcpart} ${loadaddr} ${image}
 +mfgtool_args=setenv bootargs console=${console},​${baudrate} rdinit=/​linuxrc clk_ignore_unused
 +mmc_boot=if mmc dev ${devnum}; then devtype=mmc;​ run scan_dev_for_boot_part;​ fi
 +mmcargs=setenv bootargs ${jh_clk} ${mcore_clk} console=${console} root=${mmcroot}
 +mmcautodetect=yes
 +mmcboot=echo Booting from mmc ...; run mmcargs; if test ${sec_boot} = yes; then if run auth_os; then run boot_os; else echo ERR: failed to authenticate;​ fi; else if test ${boot_fit} = yes || test ${boot_fit} = try; then bootm ${loadaddr};​ else if run loadfdt; then run boot_os; else echo WARN: Cannot load the DT; fi; fi;fi;
 +mmcdev=0
 +mmcpart=1
 +mmcroot=/​dev/​mmcblk1p2 rootwait rw
 +netargs=setenv bootargs ${jh_clk} ${mcore_clk} console=${console} root=/​dev/​nfs ip=dhcp nfsroot=${serverip}:​${nfsroot},​v3,​tcp
 +netboot=echo Booting from net ...; run netargs; ​ if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; if test ${sec_boot} = yes; then ${get_cmd} ${cntr_addr} ${cntr_file};​ if run auth_os; then run boot_os; else echo ERR: failed to authenticate;​ fi; else ${get_cmd} ${loadaddr} ${image}; if test ${boot_fit} = yes || test ${boot_fit} = try; then bootm ${loadaddr};​ else if ${get_cmd} ${fdt_addr_r} ${fdtfile}; then run boot_os; else echo WARN: Cannot load the DT; fi; fi;fi;
 +nodes=/​usbg1 /usbg2 /wdt-reboot /​rm67199_panel /dsi-host /​display-subsystem /​soc@0/​bus@44000000/​dma-controller@44000000 /​soc@0/​bus@44000000/​sai@443b0000 /​soc@0/​bus@44000000/​mqs1 /​soc@0/​bus@44000000/​bbnsm@44440000 /​soc@0/​bus@44000000/​system-controller@44460000 /​soc@0/​bus@44000000/​tmu@44482000 /​soc@0/​bus@44000000/​micfil@44520000 /​soc@0/​bus@42000000/​dma-controller@42000000 /​soc@0/​bus@44000000/​i3c-master@44330000 /​soc@0/​bus@42000000/​i3c-master@42520000 /​soc@0/​bus@42000000/​sai@42650000 /​soc@0/​bus@42000000/​sai@42660000 /​soc@0/​bus@42000000/​mqs2 /​soc@0/​bus@42000000/​xcvr@42680000 /​soc@0/​bus@42000000/​flexio@425c0000 /​soc@0/​bus@42800000/​epxp@4ae20000 /​soc@0/​bus@42800000/​camera /​soc@0/​efuse@47510000 /​soc@0/​system-controller@4ac10000 /​soc@0/​ldb@4ac10020 /​soc@0/​phy@4ac10024 /​soc@0/​ele-mu /​soc@0/​dsi@4ae10000 /​soc@0/​lcd-controller@4ae30000 /​soc@0/​blk-ctrl@4e010000 /​soc@0/​memory-controller@4e300000 /​soc@0/​bus@44000000/​i2c@44350000/​pmic@25 /imx93-lpm
 +prepare_mcore=setenv mcore_clk clk-imx93.mcore_booted;​
 +scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:​${distro_bootpart}...;​ for prefix in ${boot_prefixes};​ do run scan_dev_for_extlinux;​ run scan_dev_for_scripts;​ done;run scan_dev_for_efi;​
 +scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist};​ do if fstype ${devtype} ${devnum}:​${distro_bootpart} bootfstype; then part uuid ${devtype} ${devnum}:​${distro_bootpart} distro_bootpart_uuid ; run scan_dev_for_boot;​ fi; done; setenv devplist
 +scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in ${efi_dtb_prefixes};​ do if test -e ${devtype} ${devnum}:​${distro_bootpart} ${prefix}${efi_fdtfile};​ then run load_efi_dtb;​ fi;done;run boot_efi_bootmgr;​if test -e ${devtype} ${devnum}:​${distro_bootpart} efi/​boot/​bootaa64.efi;​ then echo Found EFI removable media binary efi/​boot/​bootaa64.efi;​ run boot_efi_binary;​ echo EFI LOAD FAILED: continuing...;​ fi; setenv efi_fdtfile
 +scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:​${distro_bootpart} ${prefix}${boot_syslinux_conf};​ then echo Found ${prefix}${boot_syslinux_conf};​ run boot_extlinux;​ echo EXTLINUX FAILED: continuing...;​ fi
 +scan_dev_for_scripts=for script in ${boot_scripts};​ do if test -e ${devtype} ${devnum}:​${distro_bootpart} ${prefix}${script};​ then echo Found U-Boot script ${prefix}${script};​ run boot_a_script;​ echo SCRIPT FAILED: continuing...;​ fi; done
 +scriptaddr=0x83500000
 +sd_dev=1
 +sec_boot=no
 +soc=imx9
 +splashimage=0x90000000
 +sr_ir_v2_cmd=cp.b ${fdtcontroladdr} ${fdt_addr_r} 0x10000;fdt addr ${fdt_addr_r};​fdt resize 0x400;fdt set /​soc@0/​bus@44000000/​i2c@44350000/​gpio@34 compatible adi,​adp5585;​for i in ${nodes}; do fdt rm ${i}; done
 +usb_boot=usb start; if usb dev ${devnum}; then devtype=usb;​ run scan_dev_for_boot_part;​ fi
 +vendor=freescale
 +
 +Environment size: 7010/16380 bytes
 +</​code>​
 +</​spoiler>​
 +
 +Notice various environment variables? There are various addresses, strings and even scripts! Can you figure out the **command** executed automatically at **boot**?
 +
 +We hope you're getting the same idea... what if we can modify this environment when compiling U-Boot such that it executes our own script?
 +
 +The KConfig item for doing this is called something like ''​DEFAULT_ENV'',​ try searching for it!
 +
 +It allows us to specify a custom file that contains our default environment...
 +
 +First, let's create this file, let's say ''​mydefault.env''​ inside the uboot source directory. Let's start from a minimal example:
 +
 +<code C>
 +/* default u-boot environment variables */
 +/* this file is passed through the C preprocessor (so we can use C-style macros!) */
 +/* someone in uboot source code re-defined `linux`... */
 +#undef linux
 +arch=arm
 +baseboard=autodetect
 +baudrate=115200
 +mmcdev=0
 +mmcpart=1
 +emmc_dev=0
 +console=ttyLP0
 +bootargs=console=ttyLP0,​115200 earlycon,​115200 rdinit=/​linuxrc clk_ignore_unused
 +# TODO: this is the command executed automatically when uboot starts...
 +bootcmd=echo Fastboot mode... press Ctrl-C to exit; fastboot auto
 +# This runs instead of bootcmd when booted using `uuu` via USB
 +bootcmd_mfg=run bootcmd
 +bootdelay=2
 +image=linux.itb
 +loadaddr=TODO
 +loadimage=TODO
 +linux=echo Booting Linux ...; run loadimage; bootm ${loadaddr};​
 +</​code>​
 +
 +Notice in the original environment that you may use the ''​run''​ command to run scripts from other defined variables, here's its reference:
 +<​code>​
 +run - run commands in an environment variable
 +</​code>​
 +
 +We can also use ''​${varname}''​ expressions to do variable expansion like in Linux shells!
 +
 +Enter your boot script inside the ''​bootcmd''​ var and let's proceed with overwriting the default environment.
 +
 +Recall the ''​DEFAULT_ENV''​ menuconfig item? Modify it to point to your ''​mydefault.env''​ (you can simply use a relative path). Note that you need to enable ''​USE_DEFAULT_ENV_FILE''​ checkbox first to let you supply your value!
 +
 +Afterwards, [re]compile u-boot, copy the u-boot ''​.bin''​ files again to the ''​imx-mkimage''​ directory and regenerate your ''​flash.bin''​.
 +
 +Test it by booting your new firmware using ''​uuu''​. ​
 +Try using ''​run linux''​ to run the ''​linux''​ script (if you used that), otherwise edit the ''​bootcmd''​ to do that automatically after the timeout!
 +Did it work? if not, you may need to repeat this process (this is where a script comes in handy!).
 +
 +Note that real devices have their uboot configuration proceed automatically with booting the OS if a physical button is NOT pressed (remember those old Android phones? you could stop this process by holding several volume keys together!). You can script this using GPIO, but it's out of scope for today.
  
ass/labs-2025/03/tasks/01.1754470586.txt.gz ยท Last modified: 2025/08/06 11:56 by florin.stancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0