最近在移植最新的longterm内核5.15到ipq5018平台。改动是参考QSDK官方内核仓库:
https://git.codelinaro.org/clo/qsdk/oss/kernel/linux-ipq-5.4.git
分支是origin/NHSS.QSDK.12.1.r3。
移植好后,创建一个itb镜像。
$ cat targets/ipq50xx_32/fit-image.its
/dts-v1/;
/ {
description = "X-router Fit Image";
#address-cells = <1>;
images {
kernel {
description = "Linux kernel 5.15.38";
data = /incbin/("../linux-5.15.38/arch/arm/boot/zImage");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0x41208000>;
entry = <0x41208000>;
hash-1 {
algo = "sha1";
};
};
fdt {
description = "Flattened Device Tree blob";
data = /incbin/("../linux-5.15.38/arch/arm/boot/dts/ipq5018-mp02.1.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
hash-1 {
algo = "sha1";
};
};
};
configurations {
default = "config-1";
config-1 {
description = "IPQ50xx Linux kernel with FDT blob and initramfs";
kernel = "kernel";
fdt = "fdt";
};
};
};
编译itb:
$ mkimage -f fit-image.its ipq50xx_32.itb
但是传到设备上启动后没有任何输出
$ tftpboot ipq50xx_32.itb
$ bootm
想到的方法1是我们有个led灯输出。调试arch/arm/boot/compressed/head.S. 加一个led的亮灭。来看执行到哪里了。
如:bl blue_on
led的控制,只要读写寄存器就可以了,可以用c写一个blue_on/blue_off函数,不带参数,在汇编里面直接bl即可。
最终定位到执行:__armv7_mmu_cache_on
mcr p15, 0, r0, c1, c0, 0
这条指令的时候,没有往下执行了。
后来查看代码,发现是有一处改动,合入有问题,直接合入了,但是5.15不能直接合入:
/* Determine final kernel image address. */
- add r4, r0, #TEXT_OFFSET
+ ldr r0, =TEXT_OFFSET
+ add r4, r4, r0
#else
这里的本意是 r4 = r0 + TEXT_OFFSET. 由于TEXT_OFFSET的值变化了,不能直接编码进汇编中,所以先load到寄存器。原来的改动是load到r0。的那是5.15应该要load到r4. load到r0的话,变成了:r4 = r4 + TEXT_OFFSET. 所以修改为
/* Determine final kernel image address. */
- add r4, r0, #TEXT_OFFSET
+ ldr r4, =TEXT_OFFSET
+ add r4, r4, r0
#else
另外一种DEBUG方法是,开启串口输出,开启写列选项:
开启后
CONFIG_DEBUG_LL_INCLUDE="debug/msm.S"
arch/arm/include/debug/msm.S
这个汇编包含了uart的输出接口。这样在compressed里面的debug.S会include这个文件,来实现uart输出。