Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3546649
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类: LINUX

2014-07-21 23:02:40

 最近学习了一下uboot,并进行了简单的总结。现在贴出来请各位给与指正。
平台:powerpc mpc8548
uboot的版本:1.3.0
 
 

Uboot启动过程

 

1 入口:_start_e500

Mpc8548 复位后,只映射了最后的4K有效地址空间。Bootpg 区域被定位到LAST PAGE。该区域中的代码主要做三件事情,

清零一些寄存器;

设置exception table

添加TLB项,映射更大的区域。

 

    复位入口代码在文件resetvec.s中,只有一条跳转命令,将位于flash0xfffffffc处,uboot根目录\ board\xyt_cct_8548_1\u-boot.lds

    .section .resetvec,"ax"

    b _start_e500

 

 

下面的代码位于u-boot-1.3.0\cpu\mpc85xx\start.s

    .section .bootpg,"ax"

    .globl _start_e500

 

_start_e500:  上电复位后默认映射的最后页,即LAST ,位于0xfffff000,uboot根目录\ board\cds\mpc8548cds\u-boot.lds

 

1.1    使能L1 cache

1.2    设置异常向量表

1.3    配置MMU单元,TLB0TLB1 条目,此时虚实地址相同。默认只映射flash的最后的4KB空间,所以此空间也叫bootpg配置MMU之后,可以访问所有flash

1.4    重定位CCSRBAR,即cpu的寄存器映射区域,control config status registers

1.5    配置Local Access Window

1.6    设置L1 data cache 作为INIT_RAM使用

1.7 跳到_start_cont 处开始执行

1.8 设置堆栈到INIT_RAM中(L1 data cache),此时ddr尚未规划

1.9 调用cpu_init_f() 设置全局变量gd空间,并清零。bank空间

1.10 调用board_init_f()调用板级初始化函数,逐个调用[]中的板级初始化函数,初始化console interface。分配从0—256MBRAM空间。初始化bd_t *bd 板级数据结构信息。调用函数relocate_code () 把代码从flashloadRAM并从RAM中继续运行!

 其中:addr_sp指向栈顶(最大地址)。id指向gd_t,即全局数据结构。 Addr指向代码搬移的目的地址。

 

 

 

2 relocate_code

relocate_code ( ) 把代码从flashloadRAM

并从RAM中继续运行!

2.1将栈由内部RAMcache)空间重新定位到外部DDR

2.2中拷贝代码到DDR RAM中,在RAM中的高端,具体地址根据RAM大小确定。

 

 

2.3重定位中断向量到DDR RAM

2.4 计算in_ram函数在RAM中的地址,并跳转到该函数继续执行。

2.5 调整GOT表中函数的地址,并清零bss段。

2.6 调用board_init_r()函数

2.6.1 更新uboot命令函数地址,因为代码已拷贝到RAM中。

2.6.2 调用函数trap_init ()  copy exception 代码到RAM低地址处

2.6.3 调用flash_init()获取flash校验等,并填写flash信息到bd中。

2.6.4 调用cpu_init_r()初始化L2 cache

2.6.5调用mem_malloc_init()初始化uboot阶段的,可以allocatememory,我们板卡定义了128KB空间。

2.6.6 调用env_relocate(),如果enviroment 包含在编译的镜像中,则修改其地址。否则,申请空间,并拷贝默认的environment

2.6.7 获取ethernet mac地址,并保存到bd中。

2.6.8 调用getenv_IPaddr()environment 信息中获取ip地址,保存到bd中。

2.6.9 devices_init(),根据板卡头文件定义,注册必要的设备,

2.6.10 jumptable_init()初始化gd中的jump table中的函数,如get_versionmallocgetenv

2.6.11调用console_init_r()把串口设备设置为标准的输入、输出、错误控制终端。

2.6.12 调用interrupt_init()使能中断。

2.6.13 获取uImage RAM中的地址

注:在板卡头文件中定义了uImagekernel),ramdiskflat device tree RAM中的地址,在调试过程中需要把他们分别下载到对应的地址,即可调用bootm命令启动linux

如:ramdiskaddr=2000000fdtaddr=400000uImage1000000

 

2.6.14 调用 初始化以太网接口(ethernet)。在mpc8548 平台上,调用了相应的函数tsec_initialize()注册tsec以太网控制器设备。在板级头文件中有如下宏定义,

#define               "TSEC2"

函数中出现了环境变量“ethact”,不知“act”代表啥意思?在default_environment没找到。

2.6.15 调用main_loop()函数,进入主循环。

 

 

 

 

3. main_loop()函数

参考:E:\data sheet\网络下载\王兴伟-uboot命令-20120906\UbootCommands.pdf

Uboot运行稳定后,可以用它的内部命令来查看目标系统的信息,设置环境变量等。Uboot在硬件初始化完成后将进入main_loop()函数,main_loop()函数将进入一个无限循环,当用户输入命令后,首先将调用run_command()命令进行处理,在run_command()函数中,将调用find_cmd()函数把用户从终端输入的命令进行比较,当find_cmd()返回值不为0时证明系统支持用户输入的命令,在对命令进行检验后最后将调用命令处理函数。

Find_cmd()函数将从系统默认的命令表中查询一个匹配的命令,查看源代码发现,find_cmd()将把__u_boot_cmd_start开始到__u_boot_cmd_end结束的所有命令一一和用户输入的命令进行比较。而关于__u_boot_cmd_start__u_boot_cmd_end的定义是在板级相关的链接文件中,比如board\xyt_cct_8548_1\u-boot.lds中有以下定义

的基础上的

3.1 install_auto_complete() 安装自动补全的函数

3.2 s = getenv ("bootcmd") 获取引导命令。

3.3 run_command (s, 0) 在规定的时间内没有任何按键,运行引导内核的命令。这个命令是在板卡配置头文件中定义的。

 

3.4 len = readline (CFG_PROMPT); 输出uboot的命令行提示符,读取从串口输入的字符并保存到全局数组console_buffer[]中,遇到回车字符则返回。此时尚未判断命令有效性。

3.5 rc = run_command (lastcommand, flag) 匹配并运行命令。

 

阅读(905) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~