X-011-UBOOT-使用bootm命令启动kernel(Bubblegum-96平台)
作者:wowo 发布于:2016-9-9 22:18 分类:X Project
1. 前言
我们在“X-010-UBOOT-使用booti命令启动kernel(Bubblegum-96平台)”中介绍了使用u-boot booti指令加载并运行ARM64 Image格式kernel的方法。与此同时,我们在“u-boot FIT image介绍”介绍了一种新的uImage(u-boot Image)格式----FIT uImage。本文将基于这两篇文章,介绍FIT uImage的编译、启动等方法,目的有二:
1)作为“u-boot FIT image介绍”的实践篇。
2)以后“X Project”和u-boot有关的image格式,将统一使用FIT uImage。
2. FIT uImage的生成
2.1 向unify kernel的目标迈进
“u-boot FIT image介绍”中提到了,为了实现unify kernel的目标,需要为不同的平台编译同一个kernel image。换句话说,就是要有相同的kernel defconfig文件。因此,以Bubblegum-96平台为例,我们要建立统一的defconfig文件----xprj_defconfig,步骤如下:
cd ./linux
make ARCH=arm64 allnoconfig
# 直接保存并退出
cp .config arch/arm64/configs/xprj_defconfig# 生成的deconfig文件可参考
# https://github.com/wowotechX/linux/commit/1d9204207e91ffc21b845552db5756512274a37d
注1:记得我们在“X-010-UBOOT-使用booti命令启动kernel(Bubblegum-96平台)”中,为了删减kernel默认的配置项,累的死去活来的,其实有简便方法----make allnoconfig,会生成指定平台下能work的最小kernel。
与此同时,修改“X Project”的编译脚本,ARM64架构的版型,统一使用xprj_defconfig,如下:
diff --git a/Makefile b/Makefile
index b51d943..bd25f83 100644
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,10 @@ OUT_DIR=$(BUILD_DIR)/out
UBOOT_OUT_DIR=$(OUT_DIR)/u-boot
KERNEL_OUT_DIR=$(OUT_DIR)/linux+ifeq ($(BOARD_ARCH), arm64)
+KERNEL_DEFCONFIG=xprj_defconfig
+endif
+
all: uboot kernelclean: dfu-clean uboot-clean kernel-clean
@@ -59,13 +63,13 @@ uboot-clean:
#
kernel-config:
mkdir -p $(KERNEL_OUT_DIR)
- cp -f $(KERNEL_DIR)/arch/$(BOARD_ARCH)/configs/$(BOARD_NAME)_defconfig $(KERNEL_OUT_DIR)/.config
+ cp -f $(KERNEL_DIR)/arch/$(BOARD_ARCH)/configs/$(KERNEL_DEFCONFIG) $(KERNEL_OUT_DIR)/.config
make -C $(KERNEL_DIR) KBUILD_OUTPUT=$(KERNEL_OUT_DIR) ARCH=$(BOARD_ARCH) menuconfig
- cp -f $(KERNEL_OUT_DIR)/.config $(KERNEL_DIR)/arch/$(BOARD_ARCH)/configs/$(BOARD_NAME)_defconfig
+ cp -f $(KERNEL_OUT_DIR)/.config $(KERNEL_DIR)/arch/$(BOARD_ARCH)/configs/$(KERNEL_DEFCONFIG)kernel:
mkdir -p $(KERNEL_OUT_DIR)
- make -C $(KERNEL_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(KERNEL_OUT_DIR) ARCH=$(BOARD_ARCH) $(BOARD_NAME)_defconfig
+ make -C $(KERNEL_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(KERNEL_OUT_DIR) ARCH=$(BOARD_ARCH) $(KERNEL_DEFCONFIG)
make -C $(KERNEL_DIR) CROSS_COMPILE=$(CROSS_COMPILE) KBUILD_OUTPUT=$(KERNEL_OUT_DIR) ARCH=$(BOARD_ARCH) Image dtbskernel-clean:
具体可参考“https://github.com/wowotechX/build/commit/bba23bf1d63aabb797400185e4d6d764b651e3b6”。
2.2 基于新生成的kernel config,打开对bubblegum的支持(为了编译dtb文件)
CONFIG_ARCH_OWL=y
具体可参考“X-010-UBOOT-使用booti命令启动kernel(Bubblegum-96平台)”中有关的描述,patch文件如下:
https://github.com/wowotechX/linux/commit/9a4169ba5187d748a99c11d524bcd1238fd92408
2.3 增加.its文件
参考u-boot的例子,新建一个.its文件,名称为fit_uImage.its,如下:
cd ./build
cp ../u-boot/doc/uImage.FIT/kernel_fdt.its fit_uImage.its
根据x project的实际情况,修改its文件,增加Kernel image和dtb文件两个节点,如下(注意,这个its文件是有问题的,后面调试的时候再改):
https://github.com/wowotechX/build/blob/b71ccd4c7530ec6c5aed7bab0cbd74f48f1fe48e/fit_uImage.its
与此同时,修改编译脚本,加入uImage的编译命令(make uImage),借助u-boot/tools目录下的mkimage工具,编译uImage:
+UIMAGE_ITS_FILE=$(BUILD_DIR)/fit_uImage.its
+UIMAGE_ITB_FILE=$(OUT_DIR)/xprj_uImage.itb
…
+uImage:
+ mkdir -p $(OUT_DIR)
+ $(UBOOT_OUT_DIR)/tools/mkimage -f $(UIMAGE_ITS_FILE) $(UIMAGE_ITB_FILE)
其中fit_uImage.its位于当前build目录;xprj_uImage.itb是将要生成的FIT uImage文件,位于./build/out目录;mkimage工具位于u-boot/tools目录,编译u-boot之后会自定生成。
2.4 编译生成FIT uImage
在build目录执行make kernel,生成kernel image和对应的dtb文件之后,再执行make uImage,即可将它们打包成FIT uImage。然后我们可以使用mkimage查看新生成的uImage的信息,如下:
pengo@ubuntu:~/work/xprj/build$ ./out/u-boot/tools/mkimage -l out/xprj_uImage.itb
FIT description: U-Boot uImage source file for X project
Created: Sat Sep 3 00:05:17 2016
Image 0 (kernel@arm64)
Description: Unify(TODO) ARM64 Linux kernel
Created: Sat Sep 3 00:05:17 2016
Type: Kernel Image
Compression: uncompressed
Data Size: 1229056 Bytes = 1200.25 kB = 1.17 MB
Architecture: ARM
OS: Linux
Load Address: 0x00080000
Entry Point: 0x00080000
Hash algo: crc32
Hash value: ff814746
Hash algo: sha1
Hash value: db4b1b6f40827d88b2e754e795c432cddf41f9bf
Image 1 (fdt@bubblegum96)
Description: Flattened Device Tree blob for Bubblegum-96
Created: Sat Sep 3 00:05:17 2016
Type: Flat Device Tree
Compression: uncompressed
Data Size: 181 Bytes = 0.18 kB = 0.00 MB
Architecture: ARM
Hash algo: crc32
Hash value: 8ee556df
Hash algo: sha1
Hash value: fd590fa50b2f79c18c736cfb410da70feadbfdaa
Default Configuration: 'conf@bubblegum96'
Configuration 0 (conf@bubblegum96)
Description: Boot Linux kernel with FDT blob
Kernel: kernel@arm64
FDT: fdt@bubblegum96
Image信息和fit_uImage.its中所描述的完全一致,说明如下:
包含两个Image:
Image0,名称为kernel@arm64,类型是“Kernel Image”,Architecture为“ARM”,没有压缩,Load和Entry都是“0x00080000”;
Image1,名称为fdt@bubblegum96,类型是“Flat Device Tree”,Architecture为“ARM”,没有压缩,Load和Entry未指定。包含一个Configuration,名称为conf@bubblegum96,该Configuration共包括“kernel@arm64”和“fdt@bubblegum96”两个Image。
默认的Configuration就是conf@bubblegum96。
3. FIT uImage的启动
3.1 使用bootm启动FIT uImage
生成“xprj_uImage.itb”之后,我们可以使用DFU工具将它下载到板子的DDR中,并使用bootm命令启动它(有关bootm命令的支持,可参考“X-010-UBOOT-使用booti命令启动kernel(Bubblegum-96平台)”),如下[1]:
# 执行spl image,初始化DDR
sudo ../tools/dfu/dfu bubblegum 0xe406b200 ../tools/actions/splboot.bin 1# 将xprj_uImage.itb下载到DDR的收地址(最后一个参数表示不执行)
sudo ../tools/dfu/dfu bubblegum 0x0 ./out/xprj_uImage.itb 0#下载并执行u-boot
sudo ../tools/dfu/dfu bubblegum 0x11000000 out/u-boot/u-boot-dtb.bin 1
启动到u-boot命令行执行,以xprj_uImage.itb所在的地址为参数,执行bootm命令,不幸的失败了,错误信息如下:
[xprj]# bootm 0x0
## Current stack ends at 0x3ffc14e0 * kernel: cmdline image address = 0x00000000
## Loading kernel from FIT Image at 00000000 ...
No configuration specified, trying default...
Found default configuration: 'conf@bubblegum96'
Using 'conf@bubblegum96' configuration
Trying 'kernel@arm64' kernel subimage
Description: Unify(TODO) ARM64 Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x000000ec
Data Size: 1229056 Bytes = 1.2 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00080000
Entry Point: 0x00080000
Hash node: 'hash@1'
Hash algo: crc32
Hash value: ff814746
Hash len: 4
Hash node: 'hash@2'
Hash algo: sha1
Hash value: db4b1b6f40827d88b2e754e795c432cddf41f9bf
Hash len: 20
Verifying Hash Integrity ... crc32 error!
Bad hash value for 'hash@1' hash node in 'kernel@arm64' image node
Bad Data Hash
ERROR: can't get kernel image!
Command failed, result=1
3.2 删掉.its文件中的hash节点
原来hash值错了,好像fit_uImage.its指定了hash节点,但是我们没有特意的为两个Image计算hash值,简单起见,先删掉吧,如下:
kernel@arm64 {
description = "Unify(TODO) ARM64 Linux kernel";
data = /incbin/("./out/linux/arch/arm64/boot/Image");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0x00080000>;
entry = <0x00080000>;
};
fdt@bubblegum96 {
description = "Flattened Device Tree blob for Bubblegum-96";
data = /incbin/("./out/linux/arch/arm64/boot/dts/actions/s900-bubblegum.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
};
重复3.1的步骤,再来一次,还有问题:
xprj]# bootm 0x0
## Current stack ends at 0x3ffc14e0 * kernel: cmdline image address = 0x00000000
## Loading kernel from FIT Image at 00000000 ...
No configuration specified, trying default...
Found default configuration: 'conf@bubblegum96'
Using 'conf@bubblegum96' configuration
Trying 'kernel@arm64' kernel subimage
Description: Unify(TODO) ARM64 Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x000000ec
Data Size: 1229056 Bytes = 1.2 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00080000
Entry Point: 0x00080000
Verifying Hash Integrity ... OK
Unsupported Architecture
ERROR: can't get kernel image!
Command failed, result=1
3.3 将架构修改为“arm64”
“Unsupported Architecture”,不支持的架构?在u-boot的source code中,查找一下架构有关的代码,原来要把arch改为arm64,如下:
kernel@arm64 {
description = "Unify(TODO) ARM64 Linux kernel";
data = /incbin/("./out/linux/arch/arm64/boot/Image");
type = "kernel";
arch = "arm64";
os = "linux";
compression = "none";
load = <0x00080000>;
entry = <0x00080000>;
};
fdt@bubblegum96 {
description = "Flattened Device Tree blob for Bubblegum-96";
data = /incbin/("./out/linux/arch/arm64/boot/dts/actions/s900-bubblegum.dtb");
type = "flat_dt";
arch = "arm64";
compression = "none";
};
重复3.1的步骤,还有问题:
[xprj]# bootm 0x0
## Current stack ends at 0x3ffc14e0 * kernel: cmdline image address = 0x00000000
## Loading kernel from FIT Image at 00000000 ...
No configuration specified, trying default...
Found default configuration: 'conf@bubblegum96'
Using 'conf@bubblegum96' configuration
Trying 'kernel@arm64' kernel subimage
Description: Unify(TODO) ARM64 Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x000000ec
Data Size: 1229056 Bytes = 1.2 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00080000
Entry Point: 0x00080000
Verifying Hash Integrity ... OK
kernel data at 0x000000ec, len = 0x0012c100 (1229056)
* ramdisk: using config 'conf@bubblegum96' from image at 0x00000000
* ramdisk: no 'ramdisk' in config
Loading Kernel Image ... OK
kernel loaded at 0x00080000, end = 0x001ac100
images.os.start = 0x0, images.os.end = 0x12c8bb
images.os.load = 0x80000, load_end = 0x1ac100
ERROR: new format image overwritten - must RESET the board to recover
resetting ...
Command failed, result=-1
3.4 重新规划内存的使用
原来在xprj_uImage.itb中,我们指定Kernel image的load地址是0x80000,也就是说,u-boot在boot kernel之前,需要将kernel Image从itb文件中加载到load地址。但是,我们将itb文件放到0x0地址了,发生了覆盖,u-boot不允许,所以我们需要重新规划一下内存的使用,如下:
1)u-boot要在0x11000000(272M的位置)执行,并被relocated到DDR的底端。
2)kernel要在0x0执行,假设给它分配100M(0x6400000)的代码空间
3)那么,我们可以把itb文件上传到0x6400000处:
sudo ../tools/dfu/dfu bubblegum 0xe406b200 ../tools/actions/splboot.bin 1
sudo ../tools/dfu/dfu bubblegum 0x6400000 ./out/xprj_uImage.itb 0
sudo ../tools/dfu/dfu bubblegum 0x11000000 out/u-boot/u-boot-dtb.bin 1
再次执行bootm,成功了:
[xprj]# bootm 0x6400000
## Current stack ends at 0x3ffbc4e0 * kernel: cmdline image address = 0x06400000
## Loading kernel from FIT Image at 06400000 ...
No configuration specified, trying default...
Found default configuration: 'conf@bubblegum96'
Using 'conf@bubblegum96' configuration
Trying 'kernel@arm64' kernel subimage
Description: Unify(TODO) ARM64 Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x064000ec
Data Size: 1229056 Bytes = 1.2 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00080000
Entry Point: 0x00080000
Verifying Hash Integrity ... OK
kernel data at 0x064000ec, len = 0x0012c100 (1229056)
* ramdisk: using config 'conf@bubblegum96' from image at 0x06400000
* ramdisk: no 'ramdisk' in config
* fdt: using config 'conf@bubblegum96' from image at 0x06400000
## Checking for 'FDT'/'FDT Image' at 06400000
## Loading fdt from FIT Image at 06400000 ...
Using 'conf@bubblegum96' configuration
Trying 'fdt@bubblegum96' fdt subimage
Description: Flattened Device Tree blob for Bubblegum-96
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x0652c2b8
Data Size: 181 Bytes = 181 Bytes
Architecture: AArch64
Verifying Hash Integrity ... OK
Can't get 'load' property from FIT 0x06400000, node: offset 1229352, name fdt@bubblegum96 (FDT_ERR_NOTFOUND)
Booting using the fdt blob at 0x652c2b8
of_flat_tree at 0x0652c2b8 size 0x000000b5
Initial value for argc=3
Final value for argc=3
Loading Kernel Image ... OK
kernel loaded at 0x00080000, end = 0x001ac100
using: FDT
## initrd_high = 0x3fffffff, copy_to_ram = 1
ramdisk load start = 0x00000000, ramdisk load end = 0x00000000
## device tree at 000000000652c2b8 ... 000000000652c36c (len=12469 [0x30B5])
Loading Device Tree to 000000003ffb8000, end 000000003ffbb0b4 ... OK
Initial value for argc=3
Final value for argc=3
## Transferring control to Linux (at address 80000)...
Starting kernel ...
从日志上可以看出:u-boot将kernel image加载到了load address(0x00080000)到0x001ac100的位置;由于我们没有指定FDT的加载地址,u-boot将它加载到了将FDT加载到了memory的高地址(0x3ffb8000)。
3.5 点亮LED,确认kernel执行成功
参考“X-010-UBOOT-使用booti命令启动kernel(Bubblegum-96平台)”有关的说明,插入点亮LED的代码,确认OK。
4. 总结和思考
经过上面的实践,我们得出如下的经验:
1)对uImage中某一个Image来说,u-boot会将它重新load到“load address“,因此,需要确保load address和uImage所在的memory区域不能重叠。
2)对于那些可被指定的Image,u-boot会跳转到”entry point“处执行,例如linux kernel。对ARM64而言,”load address“和”entry address“是相同的。
另外,其实FIT uImage离unify kernel的目标还有一段距离,因为当前还有如下的不足:
1)虽然可以指定多个Image,但只要其中的某一个(或者多个)Image不存在,make uImage就无法执行成功。
2)以ARM64为例,假如kernel Image都是同一个,区别是不同版型的load address和entry point不同,要怎么办?.its的语法并没有照顾到这种场景。
3)u-boot将Image文件从.itb文件解除之后,会重新把它们copy到一个新的地址(load address),这等于凭空多了一次memory copy,这些动作本来可以由bootloader在从存储器中copy的时候一次性完成,这岂不是一种浪费?
希望在后续的实践过程中,逐渐解决上述问题。
5. 参考文档
[1] https://github.com/wowotechX/doc/blob/master/README.bubblegum96
原创文章,转发请注明出处。蜗窝科技,www.wowotech.net。
标签: arm64 u-boot uboot bootm fit uImage its itb

