UBOOT配置过程
- 解压缩
tar xjf u-boot-1.1.6.tar.bz2
- 打补丁 直接打到u-boot-1.1.6里面
patch -p1 < ../u-boot-1.1.6_jz2440.patch
- u-boot命令:
print:打印出环境变量
setbootdelay10:设置“倒数计时”为10秒。加save命令 保存, reset重启后可见到“倒数计时”。
UBOOT目标是启动内核:从flash上度出内核到SDRAM中去。启动内核。
硬件相关的初始化:关‘看门狗’、‘初始化SDRAM’、‘从FLASH读出内核’、‘启动内核’。
增强功能:烧写FLASH(从网卡或从USB)。串口(通过串口写命令)。
1.读flash;
2.初始化SDRAM;
初始化时钟,单板上电后是12M运行的(晶振为12M)。
初始化串口,为开发方便要写flash功能(通过网络或USB烧镜像到单板上)。
3.启动内核:
UBOOT的源码中的README中说要先配置再编译。
1.先配置make xx_config:在Makefile中搜100ask24x0_config
2.make
==============================================================================
一、配置make 100ask24x0_config
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
“make 100ask24x0_config”便响度昂与执行下面这个脚本:
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
总结make 100ask24x0_config所做的事情:
1.开发板名称BOARD_NAME等于$1。
2.创建到平台、开发板相关的头文件链接:
ln -s asm-$2 asm
ln -s arch-$6 asm-$2/arch
ln -s proc armv asm-$2/proc //如果$2不是arm的话,此行没有
3.创建顶层Makefile包含的文件include/config.mk
ARCH = arm
CPU = arm920t
BOARD = 100ask24x0
SOC = s3c24x0
4.创建开发板相关的头文件include/config.h
- 这4个结果可以知道,要在Board目录下新建一个开发板<board_name>的目录,则在include/config目录下也要简历一个文件<board_name>.h里存放的及时开发板<board_name>的配置信息。
U-boot编译过程
编译:直接make
分析Makefile文件(从头看起)
可见UBOOT中放在最前面的两个文件是:(这两个文件的代码段)
cpu/arm920t/start.o (.text)
board/100ask24x0/boot_init.o (.test)
链接地址是0x33f80000,意思是这个uboot运行时应该位于0x33f80000这里。
一开始运行的文件是cpu/arm920t/start.o 分析uboot是,便是从start.S这个汇编文件开始。
总结:
分析Makefile得到:
1.uboot从0x33f80000处开始运行第一个文件cpu/arm920t/start.S(从这个文件分析UBOOT的功能)
从这个start.S看下开可以坎通整个UBOOT.
2.链接地址是如何定义的。
board/100ask24x0/u-boot.lds这样一个链接脚本。这个链接脚本的第一个代码段文件从0x33f80000处开始运行(当前地址0加上0x33f80000,即放UBoot放在64M sdram的最上边512K空间处)。
U-Boot的编译流程
1.首先编译cpu/
(
C
P
U
)
/
s
t
a
r
t
.
S
,
对
于
不
同
的
C
P
U
,
还
可
能
编
译
c
p
u
/
(CPU)/start.S,对于不同的CPU,还可能编译cpu/
(CPU)/start.S,对于不同的CPU,还可能编译cpu/(CPU)下的其他文件。
2.然后,对平台/开发板相关的每个目录、每个通用目录都使用它们各自的Makefile生成相应的库。
3.将1、2步骤生产的.o、.a文件按照board/BOARDDIR/config.mk文件中指定的代码段起始地址、board/(BOARDDIR)/U-Boot.lsd链接脚本进行链接。
4.第三步得到的ELF格式的U-BOOT,后面Makefile还会将他转换成二进制格式、S-Record格式。
UBOOT第一阶段系统初始化
硬件相关初始化:
1.初始化:
关看门狗
初始化时钟
初始化SDRAM
2.若程序很大,还要将程序从NAND拷贝到SDRAM中去。
3.要设置栈(sp),因为要调用C函数时,必须用到栈。
设置栈就是让SP寄存器指向某块内存。设置好栈后会调用C函数——>函数再读出内核,启动内核。
这是硬件程序。UBOOT是比较复杂的单片机程序。
4.UBOOT运行的第一个文件是:cpu/arm920t/start.S(从程序的连接脚本中可知)
- 第一条指令跳到reset
- reset做的事
a.管理模式:set the cpu to SVC32 mode将CPU设置为SVC32管理模式
b.关闭看门狗
c.关中断:屏蔽所有中断
d.CPU的一些初始化:先关flash清caches,再关MMU,初始化存储控制器(board/100ask24x0/lowlevel_init.S)
e.设置栈:栈设置好了,可以调用C函数。
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq clear_bss
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
#if 1
bl CopyCode2Ram /* r0: source, r1: dest, r2: size */
#else
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
SetLoadFlag:
/* Set a global flag, PreLoadedONRAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
ldr r2, =PreLoadedONRAM
mov r3, #1
streq r3, [r2]
#if 0
/* try doing this stuff after the relocation */
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, =INTMR
str r1, [r0]
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
/* END stuff after relocation */
#endif
ldr pc, _start_armboot
_start_armboot: .word start_armboot
f.时钟(clock_init)
g.重定位(从FLASH拷代码到SDRAM),函数CopyCode2Ram
h.清bss段。bss段是初始值为0的静态的或全局的变量,或是没有初始化的静态或全局变量,他们就放在bss段里面。
i.最后调用C函数start_armboot。
uboot第二段
功能:串口、烧写读取flash,网卡、USB,启动内核等。
启动内核过程
UBOOT最终目标:启动内核
从FLASH读出内核——>启动
单板初始化:
2440相关管脚的初始化。其中有“机器ID”的设置。其中有两个如下的设置:
gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
gd->bd->bi_boot_params = 0x30000100;
gd指向128K的内存处。机器ID,这个机器ID在讲解内核时用的着。
这是启动参数,就是启动内核的时候会传些参数。这些参数存在0x30000100这个地址。讲解内核时变知道以上两个参数的设置意义。
要从FLASH读出内核:
初始化FLASH,则要:
1.支持FLASH的读。
Nor的读和内存的读一样。不需要做什么。
2.这开发方便增加:写
NOR要写首先识别她是那种FLASH。
NAND的也要初始化识别它是哪儿种FLASH。
UBOOT是单片机的程序,从内存上分配写空间等函数都得自己实现。
环境变量:env_relocate()
单板启动后,可以按“4”进入UBOOT命令中,printenv命令会显示“环境变量”。一个变量的等于号后面是变量的值。
环静变量从哪儿里来:
1.代码里默认写死的。
2.在FLASH上的,可以修改,则要保存。
分析:uboot启动内核
1.从flash上读出内核。
从bootcmd可知:用命令nand read.jffs2将内核读到内存0x30007FC0处。从哪儿里读?从kernel读,这是个分区。
2.启动
第二条命令:bootn 0x30007FC0
可知内核的启动依赖bootcmd这个环境变量。这个环境变量里定义了两个命令,一个是从FLASH上读出内核,一个是启动内核。
即:
1.启动内核:
2.在u-boot控制界面
readline读入串口的数据。run_commond()UBOOT的核心就是这些“命令”run_commond()。故只有分析了这些命令的实现之后,才能明白内核的加载与启动。
U-Boot的移植
1.同时支持S3C2410和S3C2440
(1)新建一个开发板的相应目录和文件
(2)修改SDRAM的配置
(3)增加对S3C2440的支持
(4)选择NOR Flash型号
2.支持串口xmodem协议
3.支持网卡芯片CS8900
4.支持NAND Flash
5.支持烧写yaffs文件系统映像
6.修改默认配置参数以方便使用
(1)Linux启动参数
(2)自动启动命令
(3)默认网络地址