目录
一、uboot概述
Bootloader
Bootloader基本功能:
二、SD卡启动盘制作
三、uboot的使用
3.1uboot模式
自启动模式
交互模式
3.2uboot帮助命令
3.3uboot环境变量命令
3.4常用环境变量
3.5网络传输命令
3.6u-boot访问存储器命令
3.7 u-boot自启动环境变量(bootcmd)
五、uboot源码结构、配置、编译
1、uboot源码结构
1.1 uboot源码获取
1.2 uboot的特点
1.3 uboot源码结构
2、uboot配置与编译
2.1uboot配置
2.2 uboot编译
六、Linux内核概述
1.1内核与操作系统
1.2Linux层次结构
1.3Linux内核特点
七、Linux内核源码结构
2.1Linux内核源码获取
Linux内核源码下载
Linux内核版本命名
Linux内核版本选择
2.2Linux内核源码结构
八、Linux内核源码的配置和编译
配置交叉编译工具链
读README
配置内核源码支持当前的硬件平台
驱动配置
内核编译
编译:
问题:
解决问题的方法:
测试内核
bootloader就相当于类,uboot就相当于对象。嵌入式领域常用的bootloader就是uboot
在操作系统运行之前运行的一小段代码,用于将软硬件环境初始化到一个合适的状态,为操作系统的加载和运行做准备,其本质为一段裸机程序不是操作系统本身
注:bootloader是启动引导程序的统称,嵌入式linux常用的bootloader是uboot。
常见的Bootloader
SD卡的存储以扇区为单位,每个扇区的大小为512Byte, 其中零扇区存储分区表(即分区信息),后续的扇区可自行分区和格式化;若选择SD卡启动,处理器上电后从第一个扇区开始将其中的内容搬移到内存,所以我们把uboot放到从第一个扇区开始之后的空间, 之后的空间根据个人需求可进行分区和格式化
具体制作步骤详情看实验手册-》实验四
uboot启动后若没有用户介入,倒计时结束后会自动执行自启动环境变量(bootcmd)中设置的命令(一般作加载和启动内核)
倒计时结束之前按下任意按键uboot会进入交互模式,交互模式下用户可输入uboot命令
help
查看uboot支持的所有命令
help 命令
查看当前命令的使用方法
printenv
打印uboot中所有的环境变量
setenv
设置指定的环境变量(保存在RAM中)
setenv 环境变量 环境变量的值
saveenv
保存所有环境变量到EMMC中
ipaddr
uboot的IP地址
serverip
服务器的IP地址(即ubuntu的IP)
bootdelay
进入自启动模式之前倒计时的秒数
loadb
通过Kermit协议下载文件到指定的内存地址( loadb 地址)
tftp
通过tftp协议下载文件到指定的内存地址( tftp 地址 文件名 )
mmc read
将EMMC中指定扇区中的内容读取到内存中指定的地址( mmc read )
addr: 内存地址
blk#: EMMC中的扇区编号
cnt: 读取的扇区的个数
mmc write
将内存中指定地址中的内容写入到EMMC中指定的扇区
mmc write
该环境变量可以设置成一到多个uboot命令的集合(若有多个使用\;分割),自启动模式下uboot就会按照bootcmd中命令的顺序逐条执行
把printenv命令写进去,开机之后不做干预,倒计时结束就会自动打印环境
eg:
setenv bootcmd tftp 40008000 interface.bin\;go 40008000
saveenv
这一章节主要分为两大块一个为产品阶段即:Linux内核、根文件系统、uboot全部存储到硬盘内,另一个为研发阶段,研发阶段因为需要反复调试,所以需要我们把跟文件系统放到NFS内使用共享的方式,Linux内核放到tftp下进行传输,uboot最好使用SD卡的方式。详情见实验手册中实验五,需要注意实验五中的第一个目的是为了练习使用tftp加载文件,这里不会正常进入linux系统。
uboot是一个开源的软件。开源有两层含义。一是可以免费用、二是开放源代码
uboot源码下载
http://www.denx.de/wiki/U-Boot/
uboot版本命名:
前期:uboot-1.2.3
现在:uboot-2008.01
08年以前uboot是1.2.几1.3.几这样命名08年开始以年份和月份命名。它的更新是非常频繁的上次更新是两天前。
uboot版本选择
支持对应的硬件平台
相对成熟的版本(资料多)
每当发布新的芯片后uboot就会增加对应芯片的版本。一般和处理器同一时期发布的uboot版本对处理器的支持较好。
代码结构清晰
支持丰富的处理器与开发板,易于移植
支持丰富的用户命令
支持丰富的网络协议
支持丰富的文件系统
支持丰富的设备驱动
更新活跃、用户较多、资料丰富
开放源代码
较高的稳定性
不具有通用性(不同的处理器、开发板uboot不可通用)
由于uboot的源码特别多所以是由很多个文件夹组成的,同类型的源码放到一个文件夹里
平台相关代码
即与CPU架构或开发板硬件相关的源码,硬件的改动对应的代码也需要进行修改
arch:与CPU架构相关的源代码
board:与开发板相关的源代码,包含各种官方评估板对应的源码
api: 这个目录下有很多的用户接口
arch: 目录下存储的是架构
board:开发板样例
boards.cfg:这个文件是配置信息
common:这下面全是uboot命令的.c文件
config.mk:也是一个配置文件
COPYING:这是版权文件虽然是开源软件但是也不能乱用
CREDITS:这里是代码贡献者名单包括他们的邮箱
disk:磁盘操作的命令文件夹
readme:一个说明书或者说帮助文档,这个说明书有5000多行都是一些介绍性的的东西。
dos:这里是详细的说明书
drivers:这里面全是驱动文件
dts:设备树文件夹,后面学习驱动时在详细学习。
examples:里面是例程,在不会写的时候可以参考一下
fs:文件系统,这里面每个文件夹内都是文件系统的源代码和makefile文件这里面ext4是嵌入式领域常用的文件系统。
include:这里是头文件
lib:这里是库
makefile:方便我们编译uboot镜像。它这个makefile是层层调用的每个文件夹下都有,使用make命令后总的makefile文件会调用每层的马克file文件来共同编译出uboot镜像。
post:上电自检程序
tools:工具
net:网络文件夹,这里面是uboot支持的一些网络。
为了保证uboot适用所有的开发板,uboot把所有的开发板都写出来了,需要哪个编译哪个
1.指定当前使用的硬件平台
make _config(咱们用的是make fs6818_config)
注1:为当前使用的开发板的名字
注2:执行该命令的前提是uboot源码支持该开发板
注3:该命令必须在uboot源码的顶层目录下执行
hqyj@hqyj:u-boot-2014.07-fs6818$ make fs6818_config
Configuring for fs6818 board...
2.指定编译uboot源码使用的编译器
将以下内容(咱们使用的源码是改过的,但是要知道这个流程)
198 ifeq ($(HOSTARCH),$(ARCH))
199 CROSS_COMPILE ?=
200 endif
修改为
198 ifeq (arm,arm)
199 CROSS_COMPILE ?= arm-none-linux-gnueabi-
200 endif
1.编译uboot
make / make all(编译的时间比较长)
注1:该命令必须在uboot源码的顶层目录下执行
注2:该命令执行后在uboot源码顶层目录下生成u-boot.bin
编译需要大概一分钟。编译完多了几个文件,多了一个system.map文件和那些u-boot开头的。
make在编译的过程中先将.c和.s编译成.o文件。最后把他们链接(ld)成一个可执行文件绿色的那个u-boot。他是elf格式的。我们肯定不能把他刷到板子上。不过在这之后它还会用objcopy把利用elf文件生成bin文件。这里还有一个srec文件这是符合摩托罗拉的二进制文件。
2.清除编译过程中生成的中间文件
make clean
make distclean
注1:该命令必须在uboot源码的顶层目录下执行
这些中间文件就是.o文件。执行make clean只是清除这些.o文件。执行下面那个会把生成的可执行文件和二进制文件也删除。恢复刚下载的源码状态。
编译问题解决
Make的时候可能出现上面问题,出现上面问题,如下方法解决:
内核
内核是一个操作系统的核心,提供了操作系统最基本的功能,是操作系统工作的基础,决定着整个系统的性能和稳定性
操作系统
操作系统是在内核的基础上添加了各种工具集、桌面管理器、库、shell、应用程序等(我们使用的网络协议都是基于TCP/ip或者UDP/IP协议开发的)(我们使用rm、mv、cp。。。这些命令都不是内核提供的)
shell翻译过来就是贝壳,他把内核很好的保护了起来。Linux内核内有文件管理系统。所以可以操作磁盘。那现在我们要操作一些文件就需要去操作内核让内核再去操作文件。但是内核很复杂,我们学到不透的时候一个误操作可能就会把内核搞坏了。所以我们操作shell让shell再去操作内核就会很安全了。
库这些lib也不是内核包含的。
图形化界面也不属于内核,内核本身只支持大黑框
进程管理、内存管理、文件系统、网络管理、驱动管理
代码结构清晰、模块化设计
支持丰富的硬件平台
较高的稳定性
开很久他都不需要维护。所以一些嵌入式设备比如路由器、基站、充电桩。还有一些大型的服务器都会用Linux。
轻量化及较强的裁剪性,只有2.9MB
开放源代码
更新活跃、用户较多、资料丰富
支持丰富的网络协议,95%服务器都用Linux就是因为他的网络协议非常的丰富。
https://www.kernel.org/
主版本号.次版本号.修订版本
支持对应的硬件平台
相对成熟的版本(资料多)
稳定版本(次版本号为偶数的版本一般都是稳定版)
内核和uboot是一样的现在很少自己配置了,都是厂家提供了。
把源码拖到ubuntu里解压
平台相关代码
arch: 与CPU架构相关的源代码
block:磁盘设备的支持 crypto:加密相关
drivers:设备驱动 firmware:固件
fs:文件系统 include:头文件
一般格式化磁盘都格式化成ntfs
init:内核初始化 ipc:进程间通信
共享内存消息队列什么的都是再ipc目录下实现的
kernel:内核核心调度机制等 lib:库 内核的核心算法。
mm:内存管理 net:网络协议
scripts:工具、脚本等 security:安全
usr:打包与压缩 virt:虚拟
COPYING: 版权 gpl版权,GNU开源协议
CREDITS: 内核贡献者
README: 说明文档
Documentation: 帮助文档
Makefile: 编译管理
samples: 示例
tools: 工具
Kconfig:内核自带的图形化界面
... ...
打开内核源码顶层目录的Makefile,搜索CROSS_COMPILE
195 ARCH ?=
196 CROSS_COMPILE ?=
修改为:
195 ARCH ?= arm
196 CROSS_COMPILE ?= arm-none-linux-gnueabi-
拿到内核源码之后,应该先清除,内核源码中的中间文件
make clean
make distclean
make mrproper --》清除更干净
方法1:
make help
得到以下信息:
fs6818_defconfig - Build for fs6818
方法2:
进入arch/arm/configs/目录
发现以下文件fs6818_defconfig ,所以PLATFORM=fs6818.
让当前的内核支持自己的硬件平台,应该执行make fs6818_defconfig
执行命令:make menuconfig
实际开发中随内核进行菜单选项的配置,都是使用make menuconfig命令
问题1:
第一次使用make menuconfig 需要安装图形化界面的工具
配置之前需要安装图形图(make meuconfig):
sudo apt-get install libncurses5-dev
问题2:
出现以下错误:
cripts/kconfig/mconf Kconfig
Your display is too small to run Menuconfig!
It must be at least 19 lines by 80 columns.
make[1]: *** [menuconfig] Error 1
make: *** [menuconfig] Error 2
原因:终端的字体太大,缩小一点
make uImage
time make uImage -jx
-time:回显编译的时间
-jx:使用多线程的方式进行编译,x可以是2,4,6,8
在编译的过程中可能出现如下错误:
"mkimage" command not found - U-Boot images will not be built
make[1]: *** [arch/arm/boot/uImage] Error 1
make: *** [uImage] Error 2
错误的原因:找不到mkimage命令,根据提示分析出来mkimage应该存在uboot源码目录中
uboot源码必须进行编译之后才会有mkimage可执行程序
将uboot源码的tools目录下的mkimage,sudo cp mkimage /usr/bin
拷贝到到ubuntu的/use/bin目录下:
sudo cp ./tools/mkimage /usr/bin
uboot目录 ubuntu目录
再次对内核源码进行编译即可通过。
将arch/arm/boot/目录下的uImage拷贝到tftpboot目录下,
测试uImage是否可以正常启动,并且挂载根文件系统(重启开发板,自动方式:先将uImage下载到内存里面,然后bootcmd启动内核,然后给内核传递参数。