U-boot-2014.04移植到MINI2440(1) 初步探索移植

时间:2022-10-14 17:12:39

友善之臂给出了一份移植U-BOOT-2010-03的移植手册,之前也跟着做了,这次带着分析源码的目的再次移植一遍,整个过程借鉴友善之臂提供的手册,韦东山老师书籍的视频,同时参考了其他一些作者的博客,在此对他们表示感谢。

开发环境:VMWARE—Fedora14

开发板:MINI2440(64M RAM,256M NAND FLASH,2M NOR FLASH)

编译器:arm-linux-gcc-4.3.2

U-Boot版本:U-Boot-2014.04 下载地址:ftp://ftp.denx.de/pub/u-boot/

我移植的U-boot属于版本比较新的了,友善之臂和网上很多帖子都是移植的U-boot-2010的版本,现在最新的U-BOOT已经支持类似linux make menuconfig这样的功能,代码结构和安排也越来越向LINUX看齐,那么移植之前我想先弄清楚一个:什么是U-boot,它的作用是什么?

U-BOOT是一段引导加载程序,是由德国的DENX软件工程中心开发和维护,当前市面上有太多种类的平台和处理器,要想开发一种通用的bootloader几乎是不可能的,但是U-BOOT是一个主流,源码开放,灵活性很强,现在已经被附加了很多的功能,其实它最主要也是最重要的一个作用就是引导加载内核,因为加载内核的时候,内核需要知道Machine ID,知道参数在RAM中的位置,必须关中断,MMU之类的,所以内核启动并不是简单地知道自己在哪里这么简单。我们客户在使用一款嵌入式产品的时候,是不需要和U-BOOT进行交互的,之所以给U-BOOT加入这么多的功能是为了更加方便的我们去观察运行结果,做开发。

U-BOOT-2014.04共有20个子目录,12个文件,其中各个子目录和重要文件功能见下表:

名称

类型

功能说明

api

通用

U-boot提供的一些接口函数

arch

平台相关

当前U-BOOT重要的目录,arch下每个子目录代表一种处理器类型,这里我们关心arch/arm/cpu/arm920t中cpu和920t下的几个文件:interrupt.c用来设置中断和异常,cpu.c初始化CPU,start.s是U-BOOT启动后执行的第一个文件,u-boot.lds是用来组装代码。

board

平台相关

里面有很多支持的开发板型号,这里关注samsung/smdk2410/smdk2410.c和config.mk

common

通用

主要跟U-BOOT的命令有关,cmd_xxx.c以及环境变量的处理代码env_xxx.c

spl

平台相关

只有一个Makefile,u-boot的第一阶段相关,搬运第二阶段代码到内存中

disk

通用

磁盘驱动的分区处理代码

doc

说明文档

可以用来做配置参考

drivers

通用

设备的驱动程序,每种类型一个子目录包括网卡,USB,LCD等

dts

通用

设备树的控制,主要是由于LINUX 3.X中去除了很多冗余的代码,引入device tree,许多硬件细节可以直接传递给LINUX,是新的东西

examples

通用

一些示例程序

fs

通用

文件系统支持

include

通用

头文件和开发板的配制,configs子目录重要

lib

通用

通用的库文件

Licenses

通用

可以忽略。。。

nand_spl

平台相关

支持了部分平台的nand启动

net

通用

网络相关的代码,小型的协议栈

post

通用

加电自检程序

scripts

通用

脚本程序

test

通用

测试程序

tools

通用

工具,mkimage就在这里

boards.cfg

文件,平台相关

修改添加开发板配置现在在此处

Makefile

MAKEALL

config.mk

rules.mk

mkconfig

文件,通用

整个U-BOOT编译过程的规则文件

kbuild

mkconfig

文件,通用

对Makefile功能的补充,使得编译更加高效

其余

文件,通用

介绍文档以及其他

 

下面开始正式移植步骤:

(1)   修改顶层Makefile添加开发板配置选项

因为我们编译出来的u-boot是要在arm平台上运行的,所以要定义交叉编译工具arm-linux-gcc,使用vim Makefile后,可以使用/CROSS_COMPILE来搜索定位到该处,修改如下。

 

# set default to nothing for native builds

ifeq ($(HOSTARCH),$(ARCH))

CROSS_COMPILE ?=

 endif

CROSS_COMPILE = arm-linux-

 

# SHELL used by kbuild

 

U-BOOT-2010中顶层Makefile可以看到smdk2440a_config,在u-boot2014-04中已经没有了,使用命令grep “smdk24*” * -nR,结果如下:

U-boot-2014.04移植到MINI2440(1) 初步探索移植


可以看到在2014下,开发板的配置选项已经更改到了顶层目录下的boards.cfg下,这时我们进去添加mini2440的开发板配置选项

更改如下:

 U-boot-2014.04移植到MINI2440(1) 初步探索移植

(2)   在/board中建立mini2440的目录和文件,拷贝配置头文件

我们移植以smdk2410为蓝本,拷贝board/samsung/smdk2410目录到board/mini2440,在顶层目录下:

cp –a board /samsung/smdk2410/ board/mini2440/mini2440

然后进入board/mini2440目录下进行修改,以smdk2410.c为蓝本移植:

mv smdk2410.c mini2440.c

接下来拷贝配置头文件:

cp include/configs/smdk2410.h include/configs/mini2440.h

(3)   配置时钟

2410和2440时钟的初始化参数不一样,这里需要做出修改,根据arch/arm/cpu/u-boot.lds文件可知执行的第一个文件是arch/arm/cpu/arm920t/start.S