评论:
2016-09-10 17:29
然后
“虽然可以指定多个Image,但只要其中的某一个(或者多个)Image不存在,make uImage就无法执行成功。”
所以,我暂时就先建了一个目录its,然后搞个fit_uImage_tiny210.its给tiny210用,不然没法搞。
等wowo找到解决办法了再改哈哈。
2016-09-10 21:10
关于FIT的方式,我这里的表述更多的是指ARM64,对于arm,其实代价蛮大的,先不用也行。
后面可以考虑.its文件动态生成的方式~~
功能
最新评论
- wangjing
写得太好了 - wangjing
写得太好了! - DRAM
圖面都沒辦法顯示出來好像掛點了。 - Simbr
bus至少是不是还有个subsystem? - troy
@testtest:只要ldrex-modify-strex... - gh
Linux 内核在 sparse 内存模型基础上实现了vme...
文章分类
随机文章
文章存档
- 2025年4月(5)
- 2024年2月(1)
- 2023年5月(1)
- 2022年10月(1)
- 2022年8月(1)
- 2022年6月(1)
- 2022年5月(1)
- 2022年4月(2)
- 2022年2月(2)
- 2021年12月(1)
- 2021年11月(5)
- 2021年7月(1)
- 2021年6月(1)
- 2021年5月(3)
- 2020年3月(3)
- 2020年2月(2)
- 2020年1月(3)
- 2019年12月(3)
- 2019年5月(4)
- 2019年3月(1)
- 2019年1月(3)
- 2018年12月(2)
- 2018年11月(1)
- 2018年10月(2)
- 2018年8月(1)
- 2018年6月(1)
- 2018年5月(1)
- 2018年4月(7)
- 2018年2月(4)
- 2018年1月(5)
- 2017年12月(2)
- 2017年11月(2)
- 2017年10月(1)
- 2017年9月(5)
- 2017年8月(4)
- 2017年7月(4)
- 2017年6月(3)
- 2017年5月(3)
- 2017年4月(1)
- 2017年3月(8)
- 2017年2月(6)
- 2017年1月(5)
- 2016年12月(6)
- 2016年11月(11)
- 2016年10月(9)
- 2016年9月(6)
- 2016年8月(9)
- 2016年7月(5)
- 2016年6月(8)
- 2016年5月(8)
- 2016年4月(7)
- 2016年3月(5)
- 2016年2月(5)
- 2016年1月(6)
- 2015年12月(6)
- 2015年11月(9)
- 2015年10月(9)
- 2015年9月(4)
- 2015年8月(3)
- 2015年7月(7)
- 2015年6月(3)
- 2015年5月(6)
- 2015年4月(9)
- 2015年3月(9)
- 2015年2月(6)
- 2015年1月(6)
- 2014年12月(17)
- 2014年11月(8)
- 2014年10月(9)
- 2014年9月(7)
- 2014年8月(12)
- 2014年7月(6)
- 2014年6月(6)
- 2014年5月(9)
- 2014年4月(9)
- 2014年3月(7)
- 2014年2月(3)
- 2014年1月(4)
2016-09-15 19:05
尝试做了一个自动生成its脚本,在tiny210验证过是可以用的。您有空的时候可否帮忙在bubblegum平台上试一下。
测试步骤如下
(1)build同步一下切换到tiny210分支
(2)config.mk里面改一下对应的配置
BOARD_NAME=bubblegum
BOARD_ARCH=arm64
UIMAGE_LOADADDR=0x00080000
UIMAGE_ENTRYADDR=0x00080000
DTB_NAME=actions/s900-bubblegum.dtb
(3)执行make kernel-img
(4)在out/fit目录下会生成fit_uImage.its xprj_uImage.itb。然后帮忙测试一下这个xprj_uImage.itb在您的bubblegum这个板子上是否可用?
十分感谢~