SD卡启动
s3c6410支持SD卡启动原理,参考《S3C6410-Internal-ROM-Booting.pdf》一文。
其原理为,IC内部已经固化了一段代码,上电后如果Boot管脚选择了SD卡启动方式,将会自动从SD卡固定的地址加载8K的代码到SRAM中(s3c6410内部8K SRAM)运行,运行之后需要将剩下的全部u-boot代码加搬运到ram中。
而现在要做的关键是,怎样搬运代码到ram。
1、建立s3c6410_sdboot.c,/home/eric/Documents/u-boot-2013.04-rc1/arch/arm/cpu/arm1176/s3c64xx/s3c6410_sdboot.c
/*
* Samsung S3C6410 SD/MMC Device Boot
* date: 2016/11/05
* Licensed under the GPL-2 or later.
*/
#include <common.h>
#include <asm/io.h>
#ifdef CONFIG_MMC_CHANNEL
#define MMC_CHANNEL CONFIG_MMC_CHANNEL
#else
#define MMC_CHANNEL 0
#endif
#define ELFIN_HSMMC_BASE (0x7C200000 + MMC_CHANNEL*0x100000)
#define HM_CONTROL4 (ELFIN_HSMMC_BASE+0x8C)
#define globalBlockSizeHide *((volatile unsigned int*)(0x0C004000-0x4))
#define globalSDHCInfo *((volatile unsigned int*)(0x0C004000-0x8))
#define LAST_BLKPOS (globalBlockSizeHide - 2)
#define BLK_SIZE 512
#define BL1_SIZE (1024*8)
#define BL2_SIZE (300*1024)
#if 0
#define ENV_SIZE CONFIG_ENV_SIZE
#else
#define ENV_SIZE (16*1024)
#endif
#define BL1_BLKCNT (BL1_SIZE/BLK_SIZE)
#define BL2_BLKCNT (BL2_SIZE/BLK_SIZE)
#define ENV_BLKCNT (ENV_SIZE/BLK_SIZE)
#define STARTBLKADDR (LAST_BLKPOS - BL1_BLKCNT - BL2_BLKCNT - ENV_BLKCNT)
#define DESTADDR CONFIG_SYS_PHY_UBOOT_BASE
//此函数在IROM中固化的代码已经实现,只开放了固定的地址用来调用。
#define CopyMMCtoMem(a,b,c,d,e) (((int(*)(int, uint, ushort, uint *, int)) \
(*((uint *)(0x0C004000 + 0x8))))(a,b,c,d,e))
int BootCopyMMCtoMem()
{
writel(readl(HM_CONTROL4) | (0x3 << 16), HM_CONTROL4);
return CopyMMCtoMem(0, STARTBLKADDR, BL2_BLKCNT, (uint *)DESTADDR, 0);
}
思考?因为SD卡和SDHC卡,IROM加载的起始地址并不相同,相差1024Block。但此处,不论SD卡类型是SD还是SDHC,copyMMCtoMem函数的参数都是固定跳过2个block!
#define LAST_BLKPOS (globalBlockSizeHide - 2)
解密:因为IROM中得到Block总数,如果是SDHC则自动减去1024。其目大概是保证SD卡和SDHC的兼容性吧!
2、修改配置文件/home/eric/Documents/u-boot-2013.04-rc1/include/configs/smdk6410.h
260行添加:CONFIG_BOOT_SD宏
#define CONFIG_BOOT_SD
3、修改u-boot-2013.04-rc1/arch/arm/cpu/arm1176/s3c64xx/Makefile
36行添加:将s3c6410_sdboot.c编译到u-boot中
COBJS-$(CONFIG_BOOT_SD) += s3c6410_sdboot.o ##eric++ 2017-11-04
4、 修改/home/eric/Documents/u-boot-2013.04-rc1/board/samsung/smdk6410/lowlevel_init.s
54行修改:修改IO配置,对应板子上的LED
/* LED on only #8 */
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x00001111//0x55540000 //eric++2017-11-04
str r1, [r0, #GPMCON_OFFSET]//str r1, [r0, #GPNCON_OFFSET]
ldr r1, =0x000000AA//ldr r1, =0x55555555
str r1, [r0, #GPMPUD_OFFSET]//str r1, [r0, #GPNPUD_OFFSET]
ldr r1, =0x000A//ldr r1, =0xf000
str r1, [r0, #GPMDAT_OFFSET]//str r1, [r0, #GPNDAT_OFFSET]
134行修改:上电后的状态
/* LED test */
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x000000AA//0x3000 //eric++
str r1, [r0, #GPMDAT_OFFSET]//str r1, [r0, #GPNDAT_OFFSET]
225行修改时钟,6400和6410时钟配置不同,否则将不能正常启动u-boot
/* FOUT of EPLL is 96MHz */
ldr r1, =0x80200203//0x200203 //eric++
5、修改u-boot-2013.04-rc1/arch/arm/cpu/arm1176/start.s,添加SD跳转
226行添加:完成初始化后,调用BootCopyMMCtoMem,将u-boot加载到ram中运行。
/* eric++ 2017-11-04*/
#if defined(CONFIG_BOOT_SD) && !defined(CONFIG_NAND_SPL)
ldr sp, =CONFIG_SYS_INIT_SP_ADDR
bl BootCopyMMCtoMem
cmp r0, #0
copyerror:
beq copyerror
ldr pc, =_main
#endif
/* end add */
6、修改基本完成。尝试进行编译,可以成功生成u-boot.bin
eric@eric-PC:~/Documents/u-boot-2013.04-rc1$ ls
api disk lib README u-boot.bin
arch doc MAINTAINERS rules.mk u-boot.lds
board drivers MAKEALL snapshot.commit u-boot.map
boards.cfg dts Makefile spl u-boot-nand.bin
common examples mkconfig System.map u-boot.srec
config.mk fs nand_spl test
COPYING helper.mk net tools
CREDITS include post u-boot
eric@eric-PC:~/Documents/u-boot-2013.04-rc1$
7、将生成的u-boot,通过烧录软件烧录至SD卡中(借用lq的软件)
其中SD和SDHC中u-boot.bin分布如下:
8、开发板,插入SD卡,接入串口线,启动超级终端(或者dnw),默认波特率为115200。BOOT拨至SD卡启动。上电!(心情无比激动)
但是遗憾!串口没有任何信息,表明板子并没有成功启动,但是LED好像亮了!
无法启动,修改如下:
/home/eric/Documents/u-boot-2013.04-rc1/board/samsung/smdk6410/u-boot-nand.lds
38行添加:保证此部分代码,在u-boot.bin的前8K代码中
board/samsung/smdk6410/libsmdk6410.o (.text)
9、再次编译,烧录,启动
U-Boot 2013.04-rc1 (Nov 04 2017 - 16:41:04) for SMDK6410
CPU: S3C6410@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6410
DRAM: 128 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###
至此!虽然出现了错误信息,但可以成功启动!!!
10、修改/home/eric/Documents/u-boot-2013.04-rc1/arch/arm/lib/board.c
588行:flash 容量0,忽略,并继续运行
//hang(); //eric++2017-11-04
11、重新启动
U-Boot 2013.04-rc1 (Nov 04 2017 - 17:13:33) for SMDK6410
CPU: S3C6410@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6410
DRAM: 128 MiB
WARNING: Caches not enabled
Flash: *** failed ***
NAND: raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
一直不断输出raise: Signal # 8 caught。其根本原因是程序中出现了运算错误,导致。
修复:u-boot-2013.04-rc1/arch/arm/cpu/arm1176/s3c64xx/timer.c
46行:将timer_load_val ,lastdec,timestamp分别用gd->arch中的timer_rate_hz,lastinc,timer_reset_value代替。并声明gd。
#define timer_load_val gd->arch.timer_rate_hz//static ulong timer_load_val; //eric++ 2017-11-04
DECLARE_GLOBAL_DATA_PTR //eric++,声明gd
63行:
/* Internal tick units */
/* Last decremneter snapshot */
#define lastdec gd->arch.lastinc//static unsigned long lastdec; //eric++ 2017-11-04
/* Monotonic incrementing timer */
#define timestamp gd->arch.timer_reset_value//static unsigned long long timestamp; //eric++ 2017-11-04
11、重新启动
U-Boot 2013.04-rc1 (Nov 04 2017 - 21:48:46) for SMDK6410
CPU: S3C6410@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: SMDK6410
DRAM: 128 MiB
WARNING: Caches not enabled
Flash: *** failed ***
NAND: nand_get_flash_type: second ID read did not match 00,04 against 00,00
No NAND device found!!!
0 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
no devices available
Wrong Image Format for bootm command
ERROR: can't get kernel image!
SMDK6410 #
至此,u-boot,启动初步完成。