1、s3c2440启动代码Bootloader学习开发板:TQ2440开发环境:fedora 10U-boot代码:u-boot-1.1.6简单上手篇: Ok,学习bootloader前我们先不管这么多先,先编译移植,来个感性的认识先吧!这里我们就编译一个天嵌自带的u-boot,编译出适合TQ2440运行的启动代码!其实很简单的,大家放松吧! 一般情况下,我会把源码放在linux的/opt/EmbedSky/Linux下。第一步进入到/opt/EmbedSky/Linux目录。第二步解压源码tar xvfj /mnt/hgfs/Linux/ u-boot-1.1.6.tar.bz2 C /第三步进
2、入u-boot源码配置u-boot:make EmbedSky_config(后面会讲为什么是这样的)最后一步编译:make使用ls查看一下当前目录可以看到u-boot.bin这个就是我们的镜像了!Ok,搞定!简单吧!自己动手篇: 这一章节我们亲自来动手做一个属于自己的u-boot吧!第一步:上一章节中可否记得make EmbedSky_config,为什么是EmbedSky_config呢?我们打开主目录的Makefile可以看到如下定义:EmbedSky_config : unconfig $(MKCONFIG) $(:_config=) arm arm920t EmbedSky NULL
3、 s3c24x0明白了吧,就是这样的。我想做一个属于自己的u-boot就得改这里了!那我们就依葫芦画瓢吧:haha_config : unconfig $(MKCONFIG) $(:_config=) arm arm920t haha NULL s3c24x0下次记得我们的是用make haha_config的了咯!第二步:既然我们修改了主目录的makefile,那是有代价滴,没事,我们就继续改咯!进入board目录将之前的天嵌的那个文件夹改为haha,并修改里面的内容:1、 修改EmbedSky.c改为haha.c。2、 修改makefile,将COBJS := EmbedSky.o fla
4、sh.o boot_init.o改为COBJS := haha.o flash.o boot_init.o第三步:将include/configs目录下的EmbedSky.h改为haha.hOk,就这样吧,照着上面编译一下吧!遇到什么问题自己再慢慢查资料咯。其实,这个的移植裁剪还是比较简单的,假如拿到一个全新的u-boot要做的工作还是挺多的,这些就自己慢慢搞吧!代码分析篇:先看下u-boot目录下的主要目录吧:Board:存放开发板相关的目录,他里面放着各种各样的开发板的板子有关的代码。比如说我们只是关注SMDK2410的,所以其他的文件可以删掉。Common:主要是u-boot命令有关的文
5、件,我们可以向其中添加自己的命令。 再来看看u-boot的启动过程吧,看下面的截图:从这张截图我们看到u-boot的启动是分为两个过程的,第一个过程是汇编代码编写的,第二个过程是c代码编译的。我们先大致了解一下代码情况吧!u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;在board/EmbedSky/u-boot.lds下有配置。u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。 我们再来看看另一张图片吧:从这里我们看到u-boot的镜像是放在nand flash里的,代码运行之后要搬运到SDRAM中就
6、是TEXT_BASE开始的地指处。 我们现在正式进入代码里面进行了解吧!start.s文件看到:.globl _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*/这一段就是异常向量表了,当发生异常的时候,就会执行到这个向量表。这里我们不管它先。也就是说我们要跳转到reset去,而且是不带返回的跳转。接着看到
7、,这一段断码是为了设置cpu的模式。reset: mrs r0,cpsr /将cpsr值保存到r0中 bic r0,r0,#0x1f /r0&=1f orr r0,r0,#0xd3 /10011,也就是设置为超级用户、中断关闭 msr cpsr,r0 /将设置好的r0的值赋给cpsr接着定义了一系列的寄存器,不用管它,之后就是关闭看门狗了:#if defined(CONFIG_S3C2400) | defined(CONFIG_S3C2410) | defined(CONFIG_S3C2440) ldr r0, =pWTCON mov r1, #0x0 /置0就是关闭了看门狗了 str r1,
8、 r0接着是设置中断屏蔽寄存器: mov r1, #0xffffffff /中断的位给屏蔽了 ldr r0, =INTMSK str r1, r0设置各时钟的分频比:#if 0 /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, r0#endif跳转到cpu初始化 bl cpu_init_crit,清除指令cache和数据cache的功能。在这里来点小插曲吧,不然很闷啊,讲什么呢?就讲讲协处理吧,协处理器就是为了分担的cpu工作的,在这里重点讲解一下p1
9、5吧,通过协处理器指令MCR和MRC提供具体的寄存器来配置和控制caches、MMU、保护系统、配置时钟模式。看着啊:p15包括15个具体的寄存器如下-R0:ID号寄存器-R0:缓存类型寄存器-R1:控制寄存器-R2:转换表基址寄存器(Translation Table Base -TTB) -R3:域访问控制寄存器(Domain access control ) -R4:保留-R5:异常状态寄存器(fault status -FSR) -R6:异常地址寄存器(fault address -FAR) -R7:缓存操作寄存器-R8:TLB操作寄存器-R9:缓存锁定寄存器-R10:TLB 锁定寄存
10、器p15的寄存器只能被MRC和MCR(Move to Coprocessor from ARM Register )指令访问。MRC 指令用于将协处理器寄存器中的数据传送到ARM 处理器寄存器中。MCR 指令用于将ARM 处理器寄存器中的数据传送到协处理器寄存器中。这个小插曲还好吧,至少等一下你们看下面的代码时不会这么迷糊了吧。cpu_init_crit: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ mrc p15, 0, r0
11、, c1, c0, 0 / /将c1为0的数值写入r0中作用就是禁止相应的位之类的(可通过cache介绍文档的知识了解) bic r0, r0, #0x00002300 clear bits 13, 9:8 (-V- -RS) bic r0, r0, #0x00000087 clear bits 7, 2:0 (B- -CAM) 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/将r0的值读到p15的寄存器c1中 mov ip, lr bl lowlevel_init mov lr, ip mov pc, lr#endif
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1