本文在《tiny4412 uboot 2020.10版本移植(三)——uboot初步启动》 的基础上继续向tiny4412 uboot 2020.10版添加功能。

主要有三块内容:1. D-cache开启,2. 串口设置,3. SD卡或者eMMC启动uboot并引导内核启动,第三块内容比较重要。

代码参见如下仓库,分支为20201116_release

https://gitee.com/sanzhouzi/uboot202010_tiny4412.git

https://github.com/sanzhouzi/uboot202010_tiny4412.git


该uboot的使用方法

0.1. 编译

make tiny4412_defconfig
make

0.2. 烧录

编译完成,插入sd卡到电脑,执行如下命令:
cd sd_fuse/tiny4412/

烧录BL1,BL2,UBOOT到SD卡:
sudo ./sd_fusing.sh /dev/sdx  //sdx是sd卡的设备名,使用sudo fdisk查看一下既可以知道。

sudo ./sd_fusing.sh /dev/sdd
/dev/sdd reader is identified.
-----------------size----------------------
block = 512
reserve_size = 512
bl1_size = 8192
bl2_size = 16384
uboot_size = 819200
env_size = 16384
-----------------offset----------------------
signed_bl1_position = 1
bl2_position = 17
uboot_position = 49
env_position = 1649
tzsw_position = 1681
---------------------------------------
BL1 fusing
16+0 records in
16+0 records out
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.0495088 s, 165 kB/s
---------------------------------------
BL2 fusing
28+0 records in
28+0 records out
14336 bytes (14 kB, 14 KiB) copied, 0.0998117 s, 144 kB/s
---------------------------------------
u-boot fusing
556+1 records in
556+1 records out
284727 bytes (285 kB, 278 KiB) copied, 1.1611 s, 245 kB/s
---------------------------------------
U-boot image is fused successfully.
Eject SD card and insert it again.

0.3. 烧录内核镜像到SD卡

sudo ./kernel_fuse.sh /dev/sdd

0.4. SD卡启动uboot,加载默认环境变量到SD卡

把sd卡插入板子,然后板子拨到sd卡启动模式,打开串口,波特率115200。读秒前按下回车键。

然后执行如下命令加载默认环境变量,然后保存环境变量:

env default -a

saveenv

计算linux内核占用的块数,写入env(这里或许可以修改代码,自动判断镜像大小并自动写入env?)

计算公式:kernelbsize = kernelsize(字节)/512(字节) + 1 (刚好整除不用加一)

计算结果转换为16进制,比如0x2481,执行如下命令:

setenv kernelbsize 0x2481
saveenv

0.5. 通过SD卡向eMMC烧录所有镜像

/* 烧录过程是从SD卡(dev2)读取镜像到内存,
然后切换到eMMC(dev0)烧录,
其中mmc dev 0 1代表切换到eMMC的boot1分区,
boot1分区存放BL1,BL2,UBOOT,ENV。
mmc dev 0 0代表切换到eMMC的用户分区,起始位置存放Linux内核镜像。
*//* 烧录BL1 */
mmc dev 2
mmc read 0x40008000 0x1 0x10
mmc dev 0 1
mmc write 0x40008000 0x0 0x10/* 烧录BL2 */
mmc dev 2
mmc read 0x40008000 0x11 0x20
mmc dev 0 1
mmc write 0x40008000 0x10 0x20/* 烧录UBOOT */
mmc dev 2
mmc read 0x40008000 0x31 0x640
mmc dev 0 1
mmc write 0x40008000 0x30 0x640/* 烧录内核镜像 */
mmc dev 2
mmc read 0x40008000 0x691 0x2481
mmc dev 0 0
mmc write 0x40008000 0x0 0x2481/* mmc partconf dev [boot_ack boot_partition partition_access] 对eMMC设备的boot1分区使能, 在引导操作中发送确认应答。
*/
mmc partconf 0 1 1 0
或者
mmc partconf 0 1 1 1
两个都可以让eMMC顺利启动uboot.

0.6. eMMC启动uboot,并写入env到eMMC

与步骤0.4. SD卡启动uboot,加载默认环境变量到SD卡类似:

env default -a

saveenv

setenv kernelbsize 0x2481
saveenv

至此,SD卡和eMMC都具备启动uboot并加载各自的内核镜像的能力。

如下:

SD卡启动下的串口输出:可见从SD加载了内核read zImage from SD card...

U-Boot 2020.10.20201116-ge8c07abc (Nov 16 2020 - 21:32:05 +0800) for TINY4412
Modified by Liu Guichao<gccb@foxmail.com>CPU:   Exynos4412 @ 1.4 GHz
Model: Tiny4412(v1412) board based on Exynos4412
DRAM:  1 GiB
MMC:   SAMSUNG SDHCI: 0, SAMSUNG SDHCI: 2
Loading Environment from MMC... OK
Hit any key to stop autoboot:  0
SD/MMC found on device 2
read zImage from SD card...MMC read: dev # 2, block # 1681, count 9345 ... 9345 blocks read: OK
Kernel image @ 0x40008000 [ 0x000000 - 0x48ff70 ]Starting kernel ...Uncompressing Linux... done, booting the kernel.

