一、Uboot的特点
>uboot属于bootloader的一种,还有armboot、vivi、redboot等等
>uboot是著名的开源软件,德国的denx开发小组维护,官网:http://www.denx.de/wiki/U-Boot/WebHome
>uboot本质就是一个裸板程序,跟咱们编写的裸板程序一样
>uboot支持多种处理器:powerpc,dsp,fpga,arm,mips,stm32等
>uboot支持的开发板多达上万种
自己的板子 飞思卡尔官方参考板FPU
CPU IMX25 IMX25
内存基地址 0x10000000 0x20000000
内存容量 128MB 256MB
闪存 NorFlash Norflash
闪存基地址 0x30000000 0x30000000
闪存容量 512MB 64MB
UART调试串口 UART1 UART0
时钟频率 40MHz 33MHz
... ... ...
厂家提供uboot源码 无法运行 完美运行
结论:切记uboot严重依赖硬件信息,所以根据硬件差异修改官方uboot源码适配我们自己的板子即可
二、uboot三大功能
2.1 硬件初始化
初始化硬件:本质目的就是为了运行linux内核提前准备一个好的硬件环境。
mmc read 0x48000000 0x800 0x3000 //将linux内核从emmc中加载到内存中
如果不初始化EMMC,不就不可以mmc read
如果不初始化内存,也不能将uImage数据拷贝到内存0x48000000地址上去
开发板上的硬件都必须初始化吗?
不用全部初始化
因为uboot仅仅就是用来启动linux内核并且它的生命周期极短,如果做大量的无用的硬件初始化 跟linux内核运行毫无关系并且延长了uboot的启动时间(用户体验不好), 关键如果做大量无用的初始化内核一旦启动,uboot生命结束所作的工作对于内核来说全部无效了,改朝换代!内核会重新初始化
哪些硬件必须初始化?
八大必要硬件
1.初始化CPU:主要初始化Cache缓存,将Cache中的数据,指令进行清除和无效处理,为了防止CPU上电之后上来就去Cache中拿去指令或者数据,造成各种异常
2.初始化系统时钟:I2C控制器的时钟,UART控制器的时钟800MHz,200MHz,50MHz
3.初始化内存
4.初始化闪存
5.初始化网卡或者OTG USB
6.关闭中断:加快uboot启动的速度,缩短系统启动时间,提高用户体验,中断处理将来交给linux内核来处理
7.初始化串口
8.关闭看门狗:加快uboot启动的速度,防止系统复位 看门狗功能:如果系统死机,利用看门狗在系统死机时系统复位!
喂狗:看门狗的倒计时没有到期时重新设置一个新的倒计时,此过程叫喂狗
注意:其他硬件外设根据用户需求选择性初始化即可,例如:手机开机实现一个logo显示,此时uboot的代码必须初始化LCD显示屏硬件无线路由器没有必要显示logo,所以对应的uboot代码无需添加LCD显示屏初始化
2.2 加载启动linux内核功能
从内存上加载linux内核到内存并且从内存启动linux内核,
通过bootcmd环境变量实现
setenv bootcmd mmc read 0x48000000 0x800 0x3000 \; bootm 0x48000000
注意:0x800~0x3000 以块为单位512k(0x200)
2.3 挂接根文件系统rootfs
给linux内核传递启动参数告诉根文件系统rootfs位于闪存的某个分区上,
通过bootargs环境变量实现,
setenv bootargs root=/dev/mmcblk0p2 init=/linuxrc cosole=ttySCA0,115200 maxcpus=1
[lcd=wy070ml tp=gslx680-linux] []配置lcd和触摸屏
三、uboot源码操作
==获取交叉编译器并且安装交叉编译器==
建议:从芯片厂家获取
切记:交叉编译器的版本要和uboot源码版本要匹配
==获取uboot源码==
切记:从芯片厂家获取
注意:此源码仅仅支持芯片厂家的参考板,不一定能够在自己设计的开发板上运行起来,所以将来势必要根据硬件差异修改uboot源码
拿到源码时,先不要根据硬件差异修改官方的uboot源码,先对uboot源码做编译验证:
uboot源码操作三步骤:
make distclean //获取最干净的uboot源码,只做一次,清除生成的所有文件
make abc_config //配置uboot源码,配置成能够运行在abc这个参考板上,只做一次,abc 参考板的名称
make //编译,只要修改了uboot源码,必须重新编译
ls
ubootpak.bin //便是三星独有的 u-boot.bin
案例:
交叉编译X6818开发板官方的uboot源码
上位机执行:
sudo chown tarena /opt -R
sudo chgrp tarena /opt -R
cp uboot.tar.bz2 /opt/
cd /opt/
tar -xvf uboot.tar.bz2
cd /opt/uboot //进入uboot源码根目录
//三步骤
make distclean
make x6818_config
make -j2/-j4/-j8 //采用2核或者4核或者8核同时编译
ls
ubootpak.bin //编译生成的uboot可执行文件
==uboot源码操作==
修改uboot源码中跟硬件信息相关的头文件
此头文件定义了大量的外设硬件信息,只需根据硬件差异修改对应的宏即可;
此头文件位于:uboot源码/include/configs/abc.h(abc就是参考板的名称)
案例:利用sourceinsight创建uboot源码工程,然后阅读x6818开发板对应的头文件;
位于:/opt/uboot/include/configs/x6818.h
下面操作x6818.h头文件
uboot的内存格局
/*设置系统(x6818)代码段基地址0x43C00000
x6818地址范围:0x40000000 ~ 0x7FFFFFFF(1GB)*/
#define CONFIG_SYS_TEXT_BASE 0x43C00000
-------------------------------------------------------------------------------------------------------------------------
/*设置x6818初始化栈指针指向代码段基地址
注意:ARM处理器 栈区地址是往下走 满减栈的意思是先降地址,再放数据*/
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE
标签:初始化,uboot,SYS,源码,Uboot,CONFIG,define From: https://blog.csdn.net/qq_63650289/article/details/143464561/*设置堆区起始地址*/
#define CONFIG_MEM_MALLOC_START 0x44000000
/*堆区的大小 32M,
分配大小一般比你需要的大小要大一些,防止你其他地方也需要分配堆区*/
#define CONFIG_MEM_MALLOC_LENGTH 32*1024*1024-------------------------------------------------------------------------------------------------------------------------
/*Config_LCD 显存起始地址*/
#define CONFIG_FB_ADDR 0x46000000
#define CONFIG_BMP_ADDR 0x47000000-------------------------------------------------------------------------------------------------------------------------
/* Download OFFSET
指定uboot默认内存下载地址*/
#define CONFIG_MEM_LOAD_ADDR 0x48000000-------------------------------------------------------------------------------------------------------------------------
/*指定内存的起始地址和内存的大小*/
#define CONFIG_SYS_SDRAM_BASE CFG_MEM_PHY_SYSTEM_BASE
#define CONFIG_SYS_SDRAM_SIZE CFG_MEM_PHY_SYSTEM_SIZE== ==
#define CFG_MEM_PHY_SYSTEM_BASE 0x40000000
#define CFG_MEM_PHY_SYSTEM_SIZE 0x40000000 /* 1GB */
//#define CFG_MEM_PHY_SYSTEM_SIZE 0x80000000 /* 2GB */-------------------------------------------------------------------------------------------------------------------------
#define CONFIG_SYS_MALLOC_END (CONFIG_MEM_MALLOC_START + CONFIG_MEM_MALLOC_LENGTH)
/* board_init_f, more than 2M(0x8000) for ubifs */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_MEM_MALLOC_LENGTH - 0x8000)/* kernel load address */
#define CONFIG_SYS_LOAD_ADDR CONFIG_MEM_LOAD_ADDR
/*内存测试 :可以找一块内存区,往那一块内存区里面写入数据,看是否读出来是你写入的数据,写入的和读出的数据一致便成功*/
/* memtest works on */
#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_MALLOC_END
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE)