嵌入式Linux系统移植之UBOOT分析

UBOOT配置过程

  1. 解压缩 tar xjf u-boot-1.1.6.tar.bz2
  2. 打补丁 直接打到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.SCPUcpu/(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(从程序的连接脚本中可知)

  1. 第一条指令跳到reset
  2. 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)默认网络地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值