eMMC启动的串口输出:

U-Boot 2020.10.20201116-gf3f770ee-dirty (Nov 16 2020 - 17:27:03 +0800) for TINY4412
Modified by Liu Guichao<gccb@foxmail.com>CPU:   Exynos4412 @ 1.4 GHz
Model: Tiny4412(v1412) board based on Exynos4412
DRAM:  1 GiB
MMC:   SAMSUNG SDHCI: 0, SAMSUNG SDHCI: 2
Loading Environment from MMC... OK
Hit any key to stop autoboot:  0
SD/MMC found on device 0
switch to partitions #0, OK
mmc0(part 0) is current device
read zImage from eMMC card...MMC read: dev # 0, block # 0, count 9344 ... 9344 blocks read: OK
Kernel image @ 0x40008000 [ 0x000000 - 0x48ff70 ]Starting kernel ...Uncompressing Linux... done, booting the kernel.

Uncompressing Linux... done, booting the kernel.这句输出已经是内核镜像的输入,说明uboot已经引导启动了linux kernel镜像。

由于我还没有一个可以完全启动的内核,我先在内核的启动汇编部分head.S加入了一个跑马灯,加载到内核之后,板子的LED灯会快速闪烁。

表示加载进入了内核阶段。如下:

tiny4412 uboot引导linux内核视频说明


下面对具体修改的地方进行回顾和注释:


一、开启D-cache

默认配置文件configs/tiny4412_defconfig去掉:

CONFIG_SYS_DCACHE_OFF=y

或者make menuconfig 去掉如下选项:

ARM architecture  --->[ ] Do not enable dcache

二、串口设置

2.1. 把早期的uart debug关掉:

默认配置文件configs/tiny4412_defconfig去掉:

CONFIG_DEBUG_UART = y
CONFIG_DEBUG_UART_BASE=0x13800000
CONFIG_DEBUG_UART_CLOCK=100000000
CONFIG_DEBUG_UART_ANNOUNCE=y

或者自己通过执行make menuconfig 去掉:

Device Drivers  --->Serial drivers  --->[ ] Enable an early debug UART for debugging

注意:如果后面调试还想开启早期的uart debug,则应该关闭正常的debug。

比如include/log.h中不要添加#define DEBUG,否则可能需要修改更多的地方才能使用早期的uart debug。

2.2. 开启正常的串口控制台

由于前面已经对串口有一些前期的设置,设备树关于uart的设置也已经正确。

所以这里仅修改一个地方即可。

修改文件common/board_f.c

函数void board_init_f(ulong boot_flags)第二行

gd->have_console = 0; 修改为:gd->have_console = 1;

