赞
踩
设备确认启动方式分为硬件方式和软件方式,硬件方式是通过芯片某几个引脚的高低电平来决定启动方式;软件方式就是通过代码设置来决定启动方式。
(1)硬件方式:比如S5PV210芯片,通过拨码开关去设置芯片引脚的高低电平来设置启动方式,要改启动方式必须要硬件上进行设置,芯片在启动时检查引脚的电平从而决定去何种启动介质中读取启动代码;
(2)软件方式:比如X86架构的芯片用bios启动,在设备启动时进入bios界面,可以修改启动顺序。PC电脑也是用的bios,感兴趣可以去看看关于启动顺序的设置。
/* 读取启动方式,也就是读取om引脚的状态*/ ldr r0, =PRO_ID_BASE ldr r1, [r0,#OMR_OFFSET] bic r2, r1, #0xffffffc1 /* NAND BOOT */ 省略掉NAND BOOT部分的判断 /* SD/MMC BOOT */ cmp r2, #0xc moveq r3, #BOOT_MMCSD /* NOR BOOT */ cmp r2, #0x14 moveq r3, #BOOT_NOR /* Uart BOOTONG failed */ cmp r2, #(0x1<<4) moveq r3, #BOOT_SEC_DEV /*将r3寄存器的值保存到[INF_REG_BASE+INF_REG3_OFFSET]地址处*/ ldr r0, =INF_REG_BASE str r3, [r0, #INF_REG3_OFFSET] #if defined(CONFIG_EVT1) /* If BL1 was copied from SD/MMC CH2 */ ldr r0, =0xD0037488 ldr r1, [r0] ldr r2, =0xEB200000 cmp r1, r2 beq mmcsd_boot #endif ldr r0, =INF_REG_BASE ldr r1, [r0, #INF_REG3_OFFSET] cmp r1, #BOOT_NAND /* 0x0 => boot device is nand */ beq nand_boot cmp r1, #BOOT_ONENAND /* 0x1 => boot device is onenand */ beq onenand_boot cmp r1, #BOOT_MMCSD beq mmcsd_boot cmp r1, #BOOT_NOR beq nor_boot cmp r1, #BOOT_SEC_DEV beq mmcsd_boot mmcsd_boot: bl movi_bl2_copy b after_copy
1.读取[PRO_ID_BASE+ OMR_OFFSET]地址处的数据,然后取bit1-bit5赋值给r2;(假设r2的值是0xc,SD卡启动方式)
2.将r2做比较从而判断当前是哪种启动方式,于是得知当前是 SD/MMC BOOT,r3=#BOOT_MMCSD;
3.将r3的数据写到[INF_REG_BASE+INF_REG3_OFFSET]地址处保存起来;
4.将0xD0037488地址处的数据读取出来,如果值为0xEB200000就跳转到mmcsd_boot处执行,跳过后面的步骤;
5.将第三步保存在[INF_REG_BASE+INF_REG3_OFFSET]地址处的数据读取出来保存在r1;
6.r1的值为#BOOT_MMCSD,于是最终跳转到mmcsd_boot处执行;
7.movi_bl2_copy是一个C语言函数,主要作用就是重定位BL2;
8.after_copy就是启动代码的剩余部分;
[PRO_ID_BASE+ OMR_OFFSET]=0xE0000004,是一个寄存器的地址,该寄存器的值是硬件根据OM引脚的设置而自动填充的,这个值反映的是OM引脚的接法,也就是当前我们选择的启动介质是什么。通过判断该寄存器的bit1-bit5就可以知道该去何种启动介质读取启动代码。
这两个地址是SD卡启动相关的,参考博客《ARM芯片开发(S5PV210芯片)——SD卡启动》。
typedef u32(*copy_sd_mmc_to_mem)(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init); void movi_bl2_copy(void) { ulong ch; ch = *(volatile u32 *)(0xD0037488); copy_sd_mmc_to_mem copy_bl2 = (copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98)); #if defined(CONFIG_SECURE_BOOT) ulong rv; #endif u32 ret; if (ch == 0xEB000000) { ret = copy_bl2(0, MOVI_BL2_POS, MOVI_BL2_BLKCNT, CFG_PHY_UBOOT_BASE, 0); } else if (ch == 0xEB200000) { ret = copy_bl2(2, MOVI_BL2_POS, MOVI_BL2_BLKCNT, CFG_PHY_UBOOT_BASE, 0); } else return; if (ret == 0) while (1); else return; }
该函数作用是重定位bl2:
1.将0xD0037488地址处的数据赋值给ch,;
2.将0xD0037F98强制转换成函数指针,这是从SD/MMC中拷贝数据到内存的函数;
3.通过比较ch的值判断出当前是从SD卡通道2还是通道0启动,从而去对应的通道读取数据;
4.copy_bl2函数功能就是从SD卡某个通道的某个扇区开始读取n个块到某个地址处,具体都可以在函数参数里指定。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。