/*****************
uboot移植
******************/
【1】获取u-boot源码
1. u-boot官方网站
https://ftp.denx.de/pub/u-boot/
2. 开发板厂家
3. 芯片厂家
4. 主管领导(推荐)
第1种和第2,3,4种有何区别?
芯片厂家没有将芯片的uboot支持的源码开源
到u-boot官方源码中,
uboot官方源码不支持此处理器。
S5P6818芯片三星没有将支持此处理器的
源码开源到uboot官方,uboot官方获取的
uboot源码不支持S5P6818芯片。
此课程使用的fs6818的uboot源码:u-boot-2014.07-netok.tar.bz2
【2】uboot版本选择
* 1. 芯片厂家提供哪个版本就直接用哪个版本
2. 不选最新 --》 不稳定,资料较少
3. 不选太旧 --》 不支持硬件平台
4. 不选择测试版,选择稳定版
后缀有rc为测试版
【3】移植的准备工作
根据处理器获取硬件相关的信息。
cpu:Cortex-A53
arch:ARM
SOC:S5P6818
vendor:samsung
board:S5P6818 ---》fs6818开发板
【4】移植uboot源码
1. 准备uboot源码
1》 拷贝uboot源码到ubuntu中。
2》 解压缩uboot源码
tar -vxf u-boot-2014.07-netok.tar.bz2
3》 进入uboot源码目录
cd u-boot-2014.07
不要将源码放到共享文件夹中,
源码不要在windows下边去解压缩。
windows不支持软连接文件。
2. 分析uboot源码的目录结构
平台相关:跟硬件相关的代码
arch :架构相关代码
board:板子相关代码
samsung公司将arch和borad目录下很多跟自己硬件无关的代码全部删除
uboot源码的配置编译和管理使用Makefile工具。
3. 配置和编译uboot源码:
1》 make help : 查看make的帮助信息
清除目标:
clean
mrproper
distclean
编译uboot源码:
all
Execute "make" or "make all" to build all targets marked with [*]
For further info see the ./README file
更多的详细的信息查看README。
2》读README
254 For all supported boards there are ready-to-use default
255 configurations available; just type "make <board_name>_config".
256
257 Example: For a TQM823L module type:
258
259 cd u-boot
260 make TQM823L_config
make <board_name>_config 作用?
由于uboot源码支持多种架构和开发板,应该配置uboot支持
当前自己使用的开发板,目的是编译uboot源码时,
只编译跟自己硬件平台相关的代码。
3》uboot源码详细的配置编译过程
1> 修改Makefile配置交叉编译工具链
打开uboot源码顶层目录的Makefile,修改以下内容:
198 ifeq ($(HOSTARCH),$(ARCH))
199 CROSS_COMPILE ?=
200 endif
修改为:
198 ifeq (arm,arm)
199 CROSS_COMPILE ?= arm-none-linux-gnueabi-
200 endif
2> 清除中断文件
make distclean
切记:make distclean只在第一次编译是执行一次。
3> 配置uboot源码支持fs6818开发板
make fs6818_config
打印以下信息表示配置成功:
Configuring for fs6818 board...
4> 编译uboot源码,生成uboot的镜像(可执行文件)
make/make all
打印以下信息表示编译成功,生成ubootpak.bin
LD u-boot
OBJCOPY u-boot.srec
OBJCOPY u-boot.bin
./tools/mk6818 ubootpak.bin nsih.txt 2ndboot u-boot.bin
NSIH : 188 line processed.
NSIH : 512 bytes generated.
Generate destination file: ubootpak.bin
分析make fs6818_config命令的执行过程详解
需要具备能力:看到Makefile shell脚本
1. 打开uboot源码顶层目录的Makefile文件,
搜索fs6818_config,搜索发现没有fs6818_config目标。
%:模式匹配符
搜索_config,找到以下信息:
467 %_config:: outputmakefile
468 @$(MKCONFIG) -A $(@:_config=)
469 @cp net/x6818-eth.mk net/eth.o
去掉@$(MKCONFIG) -A $(@:_config=)前边的@符号,
将命令回显到终端。
/home/hqyj/20021/porting/u-boot-2014.07/mkconfig -A fs6818
$(@:_config=):截取fs6818_config中的fs6818字符串
2. 使用file命令查看mkconfig文件的属性
file mkconfig : shell脚本文件
3. 打开uboot源码顶层目录的mkconfig脚本文件
24 if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
25 # Automatic mode
26 line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' $srctree/boards.cfg`
27 if [ -z "$line" ] ; then
28 echo "make: *** No rule to make target \`$2_config'. Stop." >&2
29 exit 1
30 fi
31
32 set ${line}
33 # add default board name if needed
34 [ $# = 3 ] && set ${line} ${1}
35 fi
解析:
$# : 参数的个数
$1 : 第一个参数
$2 : 第二个参数
-eq :相等
-a :并且
$0 !~ /^#/ : 不是以#开头
$7 ~ /^'"$2"'$/ :$7和$2相等
打开uboot源码顶层目录的boards.cfg
line=Active arm slsiap s5p6818 s5p6818 fs6818 fs6818 -
set ${line} :重新设置脚本文件传递的参数
之前:
mkconfig -A fs6818
$1 $2
执行set ${line}之后:
mkconfig Active arm slsiap s5p6818 s5p6818 fs6818 fs6818 -
$1 $2 $3 $4 $5 $6 $7 $8
51 CONFIG_NAME="${7%_config}"
52
53 [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"
54
55 arch="$2"
56 cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
57 spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
解析:
CONFIG_NAME=fs6818
arch=arm
cpu=slsiap
63 [ "$6" != "-" ] && board="$6"
64 [ "$5" != "-" ] && vendor="$5"
65 [ "$4" != "-" ] && soc="$4"
board=fa6818
vendor=s5p6818
SOC=S5P6818
96 if [ "$options" ] ; then
97 echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${
98 else # 配置成功打印以下内容
99 echo "Configuring for ${BOARD_NAME} board..."
100 fi
# 创建架构头文件
102 #
103 # Create link to architecture specific headers
104 #
105 if [ -n "$KBUILD_SRC" ] ; then
106 mkdir -p ${objtree}/include
107 LNPREFIX=${srctree}/arch/${arch}/include/asm/
108 cd ${objtree}/include
109 mkdir -p asm
110 else
111 cd arch/${arch}/include
112 fi
113
114 rm -f asm/arch
115
116 if [ "${soc}" ] ; then
117 ln -s ${LNPREFIX}arch-${soc} asm/arch
118 elif [ "${cpu}" ] ; then
119 ln -s ${LNPREFIX}arch-${cpu} asm/arch
120 fi
121
122 if [ -z "$KBUILD_SRC" ] ; then
123 cd ${srctree}/include
124 fi
# 创建Make工具需要使用的配置头文件
126 #
127 # Create include file for Make
128 #
129 ( echo "ARCH = ${arch}"
130 if [ ! -z "$spl_cpu" ] ; then
131 echo 'ifeq ($(CONFIG_SPL_BUILD),y)'
132 echo "CPU = ${spl_cpu}"
133 echo "else"
134 echo "CPU = ${cpu}"
135 echo "endif"
136 else
137 echo "CPU = ${cpu}"
138 fi
139 echo "BOARD = ${board}"
140
141 [ "${vendor}" ] && echo "VENDOR = ${vendor}"
142 [ "${soc}" ] && echo "SOC = ${soc}"
143 exit 0 ) > config.mk
打开include目录下的config.mk文件,有以下信息:
1 ARCH = arm
2 CPU = slsiap
3 BOARD = fs6818
4 VENDOR = s5p6818
5 SOC = s5p6818
创建板子指定的头文件
152 #
153 # Create board specific header file
154 #
155 if [ "$APPEND" = "yes" ] # Append to existing config file
156 then
157 echo >> config.h
158 else
159 > config.h # Create new config file
160 fi
161 echo "/* Automatically generated - do not edit */" >>config.h
162
163 for i in ${TARGETS} ; do
164 i="`echo ${i} | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'`"
165 echo "#define CONFIG_${i}" >>config.h ;
166 done
168 echo "#define CONFIG_SYS_ARCH \"${arch}\"" >> config.h
169 echo "#define CONFIG_SYS_CPU \"${cpu}\"" >> config.h
170 echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h
171
172 [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h
173
174 [ "${soc}" ] && echo "#define CONFIG_SYS_SOC \"${soc}\"" >> config.h
175
176 [ "${board}" ] && echo "#define CONFIG_BOARDDIR board/$BOARDDIR" >> config.h
177 cat << EOF >> config.h
178 #include <config_cmd_defaults.h>
179 #include <config_defaults.h>
180 #include <configs/${CONFIG_NAME}.h>
181 #include <asm/config.h>
182 #include <config_fallbacks.h>
183 #include <config_uncmd_spl.h>
184 EOF
185
打开include目录下的config.h文件,有以下信息:
1 /* Automatically generated - do not edit */
2 #define CONFIG_SYS_ARCH "arm"
3 #define CONFIG_SYS_CPU "slsiap"
4 #define CONFIG_SYS_BOARD "fs6818"
5 #define CONFIG_SYS_VENDOR "s5p6818"
6 #define CONFIG_SYS_SOC "s5p6818"
7 #define CONFIG_BOARDDIR board/s5p6818/fs6818
8 #include <config_cmd_defaults.h>
9 #include <config_defaults.h>
10 #include <configs/fs6818.h>
11 #include <asm/config.h>
12 #include <config_fallbacks.h>
13 #include <config_uncmd_spl.h>
【8】开发板系统的部署
uboot镜像:ubootpak.bin
linux内核镜像:uImage
根文件系统镜像:ramdisk.img
根文件系统:rootfs
ramdisk.img由rootfs打包压缩得到
1. 开发阶段系统部署方式 (驱动开发)
uboot ---》EMMC/SD卡
uImage ---》使用tftp下载到内存中
rootfs ---》使用nfs网络文件系统的方式进行挂载
2. 产品阶段系统部署方式(项目完成)
uboot ---》EMMC/SD卡
uImage ---》EMMC/SD卡
ramdisk.img ---》EMMC/SD卡
【开发阶段系统部署方式】
内核镜像:系统移植\系统移植资料\镜像\uImage
1. 启动uboot进入uboot的交互界面
2. 下载内核镜像uImage到内存中
先将uImage镜像文件拷贝到tftpboot目录下,
tftp 0x48000000 uImage
3. 设置自启动参数bootargs, 重点掌握面试出现概率高。
uboot环境变量中的bootargs变量是一个自启动参数,
linux内核启动时,会uboot环境变量的分区读取bootargs变量的值。
(只需要设置一次)
ubuntu系统是32位:
setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.222
saveenv
ubuntu系统是16.04 64位:
setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs v4,tcp rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.222
ubuntu系统是18.04以上 64位:
setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs v4,tcp rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.222
ubuntu系统是18.04以上版本需要修改ubuntu中的配置文件:
参考文档:
https://www.jianshu.com/p/10e3245f15f3?tdsourcetag=s_pctim_aiomsg
root=/dev/nfs:根文件系统的类型是nfs
nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs:
根文件系统的路径,改成自己的ubuntu
IP地址和根文件系统的路径
rw:对根文件系统具有可读可写的权限
console=/dev/ttySAC0,115200:
开发板使用的是串口0,波特率是115200
init=/linuxrc:内核启动之后执行的1号进程
ip=192.168.1.222:开发板的IP地址
bootargs:就是告诉内核从哪里挂载根文件系统的,
4. 启动linux内核
bootm 0x48000000
bootm:用于启动linux内核的命令
5. 总结:根文件系统挂载不成功的原因
1》检查nfs安装和配置是否正确
2》重启nfs服务
sudo service nfs-kernel-server restart
3》检查bootargs参数设置是否正确
tftp下载镜像不成功的原因,翻阅前边的笔记。
uboot配置编译流程:
uboot配置编译流程
1》配置交叉编译工具链
CROSS_COMPILE
2》清除源码的中间文件
make clean / distclean
3》配置源码支持自己的硬件平台
make <board_name>_config
make fs6818_config
4》编译uboot源码
make all
通过ubuntu系统烧写ubootpak.bin到SD卡中
使用sdtool工具:工具在以下目录中:
系统移植\系统移植资料\工具\sdtool
1》拷贝sdtool工具到ubuntu中,并切换到sdtool目录下
....
cd sdtool
2》将SD卡插到PC上,并让ubuntu识别SD卡,
要求:必须使用SD卡读卡器,不可以使用电脑自带的SD卡卡槽
SD卡被ubuntu识别之前,先在windows下对SD卡进行格式化。
ubuntu识别SD卡步骤:
虚拟机-》可移动设备-》读卡器的名字-》连接
读卡器或者电脑是USB3.0的接口:
虚拟机-》设置-》USB控制器-》USB兼容性:--》USB3.0
3》进入到sdtool目录下
s5p6818-sdmmc.sh:烧写ubootpak.bin到SD卡中的脚本文件
ubootpak.bin:自己编译生成的u-boot的镜像
使用我们自己制作的ubootpak.bin文件替换
sdtool目录下的ubootpak.bin文件。
4》烧写ubootpak.bin文件到SD卡中
在ubuntu的终端中执行以下命令
sudo ./s5p6818-sdmmc.sh /dev/sdb ubootpak.bin
/dev/sdb : SD卡在dev目录下的设备文件
执行以上命令出现以下内容,表示制作成功:
669+1 records in
670+0 records out
343040 bytes (343 kB) copied, 0.00605781 s, 56.6 MB/s
^_^ The image is fused successfully
5》测试SD卡是否成功烧写uboot的镜像
1. 开发板断电,
2. 将SD卡插到开发板的SD卡槽上
3. 设置开发板的启动方式为SD卡启动:查看拨码开关上边的表格
拨码开关
1 OFF
2 OFF
3 OFF
4. 开发板上电
注意:
1. 格式化SD卡,格式化为Fat32格式
在ubuntu中格式化使用fdisk命令。
2. SD卡上的开关拨到lock位置,
如果拨到Lock的对立面,SD卡会写保护。
s5p6818-sdmmc.sh脚本文件分析:
dd if="${xboot}" of="${dev}" bs=512 seek=1 conv=sync
dd:数据烧写命令
xboot=ubootpak.bin
dev=/dev/sdb
if:输入文件 (input file)
of:输出文件 (output file)
bs:大写是512字节
seek:偏移seek*bs大小空间
conv=sync:同步
通过windows系统烧写xin_ubootpak.bin到SD卡中
通过windows系统烧写xin_ubootpak.bin到SD卡中
使用windows下的工具:
系统移植\系统移植资料\工具\ImageWriter.7z
解压缩之后,双击打开工具:Win32DiskImager.exe
1. 首先得到windows版本的ubootpak.bin
在ubuntu版本的ubootpak.bin文件前边添加512字节的占位,
跳过SD的前边512字节的分区表。
dd if=/dev/zero of=512B bs=512 count=1
chmod 777 512B
cat 512B ubootpak.bin > win_ubootpak.bin
拷贝win_ubootpak.bin到windows文件夹中
2. 将SD卡插到PC上,可以使用PC自带的SD卡卡槽
打开Win32DiskImager.exe,选择SD卡的盘符,
选择要写到SD卡中的win_ubootpak.bin文件,
单击write,就可以写入到SD卡中。
3. 测试SD卡是否制作成功。
烧写ubootpak.bin到EMMC(flash)中
烧写ubootpak.bin到EMMC(flash)中
前提:SD卡启动盘必须制作好,前边已经完成。
通过SD卡的方式启动uboot,并进入uboot的交互界面。
思路:ubootpak.bin烧写到EMMC中的思路.png
1. 通过SD卡的方式启动uboot,并进入uboot的交互界面。
2. 使用tftp命令将ubootpak.bin文件烧写到内存中
先将ubootpak.bin拷贝到tftpboot目录下
cp ubootpak.bin ~/tftpboot/
tftp 0x41000000 ubootpak.bin
将ubootpak.bin烧写到内存的0x41000000地址中
3. 将内存中的ubootpak.bin使用update_mmc命令烧写到EMMC中
update_mmc <dev no> <type> <mem> <addr> <length>
- type : 2ndboot | boot | raw | part
<dev no>:设备号 EMMC设备号为:2
<type>:类型 2ndboot
<mem>:从内存的哪个地址开始进行数据搬移
<addr>:搬移到EMMC的起始地址,以字节为单位
<length>:搬移数据的长度,以字节为单位
具体长度要看ubootpak.bin大小
pri打印环境变量有以下信息:
flash=mmc,2:ubootpak:2nd:0x200,0x78000;
flash=mmc,2:2ndboot:2nd:0x200,0x4000;
update_mmc 2 2ndboot 0x41000000 0x200 0x78000
4. 测试是否烧写成功
1. 开发板断电,
2. 切换到EMMC的启动方式
拨码开关
1 ON
2 OFF
3 ON
3. 开发板上电
uboot中mmc命令的使用
uboot中mmc命令的使用
1》mmc info - display info of the current MMC device
查看当前mmc设备的信息
2》mmc read addr blk# cnt
作用:从MMC中读数据到内存中
addr:内存的起始地址
blk#:MMC块设备的编号,一块是512字节
cnt:个数
从MMC的起始块号为blk的位置读数据到内存的addr为起始地址处,
读cnt块数据的大小
3》mmc write addr blk# cnt
作用:从内存中写数据到MMC中
addr:内存的起始地址
blk#:MMC块设备的编号,一块是512字节
cnt:个数
从内存的addr为起始地址写数据到MMC的blk块号处,
写数据的大小位cnt块。
4》mmc erase blk# cnt
作用:擦除MMC中的数据
blk#:MMC块设备的编号,一块是512字节
cnt:个数
从MMC的blk处开始擦除数据,擦除数据的大小是cnt块。
产品阶段系统部署方式(项目完成)
【产品阶段系统部署方式(项目完成)】
uboot ---》EMMC/SD卡
uImage ---》EMMC/SD卡
ramdisk.img ---》EMMC/SD卡
1. 将uboot镜像烧写到EMMC中(uboot烧写阶段已经完成)
update_mmc
2. 将内核镜像uImage烧写到EMMC中
系统移植\系统移植资料\镜像\uImage
将uImage拷贝到ubuntu的tftpboot目录下
tftp 0x41000000 uImage
mmc write 0x41000000 0x800 0x4000
3. 将根文件系统镜像ramdisk.img烧写到EMMC中
系统移植\系统移植资料\镜像\ramdisk.img
将ramdisk.img拷贝到ubuntu的tftpboot目录下
tftp 0x41000000 ramdisk.img
mmc write 0x41000000 0x20800 0x20800
4. 设置uboot的启动参数
bootcmd bootargs
setenv bootcmd mmc read 0x48000000 0x800 0x4000\;
mmc read 0x49000000 0x20800 0x20800\;
bootm 0x48000000 0x49000000
setenv bootargs root=/dev/ram rw
initrd=0x49000040,0x1000000
rootfstype=ext4 init=/linuxrc
console=ttySAC0,115200
saveenv
解析:
root=/dev/ram :从内存中挂载根文件系统
rw :对根文件系统具有读写的权限
initrd=0x49000040,0x1000000
挂载根文件系统的起始地址和大小
跳过根文件系统的64字节的头部信息。
rootfstype=ext4 :根文件系统的类型
init=/linuxrc
console=ttySAC0,115200
开发板的内存是1G大小,寻址空间是
0x4000_0000 - 0x8000_0000
系统的部署
开发阶段系统的部署
u-boot镜像 : EMMC/SD/TF
linux内核镜像 : tftp服务下载到内存中
根文件系统 : nfs服务从服务器端去挂载
setenv bootargs root=/dev/nfs nfsroot=192.168.2.149:/home/topeet/nfs/rootfs rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.2.213
setenv bootcmd tftp 48000000 uImage\;bootm 48000000
产品阶段系统的部署
u-boot镜像 : EMMC/SD/TF
linux内核镜像 : EMMC/SD/TF
根文件系统 : EMMC/SD/TF
setenv bootcmd mmc read 0x48000000 0x800 0x4000\;mmc read 0x49000000 0x20800 0x20800\;bootm 0x48000000 0x49000000
setenv bootargs root=/dev/ram rw initrd=0x49000040,0x1000000 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200
uboot启动过程主要做了什么?
uboot启动过程主要做了什么?
分析uboot启动过程中,代码的执行主要做什么。
ubootpak.bin的程序的入口代码(第一行代码)
1. 打开uboot源码顶层目录的u-boot.lds链接脚本文件
8 .text :
9 {
10 *(.__image_copy_start)
代码段的第一个文件
11 arch/arm/cpu/slsiap/s5p6818/start.o (.text*)
12 arch/arm/cpu/slsiap/s5p6818/vectors.o (.text*)
13 *(.text*)
14 }
2. 打开arch/arm/cpu/slsiap/s5p6818/start.S
构建异常向量表
20 .globl _stext
21 _stext:
22 b reset
23 ldr pc, _undefined_instruction
24 ldr pc, _software_interrupt
25 ldr pc, _prefetch_abort
26 ldr pc, _data_abort
27 ldr pc, _not_used
28 ldr pc, _irq
29 ldr pc, _fiq
3. 通过b reset跳转到reset标签处
78 reset:
保存uboot的启动参数
79 bl save_boot_params
80 /*
81 * set the cpu to SVC32 mode
82 */
切换CPU进入SVC模式
83 mrs r0, cpsr
84 bic r0, r0, #0x1f
85 orr r0, r0, #0xd3
86 msr cpsr,r0
87 禁止看门狗
88 /* disable watchdog */
89 ldr r0, =0xC0019000
90 mov r1, #0
91 str r1, [r0]
禁止MMU和catch
95 bl cpu_init_cp15
获取CPUID,初始锁相环,选择器,内存
96 bl cpu_init_crit
252 ENTRY(cpu_init_crit)
259 b lowlevel_init @ go setup pll,mux,memory
260 ENDPROC(cpu_init_crit)
实现uboot的自搬移的过程,从flash中搬移到内存中
100 relocate_to_text:
101 /*
102 * relocate u-boot code on memory to text base
103 * for nexell arm core (add by jhkim)
104 */
105 adr r0, _stext /* r0 <- current position of code */
106 ldr r1, TEXT_BASE /* test if we run from flash or RAM */
107 cmp r0, r1 /* don't reloc during debug */
108 beq clear_bss
109
110 ldr r2, _bss_start_ofs
111 add r2, r0, r2 /* r2 <- source end address */
112
113 copy_loop_text:
114 ldmia r0!, {r3-r10} /* copy from source address [r0] */
115 stmia r1!, {r3-r10} /* copy to target address [r1] */
116 cmp r0, r2 /* until source end addreee [r2] */
117 ble copy_loop_text
118
119 ldr r1, TEXT_BASE /* restart at text base */
120 mov pc, r1
// 清除BSS段
122 clear_bss:
123 #ifdef CONFIG_MMU_ENABLE
124 bl mmu_turn_on
125 #endif
126 ldr r0, _bss_start_ofs
127 ldr r1, _bss_end_ofs
128 ldr r4, TEXT_BASE /* text addr */
129 add r0, r0, r4
130 add r1, r1, r4
131 mov r2, #0x00000000 /* clear */
132
133 clbss_l:str r2, [r0] /* clear loop... */
134 add r0, r0, #4
135 cmp r0, r1
136 bne clbss_l
// 初始化C代码运行所需的栈空间
138 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
139 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
140 sub sp, #GD_SIZE /* allocate one GD above SP */
141 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
142 mov r9, sp /* GD is above SP */
143 mov r0, #0
// 全局数据结构体类型变量的初始化
144 bl board_init_f
// 板子硬件初始化函数
160 ldr pc, =board_init_r /* this is auto-relocated! */
arch/arm/lib/board.c
710 for (;;) {
711 main_loop(); // 死循环
712 }
82 s = bootdelay_process(); 获取倒计时的时间
83 if (cli_process_fdt(&s)) 倒计时减到0之前按下任意键,进入交互模式
84 cli_secure_boot_cmd(s); 交互的程序
85
86 autoboot_command(s); 自启动的程序
内核源码配置和编译的详细过程
内核源码配置和编译的详细过程
1> 配置交叉编译工具链,打开内核源码顶层目录的Makefile,
将以下内容:
195 ARCH ?=
196 CROSS_COMPILE ?=
修改为:
195 ARCH ?= arm
196 CROSS_COMPILE ?= arm-none-linux-gnueabi-
2> 清除中间文件
make clean / distclean
3> 配置内核源码支持fs6818硬件平台
make fs6818_defconfig
4> 通过菜单选项的方式对内核进行配置
make menuconfig
5> 编译内核生成uImage的内核镜像文件
make -j2 uImage
或者make -j4 uImage
或者make uImage
打印以下信息表示编译成功:
Image Name: Linux-3.4.39-farsight
Created: Mon Jul 20 15:09:28 2020
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5391608 Bytes = 5265.24 kB = 5.14 MB
Load Address: 40008000
Entry Point: 40008000
uImage内核镜像在一下目录中:
Image arch/arm/boot/uImage is ready
问题1:make menuconfig
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
原因:
终端字体太大,缩小终端的字体
问题2:make menuconfig
第一次使用make menuconfig 需要安装图形化界面的工具
配置之前需要安装图形图(make meuconfig):
sudo apt-get install libncurses5-dev
问题3:make uImage
在编译的过程中可能出现如下错误:
"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,
拷贝到到ubuntu的/usr/bin目录下:
sudo cp ~/uboot源码目录/tools/mkimage /usr/bin
uboot目录 ubuntu目录
再次make uImage重新编译内核即可。
测试生成的uImage内核镜像文件是否可以使用
1》拷贝arch/arm/boot/目录下的uImage文件到tftpboot目录下
2》设置开发板的系统启动方式
开发阶段系统的部署和自启动的模式
tftp 下载内核
nfs挂载根文件系统
bootcmd
bootargs
3》系统启动成功,说明内核编译成功
make fs6818_defconfig命令执行过程详解
make fs6818_defconfig命令执行过程详解
1. 打开内核源码顶层目录的Makefile文件,
搜索fs6818_defconfig,没有搜索到;
搜索%config,搜索到一下信息
491 %config: scripts_basic outputmakefile FORCE
492 $(Q)mkdir -p include/linux include/config
493 $(Q)$(MAKE) $(build)=scripts/kconfig $@
$@ : 目标
$^ :所有的依赖
$< :第一个依赖
解析:
Q = @
mkdir -p include/linux include/config
make -f scripts/Makefile.build obj=scripts/kconfig fs6818_defconfig
进入scripts/kconfig目录下执行make fs6818_defconfig
2. 打开scripts/kconfig目录下的Makefile文件
搜索%_defconfig,得到以下信息
95 %_defconfig: $(obj)/conf
96 $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
解析:
scripts/kconfig/conf --defconfig=arch/arm/configs/fs6818_defconfig Kconfig
使用file命令查看scripts/kconfig目录下conf文件的类型
file scripts/kconfig/conf
可知conf文件是一个elf可执行文件
通过以上分析可知,conf文件根据arch/arm/configs/
目录下的fs6818_defconfig默认配置文件和内核源码
顶层目录的Kconfig文件生成.config文件。
make menuconfig执行过程详解
make menuconfig执行过程详解
1. 搜索menuconfig,没有搜索到;
搜索%config,搜索到一下信息
491 %config: scripts_basic outputmakefile FORCE
492 $(Q)mkdir -p include/linux include/config
493 $(Q)$(MAKE) $(build)=scripts/kconfig $@
解析:
Q = @
mkdir -p include/linux include/config
make -f scripts/Makefile.build obj=scripts/kconfig menuconfig
进入scripts/kconfig目录下执行make menuconfig
2. 打开scripts/kconfig目录下的Makefile文件
搜索menuconfig,得到以下信息
20 menuconfig: $(obj)/mconf
21 $< $(Kconfig)
解析:
scripts/kconfig/mconf Kconfig
使用file命令查看scripts/kconfig目录下mconf文件的类型
file scripts/kconfig/mconf
可知mconf文件是一个elf可执行文件
mconf根据内核源码顶层目录的Kconfig文件生成
图形化界面的菜单选项配置界面。
3. 打开内核源码顶层目录的Kconfig文件
5 mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
6
7 config SRCARCH
8 string
9 option env="SRCARCH"
10
11 source "arch/$SRCARCH/Kconfig"
解析:
mainmenu : 主菜单
语法格式:mainmenu "主菜单名字"
source:包含下一级子菜单对应的Kconfig文件路径
语法格式: source "下一级子菜单的Kconfig路径"
打开arch/arm/目录下的Kconfig文件。
Kconfig文件作用?
Kconfig用于存放菜单选项的配置信息。
1. 主菜单
包含:子菜单,菜单选项
2. 子菜单:
包含:子菜单,菜单选项
3. 菜单选项
版权声明:本文为Linux_zhicheng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。