最近在移植最新的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输出。