make smdk2410_config
make CROSS_COMPILE=arm-linux-
$make smdk2410_config
在shell执行以上命令, 对应于Makefile执行的命令是:smdk2410_config: unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
unconfig
unconfig:
@rm -f include/config.h include/config.mk board/*/config.tmp
删除文件include/config.h include/config.mk board/*/config.tmp
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
mkconfig是脚本文件, 传入的参数$1
至$6
分别为: smdk2410 arm arm920t smdk2410 NULL s3c24x0
, 根据传入的参数执行如下命令:cd ./include
rm -f asm
ln -s asm-arm/arch
ln -s arch-s3c24x0 asm-arm/srch
rm -f asm-arm/proc
ln -s proc-armv asm-arm/proc
config.mk
, 文件内容为:ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0
config.h
, 文件内容为:/* Automatically generated - do not edit */
#include <configs/smdk2410.h>
$make CROSS_COMPILE=arm-linux-
Makefile的执行首先包含include/config.mk
文件, 获取ARCH CPU BOARD VENDOR SOC
的定义, 然后根据宏的配置编译指定的文件, 最终生成u-boot.bin
文件, 执行流程请自行分析.Bootloader
从目标机上某个固态存储设备上将操作系统加载到RAM中运行, 整个过程并没有用户的介入. 这种模式是Bootloader
的正常工作模式, 因此, 在嵌入式产品发布的时候, Bootloader
显然必须工作在这种模式下.Boot Loader
将通过串口连接或网络连接等通信手段从主机(Host)下载文件, 然后控制启动流程.start.s
文件中, 用汇编语言写成.board/smdk2410/uboot.lds: ENTRY(_start) ==> cpu/arm920t/start.o (.text)
board/smdk2410/config.mk
.global _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
当发生异常时, 执行cpu/arm920t/interrupts.c
中定义的中断处理函数.
mrc r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
#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, #0ffffffff
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]
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* 失效I/D cache, 见S3C2410手册附录的2-16 */
mcr p15, 0, r0, c8, c7, 0 /* 失效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
*/
bit r0, r0, #0x00000087
/*
* 清除bits 7, 2:0 (B--CAM)
* Bit 0: MMU disabled
* Bit 1: Alignment Fault checking 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
ldr pc, _start_armboot
_start_armboot: .word start_armboot
lib_arm/board.c中的start_armboot是C语言开始的函数, 也是整个启动代码中C的主函数, 同时还是整个u-boot(armboot)的主函数, 该函数主要完成如下操作:
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
};
flash_init();
mem_malloc_init();
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts("NAND");
nand_init(); /* 初始化NAND */
env_relocate();
devices_init()
i2c_init();
drv_lcd_init();
drv_video_init();
drv_keyboard_init();
drv_system_init();
初始化相关网络设备, 填写IP, MAC地址等.
进入命令循环(即整个boot的工作循环), 接受用户从串口输入的命令, 然后进行相应的工作.
for (;;) {
main_loop(); /* common/main.c */
}