_start:
b reset
_undefined_instruction _software_interrupt _prefetch_abort _data_abort _not_used _irq _fiq
ldr pc, ldr pc, ldr pc, ldr pc, ldr pc, ldr pc, ldr pc,
当发生异常时,执行cpu/arm920t/interrupts.c中定义的中断处理函数 2.5.2.3
设置CPU 的模式为SVC 模式
mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0
2.5.2.4
关闭看门狗,禁掉所有中断,设置CPU 的频率
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] /*
* mask all IRQs by setting all bits in the INTMR - default */
mov r1, #0xffffffff ldr r0, =INTMSK str
r1, [r0]
# if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str
r1, [r0] # endif
/* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str
r1, [r0]
/* CONFIG_S3C2400 || CONFIG_S3C2410 */
#endif
2.5.2.5
与内存管理相关寄存器的设置,cp15协处理器,配置内存区控制寄存器
cpu_init_crit: /*
* flush v4 I/D caches */ mov r0, #0
mcr p15, 0, r0, c7, c7, 0 mcr p15, 0, r0, c8, c7, 0 /*
/* 失效I/D cache, 见S3C2410手册附录的2-16 */ /* 失效TLB, 见S3C2410手册附录的2-18 */
* disable MMU stuff and caches */
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 /* 清除 bits 13, 9:8 (--V- --RS)
* Bit 8: Disable System Protection * Bit 7: Disable ROM Protection
* Bit 13: 异常向量表基地址: 0x0000 0000 */
bic r0, r0, #0x00000087 /* 清除 bits 7, 2:0 (B--- -CAM)
* Bit 0: MMU disabled
* Bit 1: Alignment Fault checking disabled * Bit 2: Data cache disabled * Bit 7: 0 = Little-endian operation */
orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /*
* before relocating, we have to setup RAM timing * because memory timing is board-dependend, you will * find a lowlevel_init.S in your board directory. */ mov ip, lr bl
lowlevel_init
/*寄存器的具体值的设置需要对总线周期及 外围芯片非常熟悉, 根据所采用的内存芯片确定*/
mov lr, ip mov pc, lr
2.5.2.6 把u-boot.lds定义的text段,rodata段,data段,got段,__u_boot_cmd_start段搬移到ram区
#ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate:
ldr r2, _armboot_start ldr r3, _bss_start
/* relocate U-Boot to RAM */ /* r0 <- current position of code */
/* test if we run from flash or RAM */
adr r0, _start
ldr r1, _TEXT_BASE beq stack_setup
cmp r0, r1 /* don't reloc during debug */
sub r2, r3, r2 add r2, r0, r2
/* r2 <- size of armboot */ /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} stmia r1!, {r3-r10} cmp r0, r2 ble copy_loop
/* CONFIG_SKIP_RELOCATE_UBOOT */
/* copy from source address [r0] */ /* copy to target address [r1] */
/* until source end addreee [r2] */
#endif
2.5.2.7 建立stack空间
stack_setup:
ldr r0, _TEXT_BASE
/* upper 128 KiB: relocated uboot */
/* malloc area */
sub r0, r0, #CFG_MALLOC_LEN
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) sub sp, r0, #12
/* leave 3 words for abort-stack */
#ifdef CONFIG_USE_IRQ #endif
2.5.2.8 bss段清0
clear_bss:
clbss_l:str r2, [r0]
add r0, r0, #4 cmp r0, r1 ble clbss_l
/* clear loop... */
ldr r0, _bss_start ldr r1, _bss_end
/* find start of bss segment */ /* stop here */ /* clear */
mov r2, #0x00000000
2.5.2.9
进入C 代码部分
ldr pc, _start_armboot
_start_armboot: .word start_armboot
2.5.3 阶段2的C语言代码部分
lib_arm/board.c中的start_armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个
uboot(armboot)的主函数,该函数主要完成如下操作: 2.5.3.1
调用一系列的初始化函数
1. 指定初始函数表:
init_fnc_t *init_sequence[] = { cpu_init, /* cpu的基本设置 */
board_init, /* 开发板的基本初始化 */ interrupt_init, /* 初始化中断 */ env_init, /* 初始化环境变量 */
init_baudrate, /* 初始化波特率 */ serial_init, /* 串口通讯初始化 */
console_init_f, /* 控制台初始化第一阶段 */ display_banner, /* 通知代码已经运行到该处 */ dram_init, /* 配制可用的内存区 */ display_dram_config,
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2) checkboard, #endif NULL, };
执行初始化函数的代码如下:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
} }
2. 配置可用的Flash区
flash_init ()
3. 初始化内存分配函数
mem_malloc_init() 4. nand flash初始化
#if (CONFIG_COMMANDS & CFG_CMD_NAND) puts (\
nand_init(); /* 初始化 NAND */ 5. 初始化环境变量
env_relocate (); 6. 外围设备初始化
devices_init() 7. I2C总线初始化
i2c_init(); 8. LCD初始化
drv_lcd_init(); 9. VIDEO初始化
drv_video_init(); 10. 键盘初始化
drv_keyboard_init(); 11. 系统初始化
drv_system_init(); 2.5.3.2
初始化网络设备
初始化相关网络设备,填写IP、MAC地址等。 2.5.3.3
进入主UBOOT 命令行
进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应
的工作。
for (;;) {
main_loop (); /* 在common/main.c */ }
2.6 u-boot命令使用说明
2.6.1 命令配置
2.6.2 命令帮助获取
通过help可以获得当前开发板的UBOOT中支持的命令. # help ? - alias for 'help'
autoscr - run script from memory base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol bootvx - Boot vxWorks from an ELF image cmp - memory compare
coninfo - print console devices and information cp - memory copy crc32 - checksum calculation date - get/set/reset date & time dcache - enable or disable data cache echo - echo args to console erase - erase FLASH memory flinfo - print FLASH memory information go - start application at address 'addr' help - print online help icache - enable or disable instruction cache iminfo - print header information for application image imls - list all images found in flash itest - return true/false on integer compare loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nand - NAND sub-system nboot - boot from NAND device