其中关于时钟频率的代码如下,我做了注释,修改的话就是在这里:

   ldr    r0,=pWTCON  //将pWTCON变量的地址放到r0中

       mov       r1,#0x0    //把立即数0放到r1中

str     r1, [r0]       //将R1中的值放到以r0为地址的存储单元中去,意思就//是设置寄存器的值来关闭看门狗

 

       /*

        *mask all IRQs by setting all bits in the INTMR - default

        */

       mov       r1,#0xffffffff

       ldr   r0,=INTMSK

       str   r1,[r0]      //关中断

# ifdefined(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]               //设置分频系数,默认1:2:4

#endif    /* CONFIG_S3C24X0 */

 

 

经过修改的代码如下,可以上下对比看有哪些地方不同,红色为改动部分,标注出来了:

       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]

# ifdefined(CONFIG_S3C2410)

       ldr   r1,=0x3ff

       ldr   r0,=INTSUBMSK

       str   r1,[r0]

# endif

      

#ifdefined(CONFIG_S3C2440)

       ldr   r1,=0x7fff

       ldr   r0,=INTSUBMSK

       str   r1,[r0]

#endif/*CONFIG_S3C2440*/

#ifdefined(CONFIG_S3C2440)

#defineMPLLCON 0x4c000004 //系统主频的配置寄存器

#defineUPLLCON 0x4c000008 //usb频率配置寄存器

#defineCAMDIVN 0x4c000018 //照相机时钟分频寄存器

 

       ldr r0,=CAMDIVN

       mov r1,#0

       str r1,[r0]

 

       ldr r0,=CLKDIVN

       mov r1,#0x05

       str r1,[r0]

             

       /*如果HDIVN不等于0,则设置CPU为异步纵向模式,所谓异步总线就是各部件和设备不采用统一时钟,

       彼此间通信采用握手信号,总线时序不固定,可以兼容多种设备*/

      

       mrc p15,0,r0,c1,c0,0 /*参看ARM的数据手册,这是一个协处理器的操作指令,此处为将协处理器p15的寄存器中的数据传送到ARM处理器的寄存器r0中,其中1是协处理器操作码1,0是协处理器操作码2,c1存放第一个操作数的协处理器寄存器,c0存放第二个操作数的协处理器寄存器*/

       orr r1,r1,#0xc0000000 /*让CPU的总线从fast变为asynchronous,orr的是一个逻辑或指令*/

       mcr p15,0,r0,c1,c0,0

      

ldr r0,=UPLLCON

       ldr r1,=0x38022//USB48MHZ时钟

       str r1,[r0]

       nop

       nop

       nop

       nop

       nop

       nop

       nop

       ldr r0,=MPLLCON

       ldr r1,=0x5c011 //CPU时钟400MHZ

       str r1,[r0]

      

#else

 

       /* FCLK:HCLK:PCLK = 1:2:4 */

       /* default FCLK is 120 MHz ! */

       ldr   r0,=CLKDIVN

       mov       r1,#3

       str   r1,[r0]

 

#endif  /*CONFIG_S3C1440*/

#endif    /* CONFIG_S3C24X0 */

 

由于在mini2440.c中也对时钟做了初始化,在此处需要将其去掉,在函数board_early_init_f()中,如下:

 U-boot-2014.04移植到MINI2440(1) 初步探索移植

(4)修改配置头文件

在include/configs/mini2440.h中,主要是添加命令行的自动补全功能,还有命令提示符,再将一些暂时不用的功能去掉。

U-boot-2014.04移植到MINI2440(1) 初步探索移植

去掉2410增加2440,增加命令行自动补全

U-boot-2014.04移植到MINI2440(1) 初步探索移植

去掉CS8900网卡部分支持

U-boot-2014.04移植到MINI2440(1) 初步探索移植

去掉USB部分的支持,包括键盘,USB存储等等

U-boot-2014.04移植到MINI2440(1) 初步探索移植

U-boot-2014.04移植到MINI2440(1) 初步探索移植

去掉部分命令的支持

(5)下载u-boot到ram中运行

修改配置文件mini2440.h

#define CONFIG_SYS_TEXT_BASE0x30008000

这是代码的加载地址,编译好之后,我们就把u-boot下载到这个地址里面去,这个地址正好是mini2440的SDRAM起始地址,由于在lowlevel_init中对底层做了初始化,因此在mini2440.h中在加入以下宏以取消对内存数据代码的破坏

       #define CONFIG_SKIP_LOWLEVEL_INIT

修改好后,在顶层目录下,执行make mini2440_config

会提示:Configuring for mini2440 board…

接着make

不出问题会生成一个u-boot.bin,这个u-boot只是最初的,还不能使用,后面还会加入很多东西。

U-boot-2014.04移植到MINI2440(1) 初步探索移植

然后chmod 777 u-boot.bin更改权限,再cp u-boot.bin /tftpboot/将生成的u-boot拷贝到tftp传输的目录下,连接开发板网线,连接串口,在开发板里面要有一个能够运行的u-boot ,我用的是之前自己移植的u-boot-2010,启动后输入指令tftp 0x30008000 u-boot.bin,下载到RAM中,然后go 0x30008000就可以看到串口输出以下信息,说明我们初步的移植成功了。

U-boot-2014.04移植到MINI2440(1) 初步探索移植

后期还有很多工作要做,打算按照友善之臂的思路,根据执行流程进一步移植,下一篇翻译讨论U-BOOT的README,这样便于移植过程的理解和掌握。