@@ -960,7 +963,8 @@ static const init_fnc_t init_sequence_f[] = {void board_init_f(ulong boot_flags){gd->flags = boot_flags;
-       gd->have_console = 0;
+       /*设置控制台数量*/
+       gd->have_console = 1;if (initcall_run_list(init_sequence_f))hang();

这样开启串口控制台运行如下:

可见,对内存的测试debug没有了。

如果想开启debug, 我目前的做法是在include/log.h的顶部加上#define DEBUG,可以开启大部分的debug。

各个模块可能有其他的debug, 根据提示开启即可。


三、SD卡与eMMC启动相关修改

3.1. 修改设备树arch/arm/dts/exynos4412-tiny4412.dts

这里增加eMMC设备的配置mmc0,并把启动参数bootcmd放在这里,方便修改。

config里面的参数与env的地位有些同等,代码中有很多地方都是先检测设备树有没有相关的参数,如果有就不再读取env的参数了。

但这里主要还应该是放设备相关的参数才比较妥当吧。

diff --git a/arch/arm/dts/exynos4412-tiny4412.dts b/arch/arm/dts/exynos4412-tiny4412.dts
index c0377af5..7d33c42a 100644
--- a/arch/arm/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/dts/exynos4412-tiny4412.dts
@@ -11,22 +11,64 @@#include "exynos4412.dtsi"/ {
-       model = "Tiny4412(v1412) board based on Exynos4412 \r\nModified by Liu Guichao<gccb@foxmail.com>";
-       compatible = "insignal,tiny4412", "samsung,exynos4412";
+       model = "Tiny4412(v1412) board based on Exynos4412";
+       compatible = "samsung,tiny4412", "samsung,exynos4412";chosen {bootargs ="";};+       config {
+
+               /*
+               * SD卡分区和eMMC分区信息参见include/configs/tiny4412.h最后面注释
+               * sd_env_offset = 512 + 8*1024 + 16*1024 + 800*1024
+               * emmc_env_offset = sd_env_offset - 512
+               * kernel-offset = 512 + 8*1024 + 16*1024*2 + 800*1024
+               */
+               u-boot,sd-env-offset = <0xCE200>;
+               u-boot,emmc-env-offset = <0xCE000>;
+               /* 自动启动命令, 通过当前的MMC设备判断是SD卡引导内核还是eMMC引导内核 */
+               bootcmd = "
+               if mmc rescan; then \
+                       echo SD/MMC found on device ${mmcdev}; \
+                       if test ${mmcdev} = ${sddev}; then \
+                               echo read zImage from SD card...; \
+                               mmc read ${kerneladdr} ${sdkernelboff} ${kernelbsize}; \
+                       else \
+                               if mmc dev 0 0; then \
+                                       echo read zImage from eMMC card...; \
+                                       mmc read ${kerneladdr} ${eMMCkernelboff} ${kernelbsize}; \
+                               fi; \
+                       fi; \
+               fi; \
+               bootz ${loadaddr} ";
+       };
+
+aliases {
+               mmc0 = &sdhci0;
+               mmc2 = &sdhci2;serial0 = "/serial@13800000";console = "/serial@13800000";};};+
+&sdhci0 {
+       samsung,bus-width = <4>;
+       samsung,timing = <1 2 3>;
+       cap-mmc-highspeed = "true";
+       non-removable = "true";
+       status = "okay";
+};
+
+&sdhci2 {samsung,bus-width = <4>;samsung,timing = <1 2 3>;cd-gpios = <&gpk2 2 0>;
+       cap-sd-highspeed = "true";
+       cd-inverted = "true";status = "okay";};

3.2. 修改文件/arch/arm/mach-exynos/clock.c

这里是mmc驱动根据情况修改mmc时钟的函数,

此处的修改可要可不要,结果都一样,由于我定义了exynos4412_clock结构体,我还是选择修改一下。

diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
index ef48d35a..58a46383 100644
--- a/arch/arm/mach-exynos/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -833,8 +833,14 @@ static unsigned long exynos4_get_mmc_clk(int dev_index)/* exynos4: set the mmc clock */static void exynos4_set_mmc_clk(int dev_index, unsigned int div){
+#ifdef CONFIG_TINY4412
+       struct exynos4412_clock *clk =
+               (struct exynos4412_clock *)samsung_get_base_clock();
+#elsestruct exynos4_clock *clk =(struct exynos4_clock *)samsung_get_base_clock();
+#endif
+unsigned int addr, clear_bit, set_bit;/*

3.3. 修改文件/arch/arm/mach-exynos/exynos4412_setup.h

修改MMC0(eMMC) 和MMC2(SD)的初始输入时钟,这里设置的时钟都是20MHz(方便BL2加载UBOOT到内存,前面的文章已经涉及到);

频率没有变化,但写入寄存器的值变化了,从MMC2_RATIO=0x7, MMC2_PRE_RATIO=0x4,变为9和3,修改完之后,mmc读取更稳定,

不会出现无法读取或者写入MMC的情况,但其他值,或者修改为其他频率总会出现一些问题。这里是什么原因并未深究,可能与驱动某些地方有关系。

至于MMC的时钟在MMC使用时会根据实际情况进行修改,这里仅是初始化的时钟值。驱动中设置了eMMC最大的时钟为52MHz, SD卡为50MHz。

如果加大这个值会不会不稳定?有待以后测试。

diff --git a/arch/arm/mach-exynos/exynos4412_setup.h b/arch/arm/mach-exynos/exynos4412_setup.h
index 36ce142a..aa3c05f6 100644
--- a/arch/arm/mach-exynos/exynos4412_setup.h
+++ b/arch/arm/mach-exynos/exynos4412_setup.h
@@ -378,11 +378,11 @@ freq(SCLK_ONENAND)        = 160MHz| (MMCC1_SEL << 4) \| (MMCC0_SEL << 0))-/* SCLK_MMC[0-4] = MOUTMMC[0-4]/(MMC[0-4]_RATIO + 1)/(MMC[0-4]_PRE_RATIO +1) */
-/* CLK_DIV_FSYS1 */
-#define MMC0_RATIO             0xF
-#define MMC0_PRE_RATIO         0x0
+
+/* CLK_DIV_FSYS1 MMC0=eMMC:20MHz*/
+#define MMC0_RATIO             0x9
+#define MMC0_PRE_RATIO         0x3#define MMC1_RATIO             0xF#define MMC1_PRE_RATIO         0x0#define CLK_DIV_FSYS1_VAL      ((MMC1_PRE_RATIO << 24) \
@@ -391,8 +391,8 @@ freq(SCLK_ONENAND)  = 160MHz| (MMC0_RATIO << 0))/* CLK_DIV_FSYS2  MMC2=SDMMC:20MHz*/
-#define MMC2_RATIO             0x7
-#define MMC2_PRE_RATIO         0x4
+#define MMC2_RATIO             0x9
+#define MMC2_PRE_RATIO         0x3#define MMC3_RATIO             0xF#define MMC3_PRE_RATIO         0x0#define CLK_DIV_FSYS2_VAL      ((MMC3_PRE_RATIO << 24) \
diff --git a/arch/arm/mach-exynos/include/mach/clock.h b/arch/arm/mach-exynos/include/mach/clock.h
index 98556738..e4a24048 100644
--- a/arch/arm/mach-exynos/include/mach/clock.h
+++ b/arch/arm/mach-exynos/include/mach/clock.h
@@ -513,6 +513,10 @@ struct exynos4x12_clock {unsigned int    cmu_isp_spar3;};+/* 这个结构体是根据exynos4412时钟寄存器表进行调整的,
+ * 源代码默认exynos4412是使用exynos4_clock这个结构体进行时钟设置的,
+ * 但我直接用exynos4_clock设置时钟发现跑不起来,所以就自己改用了exynos4412_clock,
+ * 你可以根据自己需要,直接使用exynos4_clock也行,因为两者大部分都是一样的,仅存在一些差异。*/struct exynos4412_clock {unsigned char   res1[0x4200];unsigned int    src_leftbus;

3.4. 修改/arch/arm/mach-exynos/spl_boot.c

这个文件里面涉及到根据启动模式OM的不同,决定从eMMC或者SD卡里面拷贝uboot到RAM中,并执行的代码。

diff --git a/arch/arm/mach-exynos/spl_boot.c b/arch/arm/mach-exynos/spl_boot.c
index a19ebaab..4b8b95ac 100644
--- a/arch/arm/mach-exynos/spl_boot.c
+++ b/arch/arm/mach-exynos/spl_boot.c
@@ -226,7 +226,7 @@ void copy_uboot_to_ram(void)#endifcase BOOT_MODE_SD:#if defined(CONFIG_TINY4412)
-               offset = UBOOT_START_OFFSET;
+               offset = SD_UBOOT_START_OFFSET;size = UBOOT_SIZE_BLOC_COUNT;#elseoffset = BL2_START_OFFSET;
@@ -234,16 +234,22 @@ void copy_uboot_to_ram(void)#endifcopy_bl2 = get_irom_func(MMC_INDEX);break;
+               #ifdef CONFIG_SUPPORT_EMMC_BOOTcase BOOT_MODE_EMMC:/* Set the FSYS1 clock divisor value for EMMC boot */
+#if ! defined(CONFIG_TINY4412)emmc_boot_clk_div_set();
-
+#endifcopy_bl2_from_emmc = get_irom_func(EMMC44_INDEX);end_bootop_from_emmc = get_irom_func(EMMC44_END_INDEX);
-
+#if defined(CONFIG_TINY4412)
+               copy_bl2_from_emmc(UBOOT_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+#elsecopy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE);
+#endif         end_bootop_from_emmc();
+break;#endif#ifdef CONFIG_USB_BOOTING

3.5. 修改cmd/mmc.c

原来的代码仅从mmc0,也就是eMMC加载内核镜像。

这里修改为通过启动方式选择使用哪个mmc设备,并设置mmcdev环境变量做标记,以便后续决定从SD或者eMMC加载内核镜像。

diff --git a/cmd/mmc.c b/cmd/mmc.c
index 1529a3e0..5d15f009 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -983,7 +983,13 @@ static int do_mmcops(struct cmd_tbl *cmdtp, int flag, int argc,if (curr_device < 0) {if (get_mmc_num() > 0) {
+#ifdef CONFIG_TINY4412
+                       /* 通过启动方式选择使用哪个mmc设备,并设置mmcdev环境变量 --Liuguichao*/
+                       curr_device = mmc_get_env_dev();
+                       env_set_ulong("mmcdev", curr_device);
+#elsecurr_device = 0;
+#endif} else {puts("No MMC device available\n");return CMD_RET_FAILURE;

3.6. 修改默认配置文件configs/tiny4412_defconfig

diff --git a/configs/tiny4412_defconfig b/configs/tiny4412_defconfig
index 64ab4cfa..f0dd6f7e 100644
--- a/configs/tiny4412_defconfig
+++ b/configs/tiny4412_defconfig
@@ -1,21 +1,21 @@CONFIG_ARM=y
-CONFIG_SYS_DCACHE_OFF=y //去掉,以启动dcacheCONFIG_ARCH_CPU_INIT=yCONFIG_ARCH_EXYNOS=yCONFIG_SYS_TEXT_BASE=0x43E00000CONFIG_ARCH_EXYNOS4=yCONFIG_TARGET_TINY4412=y
-CONFIG_DEBUG_UART=y
+# CONFIG_DEBUG_UART is not set  //去掉早期debugCONFIG_DEBUG_UART_BASE=0x13800000CONFIG_DEBUG_UART_CLOCK=100000000CONFIG_DEBUG_UART_ANNOUNCE=yCONFIG_ENV_SIZE=0x4000CONFIG_ENV_OFFSET=0x4200
+CONFIG_SUPPORT_EMMC_BOOT=y   //支持emmc启动CONFIG_SPL_TEXT_BASE=0x02023400CONFIG_SPL=yCONFIG_SPL_GPIO_SUPPORT=yCONFIG_SPL_SERIAL_SUPPORT=y
-CONFIG_IDENT_STRING=" for TINY4412"
+CONFIG_IDENT_STRING=" for TINY4412\nModified by Liu Guichao<gccb@foxmail.com>"CONFIG_DEFAULT_DEVICE_TREE="exynos4412-tiny4412"CONFIG_DISTRO_DEFAULTS=y# CONFIG_USE_BOOTCOMMAND is not set
@@ -26,7 +26,9 @@ CONFIG_SYS_PROMPT="TINY4412 # "# CONFIG_CMD_XIMG is not setCONFIG_CMD_THOR_DOWNLOAD=yCONFIG_CMD_DFU=y
-CONFIG_CMD_GPT=y             去掉硬盘格式,EFI启动等相关配置。
+# CONFIG_CMD_GPT is not set
+# CONFIG_PARTITIONS is not set
+# CONFIG_EFI_LOADER is not setCONFIG_CMD_MMC=yCONFIG_CMD_USB_MASS_STORAGE=y# CONFIG_CMD_NET is not set
@@ -41,6 +43,7 @@ CONFIG_MMC_DW=yCONFIG_MMC_SDHCI=yCONFIG_MMC_SDHCI_SDMA=yCONFIG_MMC_SDHCI_S5P=y
+CONFIG_SYS_MMC_ENV_PART=1  /* eMMC环境变量分区在1分区,默认为1 */CONFIG_MTD=yCONFIG_USB=yCONFIG_DM_USB=y

3.7. 修改env/mmc.c

由于exyons4412从SD卡和eMMC上面加载启动程序位置有些差异,所以两者的env放在不同的位置,故这里的修改是为了支持从不同的设备正确读取env。

diff --git a/env/mmc.c b/env/mmc.c
index ba872701..2ef50d9a 100644
--- a/env/mmc.c
+++ b/env/mmc.c
@@ -66,10 +66,18 @@ static inline s64 mmc_offset(int copy)const char *offset_redund;const char *partition;const char *offset;
+#ifdef CONFIG_TINY4412
+               const char *sd_offset;
+               const char *emmc_offset;
+#endif} dt_prop = {.offset_redund = "u-boot,mmc-env-offset-redundant",.partition = "u-boot,mmc-env-partition",.offset = "u-boot,mmc-env-offset",
+#ifdef CONFIG_TINY4412
+               .sd_offset = "u-boot,sd-env-offset",
+               .emmc_offset = "u-boot,emmc-env-offset",
+#endif};s64 val = 0, defvalue;const char *propname;
@@ -86,7 +94,14 @@ static inline s64 mmc_offset(int copy)}defvalue = CONFIG_ENV_OFFSET;
+#ifdef CONFIG_TINY4412
+       if (mmc_get_env_dev())
+               propname = dt_prop.sd_offset;
+       else
+               propname = dt_prop.emmc_offset;
+#elsepropname = dt_prop.offset;
+#endif#if defined(CONFIG_ENV_OFFSET_REDUND)if (copy) {
@@ -124,7 +139,14 @@ __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)#ifdef CONFIG_SYS_MMC_ENV_PART__weak uint mmc_get_env_part(struct mmc *mmc){
+#ifdef CONFIG_TINY4412
+       /* eMMC 返回设置值,否则返回0 */
+       if (!mmc_get_env_dev())
+               return CONFIG_SYS_MMC_ENV_PART;
+       return 0;
+#elsereturn CONFIG_SYS_MMC_ENV_PART;
+#endif}static unsigned char env_mmc_orig_hwpart;

3.8. 修改include/configs/tiny4412.h

这里增加写入env的一些默认参数,并对SD卡和eMMC镜像的布局做一个说明,定义了相关的一些宏。

diff --git a/include/configs/tiny4412.h b/include/configs/tiny4412.h
index 382e2833..6eeec594 100644
--- a/include/configs/tiny4412.h
+++ b/include/configs/tiny4412.h
@@ -41,13 +41,33 @@/* MMC SPL */#define COPY_BL2_FNPTR_ADDR    0x02020030+/*
+       mmcdev                  当前启动的MMC设备,启动时根据实际启动的MMC变更为2(sd)或者0(eMMC)
+       sddev                   sd卡是MMC2设备
+       sdkernelboff    内核在sd卡上面的偏移(块)
+       eMMCkernelboff  内核在eMMC上面的偏移(块)
+       kernelbsize     内核(块)大小,uboot烧录内核镜像时需要¥改变其值¥
+       bootargs                传递给内核的参数
+
+
+       bootenv
+       loadbootenv
+       importbootenv
+       以上3个环境变量并未使用到,这几个是与在文件系统读取镜像有关的参数,留待以后需要修改时使用。
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
-       "loadaddr=0x40007000\0" \
+       "loadaddr=0x40008000\0" \"rdaddr=0x48000000\0" \
-       "kerneladdr=0x40007000\0" \
+       "kerneladdr=0x40008000\0" \"ramdiskaddr=0x48000000\0" \"console=ttySAC0,115200n8\0" \"mmcdev=0\0" \
+       "sddev=2\0" \
+       "sdkernelboff=0x691\0" \
+       "eMMCkernelboff=0x0\0" \
+       "kernelbsize=0x2480\0" \
+       "bootargs=root=/dev/mmcblk0p1 rootfstype=ext4 console=ttySAC0,115200 init=/linuxrc ctp=2 skipcali=y ethmac=1C:6F:65:34:51:7E\0" \"bootenv=uEnv.txt\0" \"loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \"importbootenv=echo Importing environment from mmc ...; " \
@@ -55,6 +75,11 @@"loadbootscript=load mmc ${mmcdev} ${loadaddr} boot.scr\0" \"bootscript=echo Running bootscript from mmc${mmcdev} ...; " \"source ${loadaddr}\0"
+
+/*
+ * 参见设备树arch/arm/dts/exynos4412-tiny4412.dts的设置,
+ * 设备树bootcmd存在的情况下,这里的配置不使用,这里的配置与文件系统读取镜像有关。
+ */#define CONFIG_BOOTCOMMAND \"if mmc rescan; then " \"echo SD/MMC found on device ${mmcdev};" \
@@ -70,7 +95,9 @@"run bootscript; " \"fi; " \"fi;" \
-       "load mmc ${mmcdev} ${loadaddr} uImage; bootm ${loadaddr} "
+       "load mmc ${mmcdev} ${loadaddr} zImage; bootz ${loadaddr} "
+
+#define CONFIG_CLK_1000_400_200@@ -80,6 +107,7 @@#define RESERVE_BLOCK_SIZE             (512)#define BL1_SIZE                       (8 << 10) /*8 K reserved for BL1*/#define BL2_SIZE                       (16 << 10) /*16 K reserved for BL2*/
+#define TINY4412_ENV_SIZE                      (16 << 10) /*16 K reserved for ENV*/#define CONFIG_SPL_MAX_FOOTPRINT       (14 * 1024)@@ -90,11 +118,27 @@#define CONFIG_SYS_INIT_SP_ADDR                0x42E00000#endif+/*
+ * SD卡分区:
+ *name:       RESERVE--------BL1--------BL2--------UBOOT-------ENV---------KERNEL
+ *size:       512B-----------8KB--------16KB-------800KB-------16KB--------10MB
+ *
+ * eMMC分区:
+ *     boot1分区       mmc dev 0 1:
+ *     name:  BL1--------BL2--------UBOOT--------ENV
+ *     size:  8KB--------16KB-------800KB--------16KB
+ *
+ *     user分区        mmc dev 0 0:
+ *     name:kernel
+ *     size:10MB
+ */
+/* U-Boot copy size from boot Media to DRAM.*/
-#define COPY_UBOOT_SIZE                0xC8000 //800KB
-#define UBOOT_START_OFFSET     ((RESERVE_BLOCK_SIZE + BL1_SIZE + BL2_SIZE) /512)
-#define UBOOT_SIZE_BLOC_COUNT  (COPY_UBOOT_SIZE /512)
+#define COPY_UBOOT_SIZE                (800 << 10) /*800 K reserved for UBOOT*/
+#define SD_UBOOT_START_OFFSET  ((RESERVE_BLOCK_SIZE + BL1_SIZE + BL2_SIZE) / 512)
+#define UBOOT_SIZE_BLOC_COUNT  (COPY_UBOOT_SIZE / 512)+/* BL2 copy size from boot Media to DRAM.*/#define COPY_BL2_SIZE          0x4000#define BL2_START_OFFSET       ((RESERVE_BLOCK_SIZE + BL1_SIZE) /512)#define BL2_SIZE_BLOC_COUNT    (COPY_BL2_SIZE /512)

3.9. 修改sd卡快速烧录脚本sd_fuse/tiny4412/fast_fuse.sh

增加自动计算各镜像需要烧录到sd卡的哪个块上面。

这个脚本仅烧录BL2与uboot到sd卡。

diff --git a/sd_fuse/tiny4412/fast_fuse.sh b/sd_fuse/tiny4412/fast_fuse.sh
index f429890d..3b1c0279 100755
--- a/sd_fuse/tiny4412/fast_fuse.sh
+++ b/sd_fuse/tiny4412/fast_fuse.sh
@@ -60,9 +60,33 @@ ${MKBL2} ${E4412_UBOOT_SPL} bl2.bin 14336##################################### fusing images
-
-bl2_position=17
-uboot_position=49
+block=512
+reserve_size=512
+bl1_size=$((8*1024)) #8KB
+bl2_size=$((16*1024))  #16KB
+env_size=$((16*1024))  #16KB
+uboot_size=$((800*1024))       #800KB
+
+echo "-----------------size----------------------"
+echo block = $block
+echo reserve_size = $reserve_size
+echo bl1_size = $bl1_size
+echo bl2_size = $bl2_size
+echo uboot_size = $uboot_size
+echo env_size = $env_size
+
+signed_bl1_position=$((reserve_size/block))
+bl2_position=$((signed_bl1_position+bl1_size/block))
+uboot_position=$((bl2_position+bl2_size/block))
+env_position=$((uboot_position+uboot_size/block))
+tzsw_position=$((env_position+env_size/block))
+
+echo "-----------------offset----------------------"
+echo signed_bl1_position = $signed_bl1_position
+echo bl2_position = $bl2_position
+echo uboot_position = $uboot_position
+echo env_position = $env_position
+echo tzsw_position = $tzsw_position#<BL2 fusing>echo "---------------------------------------"

3.10. 修改sd卡烧录镜像脚本sd_fuse/tiny4412/sd_fusing.sh

该文件的作用前面的文章已经介绍过,这里增加的通过个镜像的大小,自动计算每个镜像应该烧录到SD卡的哪些块上面。与sd_fuse/tiny4412/fast_fuse.sh类似。

这个脚本可以烧录BL1,BL2,UBOOT到SD卡。

diff --git a/sd_fuse/tiny4412/sd_fusing.sh b/sd_fuse/tiny4412/sd_fusing.sh
index c6180afc..ef7ffbff 100755
--- a/sd_fuse/tiny4412/sd_fusing.sh
+++ b/sd_fuse/tiny4412/sd_fusing.sh
@@ -61,11 +61,33 @@ ${MKBL2} ${E4412_UBOOT_SPL} bl2.bin 14336##################################### fusing images-signed_bl1_position=1
-bl2_position=17
-uboot_position=49
-#tzsw_position=705
-#tzsw_position=1649
+block=512
+reserve_size=512
+bl1_size=$((8*1024)) #8KB
+bl2_size=$((16*1024))  #16KB
+env_size=$((16*1024))  #16KB
+uboot_size=$((800*1024))       #800KB
+
+echo "-----------------size----------------------"
+echo block = $block
+echo reserve_size = $reserve_size
+echo bl1_size = $bl1_size
+echo bl2_size = $bl2_size
+echo uboot_size = $uboot_size
+echo env_size = $env_size
+
+signed_bl1_position=$((reserve_size/block))
+bl2_position=$((signed_bl1_position+bl1_size/block))
+uboot_position=$((bl2_position+bl2_size/block))
+env_position=$((uboot_position+uboot_size/block))
+tzsw_position=$((env_position+env_size/block))
+
+echo "-----------------offset----------------------"
+echo signed_bl1_position = $signed_bl1_position
+echo bl2_position = $bl2_position
+echo uboot_position = $uboot_position
+echo env_position = $env_position
+echo tzsw_position = $tzsw_position#<BL1 fusing>echo "---------------------------------------"

3.11. 增加文件sd_fuse/tiny4412/kernel_fuse.sh

这个脚本可以烧录linux内核镜像zImage到SD卡中。

把zImage放到跟这个脚本同目录下,

执行 sudo ./kernel_fuse.sh /dev/xxx,xxx为你对应sd卡的设备名,如sdd,sde等。需自己用fdisk查看,请别搞错设备名。

new file mode 100755
index 00000000..52bb90b7
--- /dev/null
+++ b/sd_fuse/tiny4412/kernel_fuse.sh
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2011 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+####################################
+
+if [ -z $1 ]
+then
+    echo "usage: ./sd_fusing.sh <SD Reader's device file>"
+    exit 0
+fi
+
+if [ -b $1 ]
+then
+    echo "$1 reader is identified."
+else
+    echo "$1 is NOT identified."
+    exit 0
+fi
+
+####################################
+#<verify device>
+
+BDEV_NAME=`basename $1`
+BDEV_SIZE=`cat /sys/block/${BDEV_NAME}/size`
+
+if [ ${BDEV_SIZE} -le 0 ]; then
+       echo "Error: NO media found in card reader."
+       exit 1
+fi
+
+if [ ${BDEV_SIZE} -gt 32000000 ]; then
+       echo "Error: Block device size (${BDEV_SIZE}) is too large"
+       exit 1
+fi
+
+####################################
+# check files
+
+E4412_UBOOT=../../u-boot.bin
+E4412_UBOOT_SPL=../../spl/u-boot-spl.bin
+MKBL2=../mkbl2
+KERNEL=zImage
+
+if [ ! -f ${E4412_UBOOT} ]; then
+       echo "Error: u-boot.bin NOT found, please build it & try again."
+       exit -1
+fi
+
+if [ ! -f ${MKBL2} ]; then
+       echo "Error: can not find host tool - mkbl2, stop."
+       exit -1
+fi
+
+#<make bl2>
+${MKBL2} ${E4412_UBOOT_SPL} bl2.bin 14336
+
+####################################
+# fusing images
+block=512
+reserve_size=512
+bl1_size=$((8*1024)) #8KB
+bl2_size=$((16*1024))  #16KB
+env_size=$((16*1024))  #16KB
+uboot_size=$((800*1024))       #800KB
+
+echo "-----------------size----------------------"
+echo block = $block
+echo reserve_size = $reserve_size
+echo bl1_size = $bl1_size
+echo bl2_size = $bl2_size
+echo uboot_size = $uboot_size
+echo env_size = $env_size
+
+signed_bl1_position=$((reserve_size/block))
+bl2_position=$((signed_bl1_position+bl1_size/block))
+uboot_position=$((bl2_position+bl2_size/block))
+env_position=$((uboot_position+uboot_size/block))
+kernel_position=$((env_position+env_size/block))
+
+echo "-----------------offset----------------------"
+echo signed_bl1_position = $signed_bl1_position
+echo bl2_position = $bl2_position
+echo uboot_position = $uboot_position
+echo env_position = $env_position
+echo kernel_position = $kernel_position
+
+#<kernel fusing>
+echo "---------------------------------------"
+echo "kernel fusing"
+dd iflag=dsync oflag=dsync if=${KERNEL} of=$1 seek=$kernel_position
+
+#<flush to disk>
+sync
+
+####################################
+#<Message Display>
+echo "---------------------------------------"
+echo "U-boot image is fused (at `date +%T`) successfully."
+echo "Eject SD card and insert it again."
+

3.12. 复制内核镜像文件zImage

最后我把一个修改过的内核镜像zImage复制到了sd_fuse/tiny4412/zImage,

读者如果把该内核镜像烧录到eMMC上面,板子的流水灯快速闪动,说明uboot已经帮你把内核加载到内存,并跳转到内核运行了。

由于我手头还没有一个可以跑起来的内核镜像,所以先在内核的汇编代码中加入流水灯。

内核镜像的修改将在后续文章中介绍。


tiny4412 uboot 2020.10版本移植(四)——uboot修改支持sd卡、eMMC引导内核及其他一些杂项设置相关推荐

  1. 【正点原子STM32连载】第四十五章 SD卡实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  2. 【正点原子FPGA连载】第四十六章SD卡读写测试实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  3. s5pv210 uboot-2012-10移植(七) 之支持SD卡

    s5pv210 uboot-2012-10移植(七) 之支持SD卡 我其实对SD卡的操作不是很熟悉,所以移植的肯定有问题,在随机赠送的Kingston 4G的SD卡上可以进行读写,但是我换了张2G的S ...

  4. iTOP-4412开发板-10.1寸屏幕硬件修改支持排线和HDMI

    迅为iTOP-4412开发板-硬件- 金属框10.1寸屏幕硬件修改支持排线和HDMI 如果 iTOP-4412 开发板(精英版和全能版)同时 10.1 寸屏幕,如果 金属框 10.1 寸屏幕(如下图所 ...

  5. sd卡烧写linux内核,uboot从SD卡烧写内核和文件系统

    环境:ubuntu 13.04 一.首先制作sd启动盘: 插入SD卡 sudo dd iflag=dsync oflag=dsync if=tiny210v2-uboot.binof=/dev/mmc ...

  6. 新唐NUC980使用记录:U-Boot Linux 编译与烧录(基于SD1位置SD卡)

    文章目录 目的 SD卡分区 U-Boot编译 U-Boot环境变量 Linux编译 默认设置 使用SD卡剩余分区 使用SD卡分区存放rootfs 制作系统镜像 总结 目的 这篇文章中将测试在 NUC9 ...

  7. 【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十四章 PS端SD卡读写

    原创声明: 本原创教程由芯驿电子科技(上海)有限公司(ALINX)创作,版权归本公司所有,如需转载,需授权并注明出处. 适用于板卡型号: AXU2CGA/AXU2CGB/AXU3EG/AXU4EV-E ...

  8. 【迅为iMX6Q】开发板 u-boot 2020.04 SD卡 启动

    前言 iMX6Q 支持多种启动方式,如 emmc启动.SD 卡启动等,这里简单的记录一下 SD卡启动的流程 下载u-boot 使用 NXP 官方提供的 uboot-imx,代码地址为: https:/ ...

  9. 创客exynos-fs4412系统移植-(uboot,内核,文件系统)

    fs4412系统移植学习笔记 环境: ubuntu 14.04 发行版 FS4412 实验平台 交叉编译工具:arm-none-linux-gnueabi- gcc: 4.8.5 目录 fs4412系 ...

最新文章

  1. Caffe学习系列(17):模型各层数据和参数可视化
  2. linux内核c1bcbc40,【资料共享】给学习linux内核的大餐
  3. 基于XML和注解的Spring Bean管理
  4. 6426C Lab2 部署和配置证书服务
  5. 2018年6月1号(线段树(1))
  6. mysql innodb 索引组织表_Mysql InnoDB引擎 -索引组织表
  7. 1512. 好数对的数目
  8. box-align,box-pack实现元素垂直底部对齐
  9. VB/VBA之死,何时休?
  10. python多叉树_python中高效的四叉树实现
  11. 《C指针》学习笔记( 第四、五章)指针与字符串、指针与多维数组
  12. 基于深度学习的自动车牌识别(详细步骤+源码)
  13. 【量化投资】策略二(聚宽)
  14. 并行计算————计算机架构
  15. 1044 mysql_MySQL 常见错误 ERROR 1044
  16. oracle 重启命令
  17. localStorage 浏览器缓存
  18. 申宝在线炒股沪指下探回升
  19. 日记 or 小小说 :想进腾讯的师弟师妹们,别学我 (三)
  20. 如何构建Informix分布式数据库访问

热门文章

  1. 鸿蒙移植i.mx6ull(三) 体验鸿蒙内核Liteos-a
  2. C#选择与循环结构,运算符
  3. Springboot/Springcloud整合ELK平台,(Filebeat方式)日志采集及管理(Elasticsearch+Logstash+Filebeat+Kibana)
  4. 从头来之【图解针对虚拟机iOS开发环境搭建】
  5. 2008年杭州市“五险一金”的缴纳比例
  6. Windows10怎样创建虚拟机
  7. 网络通信协议-ICMP协议
  8. 集合框架完整版-p1
  9. android负一屏实现方案
  10. 网络攻防作业2——js实现文档控制