很多产品几乎采用u-boot引导,44B0X板当然也少不了跑个u-boot,网上很多攻略,可以参考,但是不建议直接基于上面修改,自己下载一份完整的源代码,自己完完全全修改对流程更清晰
调试的话,下面是两种方案调试对比
willger方案:ADS(armgcc)+HJTAG-RDI----gcc+gdb+ocdremot---------------速率5k-10k,很慢
J-link方案:ADS(armgcc)+jlink-RDI----------gcc+gdb+jlink-GDBSERVER---速率500k,很快
1. 修改u-boot
u-boot实际就是一个小应用了,和修改ucos一样,最基础的就是,IO口初始化,时钟,串口,中断
既然是应用了,SDRAM大小,FLASH大小及驱动,网卡的驱动程序都要跑起来
一般说来,u-boot都提供了类似的芯片的start.s,汇编代码改动很少,s3c44b0x和B2类似,这里选择B2的代码来修改,下面就按照一步步的需要做修改
SDRAM和FLASH的大小,网卡芯片的使能以及网卡CS片选的地址,默认配置参数放在EEPROM中,改为FLASH中,并设置好起址地址,在B2.h中先修改好,顺便把config.mk的TEXT_BASE修改为0x0C700000(SDRAM的最高处)
#define CONFIG_DRIVER_RTL8019
#define RTL8019_BASE 0x06000300 /* base address */
/*使能8019,按照CS选择起址地址 */
#define PHYS_SDRAM_1 0x0c000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x00800000 /* 8 MB */
/*按照硬件SDRAM大小修改 */
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define PHYS_FLASH_SIZE 0x00200000 /* 2 MB */
/*按照硬件FLASH大小修改 */
#define CFG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */
#define CFG_ENV_ADDR (PHYS_FLASH_1+0x40000)
#define CFG_ENV_OFFSET 0x40000
/*在FLASH中储存ENV信息,并规定起址地址 */
//#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
/*默认是用EEPROM储存ENV信息 */
在B2.c中修改board_init,这个严格按照硬件电路图IO的功能,配合spec设置好,涉及到GPIO啊,串口啊,SDRAM、FLASH并行通信,网口接口以及中端口,我是从ucos中copy过来的
FCLK串口时钟
FLASH用的芯片同B2一样,不需要修改
8019也是一样的,唯一的修改是16B和8B的区别,8019的寄存器地址会有差别的
2. u-boot FLASH和SDRAM中分布
1,u-boot和应用烧入FLASH后的分布
|0x0020 0000
|
| 应用程序
|
|0x0008 0000
|
|
|
|0x0005 0000
|
| u-boot env
|
|0x0004 0000
|
| u-boot程序,44b0x的中断,指向u-boot的二级中断0x0c000000,可修改
|
|_start = 0x0000 0000
2,运行起来后SDRAM的分布
|0x0C80 0000
| ucos的代码会把二级中断向量表放这里的
|0xc7f ff00
|
| stack栈
|
|0xc7f f000堆heap end地址,紧跟的是stack栈
|
| 堆heap
|
|
|0x0C70 0000=0x0C80 0000-1MB
|
|
| rw段+bss
|
|0x0C50 0000:ucos rw段紧跟的是ZI段(BSS)
|
|
|
| ....把应用程序ucos加载到这里开始跑
|
|0x0C10 0000:ucos ro段
|
|
|0xc00 0000+1024
|
| u-boot指向的二级中断(可以修改为ucos的二级中断)
|
|0xc00 0000
.
.
.
|0x0020 0000
|
| 应用程序(ro+rw)
|
|0x0008 0000
|
|
|
|0x0005 0000
|
| u-boot env
|
|0x0004 0000
|
| u-boot程序,44b0x的中断,指向u-boot的二级中断0x0c000000,可修改
|
|_start = 0x0000 0000
3. j-link调试u-boot
直接Jlink加载u-boot后SDRAM的分布
|0x0C80 0000
|
|0xc7f ff00
|
|
|0x0C71 fb70 _bbs_end
|
|0x0C71 b2b8 _bbs_start
|
|0x0C71 ad40 .u_boot_cmd
|
|0x0C71 a11c .data段
|
|0x0C71 58e4 .rodata段
|
|
|0x0C70 0000=0x0C80 0000-1MB .text段,即是_armboot_start基址
|
|
|
|0x0C6d 0000 经过env_relocate后env_addr基址
|
|
|CFG_MALLOC_LEN
| #define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024 )
|
|0x0C6c ffdc (gd_t)gd(全局变量表)基址
| gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
|
|0x0C6c ffb8 (bt_t)bd(板卡信息表)基址
| gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
|
|
|IRQ FRQ栈
| IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
| FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
|
|
|
|
|0x0C10 0000
|
|0xc00 0000+1024
|
| u-boot指向的二级中断(可以修改为ucos的二级中断)
|
|0xc00 0000 RAM基址
.
.
.
|0x0020 0000
|
|
|
|0x0008 0000
|
|
|
|0x0005 0000
|
| u-boot env
|
|0x0004 0000 env_addr默认基址
|
| u-boot程序,44b0x的中断,指向u-boot的二级中断0x0c000000,可修改
|
|_start = 0x0000 0000
整个u-boot的思路很明确
-->cpu/s3c44b0/start.s(CONFIG_USE_IRQ 没有定义的,flash中时候,经过start,start_code,cpu_init_crit;拷贝code+data;拷贝0xc00 0008;stack_setup)
-->lib_arm/board.c(start_armboot)
-->board/.../flash.c
-->board/.../lowlevel_init.s
-->start_armboot
-->init_fnc_ptr
-->函数指针数组(1)
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
dram_init, /* configure available RAM banks */
display_dram_config,
#if defined(CONFIG_VCMA9)
checkboard,
#endif
NULL,
};
board_init(board/...)
env_init(common/env_eeprom.c)
serial_init(cpu/s3c44b0/serial.c)
console_init_f(common/console.c)
display_banner(lia_arm/board.c)
-->display_flash_config(lia_arm/board.c)
-->env_relocate
-->gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
-->main_loop(lia_arm/board.c)
-->abortboot若没有键按下则run_command (s, 0)(s为默认的bootcmd,这个是事先设置好的env bootcmd=run jffsboot) do_bootm do_bootm_linux
gd和bd初始化结束后内存信息,NOTE:env_valid=0
函数指针数组初始化结束后,NOTE:增加串口波特率,RAM基址,RAM大小信息
(当env_valid=0的时候env_addr为0x0C71 A828,WHY???)
最后打印信息为
U-Boot 1.1.1 (Feb 1 2009 - 22:44:29)
U-Boot code: 0C700000 -> 0C71B2B8 BSS: -> 0C71FB70
RAM Configuration:
Bank #0: 0c000000 8 MB
Flash: 2 MB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
## Booting image at 00020000 ...
Bad Magic Number
=>
当我们配置env信息后
=> setenv severip 10.0.7.216
=> setenv ipaddr 10.0.7.174
=> save
Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
.................................................................. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
=>
重新加载U-boot
函数指针数组初始化结束后,NOTE:env_valid=1 env_addr=0x0004 0000(默认flash中的地址)
env_relocate重载env_addr之后,NOTE:env_addr=0x0C6d 0000(重载到RAM中地址)
读取severip和ipaddr之后,NOTE:修改全局结构体中数据bi_ip_addr; /* IP Address */和bi_enetaddr[6]; /* Ethernet adress */
打印信息如下
U-Boot 1.1.1 (Feb 1 2009 - 22:44:29)
U-Boot code: 0C700000 -> 0C71B2B8 BSS: -> 0C71FB70
RAM Configuration:
Bank #0: 0c000000 8 MB
Flash: 2 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
## Booting image at 00020000 ...
Bad Magic Number
=>
5. 小结
先把u-boot代码流程弄清楚,要不然都不知道在哪里改代码,最好是参考类似的板子操作,走了不少弯路,MCLK这个我搞糊涂了,MCLK到底是根据外部的晶振来判断的吗???