Uboot 기본 Manual
https://www.denx.de/wiki/DULG/Manual
Uboot 의 전체 구성 과 설정방법
https://gitlab.denx.de/u-boot/u-boot/raw/HEAD/README
- Uboot 의 명령어
https://www.digi.com/resources/documentation/digidocs/PDFs/90000852.pdf
https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/u-boot-commands
https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/selected-annotated-u-boot-commands
- Uboot 환경값
1.1 Uboot 와 DTB 결합구성
- Uboot Image 의 구성
- Uboot의 DTS를 DTC를 이용하여 DTB 파일생성
- Uboot Build를 진행 Uboot 파일생성
- cat를 이용하여 상위 두개 파일을 하나로 결합
- mkimage를 이용하여 최종 Image 생성
DTB Image를 최종 합쳐서 Uboot Image로 만들어서 제공
https://rocketboards.org/foswiki/Documentation/A10GSRDV1511GeneratingUBootAndUBootDeviceTree |
- Uboot Build 된곳에서 기본적인확인
$ cat dts/.dt.dtb.cmd //Uboot DTB 파일 cmd_dts/dt.dtb := cat arch/arm/dts/imx6sx-sdb-emmc.dtb > dts/dt.dtb $ cat .u-boot-nodtb.bin.cmd // 일반 Uboot bin 생성 (objcopy) cmd_u-boot-nodtb.bin := arm-poky-linux-gnueabi-objcopy --gap-fill=0xff -j .text -j .secure_text -j .secure_data -j .rodata -j .hash -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn -j .binman_sym_table -j .text_rest -j .dtb.init.rodata -j .efi_runtime -j .efi_runtime_rel -O binary u-boot u-boot-nodtb.bin $ cat .u-boot-dtb.bin.cmd //Uboot 와 DTB 결합 cmd_u-boot-dtb.bin := cat u-boot-nodtb.bin dts/dt.dtb > u-boot-dtb.bin $ cat .u-boot.bin.cmd // Uboot 이름변경 및 최종 uboot cmd_u-boot.bin := cp u-boot-dtb.bin u-boot.bin $ cat .u-boot.imx.cmd // 최종 u-boot image cmd_u-boot.imx := ./tools/mkimage -n u-boot.cfgout -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx >u-boot.imx.log && cat u-boot.imx.log
Uboot 와 Kernel 는 각각 DTS 존재하며, 두 DTS가 동일하지만, Uboot의 DTB 와 Kernel DTB는 각각 별도로 사용이 되어지고 있다.
내 개인적인 생각으로는 1st Boot Loader가 Uboot에게 전달하고, Uboot가 다시 Kernel에게 전달하여 전부 공유할 것이라고 생각했는데,
설정을 바꿔서 어떻게 공유할 수 있는지를 알아봐야겠다.
(환경변수 fdtcontroladdr 와 fdt_addr를 동일하게 공유)
Device Tree Boot 기본 구조
아래링크의 그림부분 참조
https://ahyuo79.blogspot.com/2015/08/am437x-kernel-device-tree.html
TI-Sitara 의 Uboot / Kernel 의 Device Tree 관련부분 복습
https://ahyuo79.blogspot.com/2015/08/kernel-boot-kernel-device-tree.html
https://elinux.org/Device_Tree_Reference
Uboot 관련정보정리
https://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2014/uboot2014_kconfig.pdf
1.2 Uboot 와 DTB 관련소스분석
- Uboot fdt 확인
=> version
U-Boot 2019.04-4.19.35-1.1.0+g4d37753 (May 13 2020 - 07:43:31 +0000)
arm-poky-linux-gnueabi-gcc (GCC) 8.3.0
GNU ld (GNU Binutils) 2.32.0.20190204
=> bdinfo
arch_number = 0x00000000
boot_params = 0x80000100
DRAM bank = 0x00000000
-> start = 0x80000000
-> size = 0x40000000
baudrate = 115200 bps
TLB addr = 0xbfff0000
relocaddr = 0xbff45000
reloc off = 0x38745000
irq_sp = 0xbdf359f0
sp start = 0xbdf359e0
FB base = 0x00000000
Early malloc usage: fc / 400
fdt_blob = 0xbdf35a08 //uboot용 dtb (device tree blob) 주소
- Uboot Config 설정확인
$ vi .config // Uboot Config .... # # Partition Types # CONFIG_PARTITIONS=y # CONFIG_MAC_PARTITION is not set CONFIG_DOS_PARTITION=y # CONFIG_ISO_PARTITION is not set # CONFIG_AMIGA_PARTITION is not set CONFIG_EFI_PARTITION=y CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=128 CONFIG_EFI_PARTITION_ENTRIES_OFF=0 CONFIG_PARTITION_UUIDS=y # CONFIG_PARTITION_TYPE_GUID is not set CONFIG_SUPPORT_OF_CONTROL=y CONFIG_DTC=y # # Device Tree Control # ## 아래 설정으로 Uboot에서 Device Tree 사용 (fdt 사용가능) CONFIG_OF_CONTROL=y # CONFIG_OF_BOARD_FIXUP is not set # CONFIG_OF_LIVE is not set ## 아래 설정때문에 cat u-boot.bin u-boot.dtb >image.bin 결합 CONFIG_OF_SEPARATE=y # CONFIG_OF_EMBED is not set # CONFIG_OF_BOARD is not set # CONFIG_OF_PRIOR_STAGE is not set CONFIG_DEFAULT_DEVICE_TREE="imx6sx-sdb-emmc" # CONFIG_MULTI_DTB_FIT is not set CONFIG_MKIMAGE_DTC_PATH="dtc" # # Environment # # CONFIG_ENV_DEFAULT_NOWHERE is not set # CONFIG_ENV_IS_IN_EEPROM is not set # CONFIG_ENV_IS_IN_FAT is not set # CONFIG_ENV_IS_IN_EXT4 is not set # CONFIG_ENV_IS_IN_FLASH is not set CONFIG_ENV_IS_IN_MMC=y .....
- Uboot Linker Script
$ vi arch/arm/cpu/u-boot.lds
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
.end :
{
*(.__end)
}
_image_binary_end = .;
//binary 로 변경시 아래부분은 필요없음
/*
* Deprecated: this MMU section is used by pxa at present but
* should not be used by new boards/CPUs.
*/
. = ALIGN(4096);
.mmutable : {
*(.mmutable)
}
.....
$ vi u-boot.map // System.map 재확인
- Uboot Source 확인
$ vi common/board_r.c
......
static init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
...
#ifdef CONFIG_MMC
initr_mmc,
#endif
initr_env,
....
run_main_loop,
};
static int initr_env(void)
{
/* initialize environment */
if (should_load_env())
env_relocate();
else
set_default_env(NULL, 0);
// 매번 Booting 때마다 fdtcontroladdr 변수설정하기 때문에 User가 변경해도 소용없음
// Uboot에서 printenv로 확인가능하며 상위 CONFIG확인
#ifdef CONFIG_OF_CONTROL
env_set_hex("fdtcontroladdr",
(unsigned long)map_to_sysmem(gd->fdt_blob));
#endif
/* Initialize from environment */
load_addr = env_get_ulong("loadaddr", 16, load_addr);
return 0;
}
상위 설정대로 했을 경우 아래 bold 체가 실행
$ vi lib/fdtdec.c // Uboot의 dtb부분 처리를 이해가능 #if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) /* * For CONFIG_OF_SEPARATE, the board may optionally implement this to * provide and/or fixup the fdt. */ __weak void *board_fdt_blob_setup(void) { void *fdt_blob = NULL; #ifdef CONFIG_SPL_BUILD /* FDT is at end of BSS unless it is in a different memory region */ if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) fdt_blob = (ulong *)&_image_binary_end; else fdt_blob = (ulong *)&__bss_end; #else //CONFIG_OF_SEPARATE만 사용해서 uboot 끝에서 fdt를 가져옴 (Linker Script 참조) /* FDT is at end of image */ fdt_blob = (ulong *)&_end; #endif return fdt_blob; } #endif int fdtdec_setup(void) { #if CONFIG_IS_ENABLED(OF_CONTROL) // 현재설정 CONFIG_OF_CONTROL=y # if CONFIG_IS_ENABLED(MULTI_DTB_FIT) // 현재 미설정 # CONFIG_MULTI_DTB_FIT is not set void *fdt_blob; # endif # ifdef CONFIG_OF_EMBED // 현재 미설정 # CONFIG_OF_EMBED is not set /* Get a pointer to the FDT */ # ifdef CONFIG_SPL_BUILD // 현재 미설정 gd->fdt_blob = __dtb_dt_spl_begin; # else gd->fdt_blob = __dtb_dt_begin; # endif # elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) // 현재 이부분만 실행 /* Allow the board to override the fdt address. */ gd->fdt_blob = board_fdt_blob_setup(); // 상위함수 참고 CONFIG_OF_BOARD는 미설정 # elif defined(CONFIG_OF_HOSTFILE) if (sandbox_read_fdt_from_file()) { puts("Failed to read control FDT\n"); return -1; } # endif # ifndef CONFIG_SPL_BUILD // 현재 미설정 /* Allow the early environment to override the fdt address */ # if CONFIG_IS_ENABLED(OF_PRIOR_STAGE) // 현재 미설정 # CONFIG_OF_PRIOR_STAGE is not set gd->fdt_blob = (void *)prior_stage_fdt_address; # else // 상위에서 설정된 gd->fdt_blob 변수 fdtcontroladdr의 기본값으로 읽어옴 //bdinfo 와 printenv 확인가능 gd->fdt_blob = map_sysmem (env_get_ulong("fdtcontroladdr", 16, (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); # endif # endif # if CONFIG_IS_ENABLED(MULTI_DTB_FIT) // 현재미설정 # CONFIG_MULTI_DTB_FIT is not set /* * Try and uncompress the blob. * Unfortunately there is no way to know how big the input blob really * is. So let us set the maximum input size arbitrarily high. 16MB * ought to be more than enough for packed DTBs. */ if (uncompress_blob(gd->fdt_blob, 0x1000000, &fdt_blob) == 0) gd->fdt_blob = fdt_blob; /* * Check if blob is a FIT images containings DTBs. * If so, pick the most relevant */ fdt_blob = locate_dtb_in_fit(gd->fdt_blob); if (fdt_blob) { gd->multi_dtb_fit = gd->fdt_blob; gd->fdt_blob = fdt_blob; } # endif #endif return fdtdec_prepare_fdt(); }
이전의 Uboot 관련소스
https://lists.denx.de/pipermail/u-boot/2012-July/127516.html
https://gitlab.labs.nic.cz/turris/u-boot-turris/commit/eea63e05d0b7f54e7aa39725015483972c71cb3c
- Uboot의 DTB 설정확인
$ vi arch/arm/dts/Makefile .... dtb-$(CONFIG_MX6SX) += \ imx6sx-14x14-arm2.dtb \ imx6sx-17x17-arm2.dtb \ imx6sx-17x17-arm2-ecspi.dtb \ imx6sx-17x17-arm2-gpmi-weim.dtb \ imx6sx-19x19-arm2.dtb \ imx6sx-19x19-arm2-ecspi.dtb \ imx6sx-19x19-arm2-gpmi-weim.dtb \ imx6sx-sabreauto.dtb \ imx6sx-sdb.dtb \ imx6sx-sdb-emmc.dtb .....
1.3 Uboot 의 Flattened Device Tree (FDT)
Uboot는 DTB File을 Memory 에 Load하여 기본 확인가능하며, 이를 수정도 가능한 명령이 fdt 명령어이다.
uImage 에서 사용하게 될 dtb, 즉 kernel 용 dtb를 fdt 명령어를 이용하여 이를 확인해보자.
fdt 명령어 설명 (세부명령어 참조)
https://www.denx.de/wiki/view/DULG/UBootCmdFDT#Section_5.9.7.2.
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841676/U-Boot+Flattened+Device+Tree
- Uboot 에서 Kernel의 DTB 정보확인
=>pri ... mmcdev=3 mmcpart=1 fdt_addr=0x83000000 fdt_file=undefined.dtb loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file} ..... => setenv fdt_file imx6sx-sdb-emmc.dtb //DTB File 이름변경 => run loadfdt //상위 명령어 실행 (eMMC or SDcard의 Device의 Partition에서 File 읽기 49954 bytes read in 15 ms (3.2 MiB/s) => fdt addr ${fdt_addr} // FDT address 설정 => fdt list // DTB 파일을 볼수 있음 .... => fdt print // DTB 파일을 세부적으로 확인 ....
1.4 Uboot Env 분석 및 Hush Shell Script 확장
i.MX6의 경우 이전에 TI의 Uboot Env보다 좀 더 잘 구성이 되어있어 이부분을 간단정리
=> pri baudrate=115200 boot_fdt=try bootargs=console=ttymxc0,115200 rdinit=/linuxrc clk_ignore_unused bootcmd=run findfdt; mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot 0; fi; bootdelay=3 bootscript=echo Running bootscript from mmc ...; source // source command를 이용하여 boot.scr 실행 (default loadaddr) console=ttymxc0 emmc_ack=0 emmc_dev=3 eth1addr=c2:42:5a:9f:cd:09 ethact=ethernet@02188000 ethaddr=26:E1:2C:C4:C7:C6 ethprime=eth0 fastboot_bytes=adc00 fastboot_dev=mmc fdt_addr=0x83000000 // Kernel용 DTB 주소 (DRAM) fdt_file=undefined // Kernel용 DTB File 이름 fdt_high=0xffffffff // DTB MAX DRAM MAX fdtcontroladdr=bdf35a08 // Uboot 용 DTB 주소 (DRAM) filesize=adc00 findfdt=if test $fdt_file = undefined; then setenv fdt_file imx6sx-sdb-emmc.dtb; fi; image=zImage initrd_addr=0x86800000 initrd_high=0xffffffff ip_dyn=yes kboot=bootz loadaddr=0x80800000 loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script}; // eMMC에서 bootscript 읽어서 쉽게확장 loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file} // Kernel DTB File 읽기 loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image} // Kernel Image loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image} // qspi용 Kernel Image로 추정 loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file} // 보안 boot m4_qspi_cs=2 m4boot=sf probe 1:${m4_qspi_cs}; bootaux 0x78000000 m4image=m4_qspi.bin mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot} mmcautodetect=yes mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi; mmcdev=3 mmcpart=1 mmcroot=/dev/mmcblk3p2 rootwait rw netargs=setenv bootargs console=${console},${baudrate} 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; ${get_cmd} ${image}; if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;fi; panel=Hannstar-XGA script=boot.scr // FAT에서 boot.scr를 만들어 설정확장 sd_dev=3 serial#=121a59d4f21fe636 soc_type=imx6sx tee=no tee_addr=0x84000000 tee_file=uTee-6sxsdb update_m4_from_sd=if sf probe 1:${m4_qspi_cs}; then if run loadm4image; then setexpr fw_sz ${filesize} + 0xffff; setexpr fw_sz ${fw_sz} / 0x10000; setexpr fw_sz ${fw_sz} * 0x10000; sf erase 0x0 ${fw_sz}; sf write ${loadaddr} 0x0 ${filesize}; fi; fi
- i.MX6의 경우 HW bootmode에 따라 bootcmd의 실행변경
- bootcmd: 일반 boot Mode
- bootcmd_mfg: Download Mode (uuu라는 Program을 이용하여 fastboot이용)
- Download Mode (fastboot이용)
PC (USB Host) / i.MX6 (USB Device) 로 동작이되며, Uboot에서 fastboot를 이용하여 usb로 각 Data를 Download를 하고, eMMC or SDCard를 Write를 진행한다.
PC용 fastboot로는 연결해보지 못하고 오직 uuu라는 Program만 사용해봄
- bootcmd 일 경우
- loadbootscript (확장의 용이성)
TI-Sitara Uboot Script 및 Device Tree 설정
https://ahyuo79.blogspot.com/2015/08/uboot-script-device-tree.html
1.5 Uboot Env 값 고정값으로 설정
Env값들 중 변경 불가능 값들이 존재하여 관련된 소스분석 아래와 같이 board init 할때 마다 env_set 관련 function을 이용하여 직접 설정
$ cd uboot $ vi include/configs/mx6sxsabresd.h // 기본적인 uboot의 default env 값으로 saveenv 로 user가 각각 변경가능 #define CONFIG_EXTRA_ENV_SETTINGS \ //default env 값들 (saveenv 변경가능하지만, 변경불가능한 값 원인분석) ............... #define CONFIG_BOOTCOMMAND \ // bootcmd 값 (saveenv 변경가능) "run findfdt; " \ "mmc dev ${mmcdev}; if mmc rescan; then " \ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ "if run loadimage; then " \ "run mmcboot; " \ "else run netboot; " \ "fi; " \ "fi; " \ "else run netboot; fi" //mmcdev 와 mmcroot의 경우 saveenv로 변경을해도 board_init 할때마다 새로설정됨 $ vi board/freescale/common/mmc.c .... void board_late_mmc_env_init(void) { char cmd[32]; char mmcblk[32]; u32 dev_no = mmc_get_env_dev(); if (!check_mmc_autodetect()) return; //mmcdev 값 고정 , saveenv로 변경해도 기본값으로 설정 env_set_ulong("mmcdev", dev_no); //mmcroot 값 고정 , saveenv로 변경해도 기본값으로 설정 /* Set mmcblk env */ sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw", mmc_map_to_kernel_blk(dev_no)); env_set("mmcroot", mmcblk); sprintf(cmd, "mmc dev %d", dev_no); run_command(cmd, 0); }
2. Uboot 의 Command Script 관리
예전의 Uboot 보다 점점 많은 명령어를 지원해주고 있으며, fastboot를 비롯하여, 각종 filesystem도 마음대로 접근이 가능하며,
다양한 Hardware Interface도 지원을 해주고 있어 Hush shell 를 잘 이용하면 일반 Shell Script 못지않게 잘 사용할 수 있을 것 같다.
각종 사용되어지는 Image 관리부터 각각의 Interface check 기능 및다양한 Program을 쉽게 작성이 가능할 것 같다.
Hush Shell Script
https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/5-to-be-continued
// Android의 fastboot 기능 fastboot - run as a fastboot usb or udp device // Partition gpt - GUID Partition Table part - disk partition related commands // File system 관리 명령어 fstype - Look up a filesystem type fatsize - determine a file's size ext2load - load binary file from a Ext2 filesystem ext2ls - list files in a directory (default /) ext4load - load binary file from a Ext4 filesystem ext4ls - list files in a directory (default /) ext4size - determine a file's size ext4write - create a file in the root directory fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatmkdir - create a directory fatrm - delete a file fatsize - determine a file's size fatwrite - write file into a dos filesystem // DTB 관리 fdt - flattened device tree utility commands
2.1 Uboot의 mmc command 사용
=> mmc mmc - MMC sub system Usage: mmc info - display info of the current MMC device mmc read addr blk# cnt mmc write addr blk# cnt mmc erase blk# cnt mmc rescan mmc part - lists available partition on current mmc device mmc dev [dev] [part] - show or set current mmc device [partition] mmc list - lists available devices mmc hwpartition [args...] - does hardware partitioning arguments (sizes in 512-byte blocks): [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition [check|set|complete] - mode, complete set partitioning completed WARNING: Partitioning is a write-once setting once it is set to complete. Power cycling is required to initialize partitions after set to complete. mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode - Set the BOOT_BUS_WIDTH field of the specified device mmc bootpart-resize- Change sizes of boot and RPMB partitions of specified device mmc partconf dev [boot_ack boot_partition partition_access] - Show or change the bits of the PARTITION_CONFIG field of the specified device mmc rst-function dev value - Change the RST_n_FUNCTION field of the specified device WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values. mmc setdsr - set DSR register value
MMC 사용예제
https://forums.xilinx.com/t5/ACAP-and-SoC-Boot-and/U-boot-Mmc-read-write/td-p/891742
- mmc 기본확인
=> mmc list FSL_SDHC: 1 FSL_SDHC: 2 (SD) FSL_SDHC: 3 (eMMC) => mmc dev 3 //mmc device 선택 switch to partitions #0, OK mmc3(part 0) is current device => mmc part Partition Map for MMC device 3 -- Partition Type: DOS Part Start Sector Num Sectors UUID Type 1 8192 45668 304dec68-01 0c Boot 2 57344 445688 304dec68-02 83 3 507904 524288 304dec68-03 83 => mmc dev 2 //mmc device 선택 switch to partitions #0, OK mmc2 is current device => mmc part Partition Map for MMC device 2 -- Partition Type: DOS Part Start Sector Num Sectors UUID Type 1 129 3911551 02751898-01 0c
- mmc erase/write/read 방법
//SD Card의 Partition1 에서 File read => fatload mmc 2:1 ${loadaddr} core-lora-image-imx6sxsabresd.wic 528482304 bytes read in 35944 ms (14 MiB/s) => mmc dev 3 //mmc device 선택 switch to partitions #0, OK mmc3(part 0) is current device => pri loadaddr loadaddr=0x80800000 //0x82400000 = 0x80800000 + 0x1C00000 ( 57344*512) // Start Sector 0xE000(57344) // Num Sectors 0x6CCF8(445688) // mmc read/write/erase HEX로 밖에 동작이 안됨 => mmc erase 0xE000 0x6CCF8 //eMMC erase MMC erase: dev # 3, block # 57344, count 445688 ... => mmc write 0x82400000 0xE000 0x6CCF8 //eMMC Write MMC write: dev # 3, block # 57344, count 445688 ... 445688 blocks written: OK => mmc read 0x82400000 0xE000 0x6CCF8 //eMMC Write MMC read: dev # 3, block # 57344, count 445688 ... 445688 blocks read: OK
상위 정보는 linux application에서 fdisk -l 의 정보와 동일하며, image는 dd를 이용하여 편집가능
2.2 Uboot Script 생성
상위에서 사용했던 방법들을 간단히 정리하여 Script로 만들어서 이를 확장하는 방법을 알아보자.
- 환경변수로 분할한 후 마지막에 연결
$ vi myboot0.cmd setenv upgrade_read fatload mmc 2:1 ${loadaddr} core-lora-image-imx6sxsabresd.wic setenv upgrade_write mmc write 0x82400000 0xE000 0x6CCF8 setenv upgrade_remove fatrm mmc 2:1 ${script} setenv upgradelog_start echo ======== Simple Upgrade Script setenv upgradelog_success echo ======== Succeed to upgrade the firmware setenv upgradelog_success_read echo ======== Succeed to read the firmware setenv upgradelog_success_write echo ======== Succeed to wirte the firmware setenv upgradelog_fail_read echo ======== Failed to read a firmware file setenv upgradelog_fail_write echo ======== Failed to write a firmware file setenv upgrade_targets read write remove setenv upgrade_loop "for target in ${upgrade_targets}; do run upgrade_${target}; done" setenv upgrade_select "run upgradelog_start; if run upgrade_read; then if run upgrade_write; then run upgrade_remove; else run upgradelog_fail_write; fi; else run upgradelog_fail_read; fi" run upgrade_select
- 전체순차적으로 실행
$ vi myboot1.cmd echo ======== Simple Version Upgrade Script; setenv targetaddr ${loadaddr}; if test $version = 1; then echo "======== checked your firmware version"; setenv upgrade_read fatload mmc 2:1 ${loadaddr} core-lora-image-imx6sxsabresd.wic setenv upgrade_write mmc write 0x82400000 0xE000 0x6CCF8 if run upgrade_read; then echo "======== Ok found a SD card upgrade file"; echo "======== Start to upgrade a firmware"; if run upgrade_write; then echo "======== Ok write the firmware into eMMC"; setenv version 2; mw ${targetaddr} 0 100; mw ${targetaddr} 0x43435553 1; setexpr targetaddr $targetaddr + 4; mw ${targetaddr} 0x20535345 1; fatwrite mmc 2:1 ${loadaddr} result.txt 8 else echo "======== failed to write the image to eMMC"; mw ${targetaddr} 0 100; mw ${targetaddr} 0x4c494146 1; setexpr targetaddr $targetaddr + 4; mw ${targetaddr} 0x20 1; fatwrite mmc 2:1 ${loadaddr} result.txt setenv version 0 fi else echo "======== failed to read the image from SD card"; mw ${targetaddr} 0 100; mw ${targetaddr} 0x4c494146 1; setexpr targetaddr $targetaddr + 4; mw ${targetaddr} 0x20 1; setenv version 0; fi else echo "======== its same version"; mw ${targetaddr} 0 100; mw ${targetaddr} 0x454d4153 1; setexpr targetaddr $targetaddr + 4; mw ${targetaddr} 0x52455620 1; setexpr targetaddr $targetaddr + 4; mw ${targetaddr} 0x4e4f4953 1; fatwrite mmc 2:1 ${loadaddr} result.txt fi saveenv; reset;boot script example
https://boundarydevices.com/boot-scripts-for-main-line-u-boot-on-i-mx6/
- boot scirpt 생성
아래와 같이 기본이 PowerPC로 되어있으므로, 가능하다면, ARM으로 변경해서 사용하자. (아래와 같이 사용해도 동작가능)
$ mkimage -T script -C none -n 'Uboot Script File' -d myboot0.cmd boot.scr Image Name: Uboot Script File Created: Fri May 15 17:00:50 2020 Image Type: PowerPC Linux Script (uncompressed) Data Size: 271 Bytes = 0.26 kB = 0.00 MB Load Address: 00000000 Entry Point: 00000000 Contents: Image 0: 263 Bytes = 0.26 kB = 0.00 MB
$ mkimage -T script -C none -n 'Uboot Script File' -d myboot1.cmd boot.scr Image Name: Uboot Script File Created: Mon May 18 10:56:40 2020 Image Type: PowerPC Linux Script (uncompressed) Data Size: 979 Bytes = 0.96 kB = 0.00 MB Load Address: 00000000 Entry Point: 00000000 Contents: Image 0: 971 Bytes = 0.95 kB = 0.00 MB
- boot script 적용
=> setenv version 1 // version 입력 => setenv loadbootscript fatload mmc 2:1 ${loadaddr} ${script}; // SD Card Read로 변경 => saveenv => reset setenv loadbootscript fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
https://www.denx.de/wiki/view/DULG/UBootScripts
이를 이용하여 간단히 Upgrade script 도 간단히 만들수 있다.