BB-black开发板[Linux arm-v8]

TQ2440改成设备树启动kernel5.4成功--Apple的

2021-01-06  本文已影响0人  applecai

一,前言,

uboot已经移植成功了,接着就是要用kernel 5.4,而且要用设备树。一开始网上看了下,评估下难度,看上去不难。然后我就开始了menuconfig参考smkd2410_defconfig,然后设备树都是基于smdk2410-s3c2416.dts修改。

二,问题记录

  1. uboot需要支持设备树。
    参考网上教程在include/configs/smdk2440.h文件添加:
    #define CONFIG_OF_LIBFDT make之后发现:
    image-fdt.c:194: undefined reference to `set_working_fdt_addr’
    发现set_working_fdt_addr是在fdt.c文件里,检查发现是没有被编译,查看Makefile可知需要添加配置:
    make menuconfig
    选上:Library routines --->[ ] Enable the FDT library。同时把smdk2440.h中的#define CONFIG_OF_LIBFDT删除。否则警告重复定义。
    2.start kernel后就没了
Starting kernel ...
Error: unrecognized/unsupported device tree compatible list:
[ 'samsung,s3c2416' 'SMDK2440' ]

Available machine support:

ID (hex)        NAME
000000c1        SMDK2410
00000695        SMDK2416
000007cf        MINI2440
0000016a        SMDK2440

找到源码,添加early_print支持。然后在源码中添加调试信息early_print("match=%s\n",*match);

static const void * __init arch_get_next_mach(const char *const **match)
{
    static const struct machine_desc *mdesc = __arch_info_begin;
    const struct machine_desc *m = mdesc;

    if (m >= __arch_info_end)
        return NULL;

    mdesc++;
    *match = m->dt_compat;
    early_print("match=%s\n",*match);
    return m;
}

可以看出dtb识别大端是正确的,前4个字节为d0 0d fe ed,但是match都是null。

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
  r1=0x000000a8, r2=0x33b14000
  r2[]=d0 0d fe ed 00 00 20 00 00 00 00 48 00 00 15 dc
1
match=(null)
match=(null)
match=(null)
match=(null)

Error: unrecognized/unsupported device tree compatible list:
[ 'samsung,s3c2416' 'SMDK2440' ]

Available machine support:

ID (hex)        NAME
000000c1        SMDK2410
00000695        SMDK2416
000007cf        MINI2440
0000016a        SMDK2440

c文件的.dt_compat数组内容为空?想起来了,搜索下dtb中的root为samsung,s3c2416。对应的c文件名称为mach-s3c2416-dt.o,需要配置CONFIG_MACH_S3C2416_DT,但是我没配置导致的。配置完后,dt_compat能匹配到设备树中的samsung,s3c2416。

## Transferring control to Linux (at address 30008000)...

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
  r1=0x000000a8, r2=0x33b14000
  r2[]=d0 0d fe ed 00 00 20 00 00 00 00 48 00 00 15 d0
1
name=Samsung S3C2416 (Flattened Device Tree) Machine model: SMDK2416
setup_arch done

Uncompressing Linux... done, booting the kernel.
  r1=0x000000a8, r2=0x33b14000
  r2[]=d0 0d fe ed 00 00 20 00 00 00 00 48 00 00 15 d0
1
name=Samsung S3C2416 (Flattened Device Tree) match=pXd
  1. 解决了dtb设备问题,但是串口无输出
    由于early_print函数是可以使用的,我就看看卡在哪里,通过main.c的start_kernel函数中慢慢添加,最后添加到do_initialcall函数来打印指针。
do_initcall_level1 fn=0xc070c9bc
do_initcall_level2
do_initcall_level1 fn=0xc070c9c0
do_initcall_level2
do_initcall_level1 fn=0xc070c9c4
ǤbǤbǤbǤbǤbǤbǤbǤbǤFfŤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤbǤEffbǤbǤbǤb

arch_call_rest_init();没有运行完,通过在map文件查看c070c9c4地址对应的函数,确认了串口初始化samsung_serial_driver函数的问题。

c070c9bc t __initcall_sysrq_init6
c070c9c0 t __initcall_serial8250_init6
c070c9c4 t __initcall_samsung_serial_driver_init6

然后通过调试发现,运行如下几句后,先打印乱码,然后没了。上面的注释显示通过此次先注释串口clk,然后在pm-callback函数打开。通过先注释如下3行,probe函数能结束,但是do_basic_setup没有走完。但是do_basic_setup看上去没有走完。
//clk_disable_unprepare(ourport->clk);
//if (!IS_ERR(ourport->baudclk))
// clk_disable_unprepare(ourport->baudclk);
修改后输出如下,至少early_print能正常输出。

setup_arch done
kernel_init
do_basic_setup1
do_basic_setup2
s3c24xx_serial_probe
s3c24xx_serial_probe((ptrval)) 0
s3c24xx_serial_probe: initialising port (ptrval)...
s3c24xx_serial_probe: adding port
uart_add_one_port done
done

通过initialcall前后添加的打印函数。发现运行此句后停止c070cb20 t __initcall_clk_disable_unused7s
do_initcall_level1 fn=0xc070cb1c
do_initcall_level2
do_initcall_level1 fn=0xc070cb20
然后在clk_disable_unused函数中添加clk_ignore_unused = true;这样driver/clk/clk.c就不会禁止相关clock。
但是我突然想到do_initiallcall还没有调用的时候,其实应该kernel就有输出的。但是为什么也没有呢?dts我也改过,应该是对的,突然想到是boot参数里面定义了tty1(LCD)显示还是串口显示。所以去检查pri输出发现bootargs为空bootcmd为bootargs的内容。原因我之前先设置为none,重新设置bootargs传入参数console=ttySAC0是必须要有的,就可以解决此问题然后刚刚串口初始化中probe的3行注释还原,clk_ignore_unused = true还是要加的。就成功了哦!

  1. clock配置不对导致的问题
sched_clock: 16 bits at 0 Hz, resolution 0ns, wraps every 0ns
Division by zero in kernel.
CPU: 0 PID: 0 Comm: swapper Tainted: G        W         5.4.61 #41
Hardware name: Samsung S3C2416 (Flattened Device Tree)
Backtrace: 
[<c00198b8>] (dump_backtrace) from [<c0019b2c>] (show_stack+0x18/0x1c)
 r6:00000000 r5:0000ffff r4:00000000
[<c0019b14>] (show_stack) from [<c057a4e4>] (dump_stack+0x20/0x28)
[<c057a4c4>] (dump_stack) from [<c0019a14>] (__div0+0x18/0x20)
[<c00199fc>] (__div0) from [<c0577fdc>] (Ldiv0_64+0x8/0x18)
[<c006f404>] (__clocksource_update_freq_scale) from [<c006f648>] (__clocksource_register_scale+0x18/0xc4)
 r10:00000000 r9:00000002 r8:00000019 r7:00000000 r6:f6300040 r5:c0736934
 r4:c0725584
[<c006f630>] (__clocksource_register_scale) from [<c06f32d0>] (_samsung_pwm_clocksource_init+0x2fc/0x320)
 r5:c0736880 r4:c076cfa8
[<c06f2fd4>] (_samsung_pwm_clocksource_init) from [<c06f3424>] (samsung_pwm_alloc+0x130/0x16c)
 r9:00000001 r8:c05d541c r7:c0686390 r6:c0711008 r5:c3f78668 r4:c076cfa8
[<c06f32f4>] (samsung_pwm_alloc) from [<c06f3474>] (s3c2410_pwm_clocksource_init+0x14/0x1c)
 r10:c0701a30 r9:00000001 r8:c06862ec r7:c070bb50 r6:c0711008 r5:00000000
 r4:c3f78668
[<c06f3460>] (s3c2410_pwm_clocksource_init) from [<c06f2f60>] (timer_probe+0x6c/0xe0)
[<c06f2ef4>] (timer_probe) from [<c06dd5fc>] (time_init+0x34/0x3c)
 r8:00000000 r7:c0743000 r6:c0711000 r5:c0711008 r4:c0701a30
[<c06dd5c8>] (time_init) from [<c06d9c90>] (start_kernel+0x294/0x44c)
[<c06d99fc>] (start_kernel) from [<00000000>] (0x0)
 r10:c0007177 r9:41129200 r8:33b14000 r7:000000a8 r6:00003135 r5:00000053
 r4:c06d9330
clocksource: samsung_clocksource_timer: mask: 0xffff max_cycles: 0x0, max_idle_ns: 0 ns
Console: colour dummy device 80x30
Calibrating delay loop... 1305.80 BogoMIPS (lpj=6529024)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x30008400 - 0x3000847c
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 256 (order: -1, 3072 bytes, linear)
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
s3c2416_dt_machine_init
S3C Power Management, Copyright 2004 Simtec Electronics
S3C2440: Initialising architecture
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Advanced Linux Sound Architecture Driver Initialized.
Division by zero in kernel.
CPU: 0 PID: 1 Comm: swapper Tainted: G        W         5.4.61 #41
Hardware name: Samsung S3C2416 (Flattened Device Tree)
Backtrace: 
[<c00198b8>] (dump_backtrace) from [<c0019b2c>] (show_stack+0x18/0x1c)
 r6:00989680 r5:c0757c80 r4:00000000
[<c0019b14>] (show_stack) from [<c057a4e4>] (dump_stack+0x20/0x28)
[<c057a4c4>] (dump_stack) from [<c0019a14>] (__div0+0x18/0x20)
[<c00199fc>] (__div0) from [<c0577fdc>] (Ldiv0_64+0x8/0x18)
[<c006bbf8>] (tk_setup_internals.constprop.6) from [<c006d384>] (timekeeping_notify+0x84/0xec)
 r10:00000000 r9:c07257c8 r8:c07257c8 r7:800000d3 r6:80000053 r5:c0736934
 r4:c0757c80
[<c006d300>] (timekeeping_notify) from [<c006f104>] (__clocksource_select+0xa0/0x118)
 r8:c0736934 r7:00000000 r6:c0757f30 r5:c0725778 r4:c0736934
[<c006f064>] (__clocksource_select) from [<c06e3850>] (clocksource_done_booting+0x34/0x4c)
 r10:00000000 r9:c0743000 r8:ffffe000 r7:00000000 r6:c06e381c r5:c0711008
 r4:c0725768
[<c06e381c>] (clocksource_done_booting) from [<c000a664>] (do_one_initcall+0x7c/0x1f4)
 r4:c0743000
[<c000a5e8>] (do_one_initcall) from [<c06d9f54>] (kernel_init_freeable+0x10c/0x1c0)
 r8:c070182c r7:c0743000 r6:c070184c r5:000000b2 r4:c070c818
[<c06d9e48>] (kernel_init_freeable) from [<c05927c4>] (kernel_init+0x10/0xec)
 r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c05927b4
 r4:00000000
[<c05927b4>] (kernel_init) from [<c00090e0>] (ret_from_fork+0x14/0x34)
Exception stack(0xc3421fb0 to 0xc3421ff8)
1fa0:                                     00000000 00000000 00000000 00000000
1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
 r4:00000000
clocksource: Switched to clocksource samsung_clocksource_timer

虽然可以继续运行,但是打印这些信息看着就是bug验证。没有timer了。
后来查看了第一个出现此问题的log,最后dump是调用了dump_stack函数。
clk_hw_register->samsung_pll6552_recalc_rate->do_div->__div64_32->__do_div64->__div0
s3c2443_common_clk_init里面些参数到底要改成什么样,我还不清楚。直接设备树修改为2410不行,打印都没了。traps.c中我先注释掉dump_stack。

asmlinkage void __div0(void)
{
    pr_err("Division by zero in kernel.\n");
    dump_stack();
}

6.无法挂载rootfs。VFS: Mounted root都没有打印出来。
添加了dm9000的设备树,网上找的参考,修改了下地址0x20000300和0x20000304

    srom-cs4@20000000 {
        compatible = "simple-bus";
        #address-cells = <1>;
        #size-cells = <1>;
        reg = <0x20000000 0x8000000>;
        ranges;
        ethernet@18000000 {
            compatible = "davicom,dm9000";
            reg = <0x20000300 0x2 0x20000304 0x2>;
            interrupt-parent = <&gpf>;
            interrupts = <7 4>;
            local-mac-address = [00 00 de ad be ef];
            davicom,no-eeprom;
        };
    };

dm9000看上去正常。但是No soundcards found后就不走了。代码又卡到哪里了呢?

NET: Registered protocol family 10
Segment Routing with IPv6
sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
NET: Registered protocol family 17
Loading compiled-in X.509 certificates
dm9000 20000300.ethernet eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
IP-Config: Complete:
     device=eth0, hwaddr=00:00:de:ad:be:ef, ipaddr=192.168.0.17, mask=255.255.255.0, gw=192.168.0.1
     host=192.168.0.17, domain=, nis-domain=(none)
     bootserver=192.168.0.110, rootserver=192.168.0.110, rootpath=
clk: Not disabling unused clocks
ALSA device list:
  No soundcards found.

添加printk调试信息。最后找到rpc_create_xprt中return clnt; 但是又没return。搞不懂,直接我改成return 0;cInt.c中rpc_create我修改后。

    clnt = rpc_create_xprt(args, xprt);
    if (IS_ERR(clnt) || args->nconnect <= 1)
    {
        printk("rpc_create 4 IS_ERR(clnt) =%d,clnt=0x%8x\n",IS_ERR(clnt),clnt );
        //return clnt;  by apple
        return 0;
    }

然后说当前PC为rpc_release_client,看来有多线程及睡眠唤醒相关了。

nfs_mount 3
rpc_create 1 
rpc_create 2 
rpc_create 3 
rpc_create_xprt 1
rpc_create 1 
rpc_create 2 
rpc_create 3 
rpc_create_xprt 1
rpc_create_xprt 2
rpc_create 4 IS_ERR(clnt) =0,clnt=0xc2c4ac00
8<--- cut here ---
Unable to handle kernel NULL pointer dereference at virtual address 00000010
pgd = (ptrval)
[00000010] *pgd=00000000
Internal error: Oops: 5 [#1] ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper Tainted: G        W         5.4.61 #75
Hardware name: Samsung S3C2416 (Flattened Device Tree)
PC is at rpc_release_client+0x2c/0x100
LR is at rpcb_getport_async+0x284/0x458
pc : [<c05714c8>]    lr : [<c0583ce4>]    psr: 60000013
sp : c34239f8  ip : c3423a14  fp : c3423a10
r10: c0601590  r9 : 00000000  r8 : c07a111c
r7 : c2c32000  r6 : c073d008  r5 : c35a1d00  r4 : 00000000
r3 : 00000000  r2 : 48baebf2  r1 : c3428be0  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: c000717f  Table: 30004000  DAC: 00000053
Process swapper (pid: 1, stack limit = 0x(ptrval))
Stack: (0xc34239f8 to 0xc3424000)
---
[<c057149c>] (rpc_release_client) from [<c0583ce4>] (rpcb_getport_async+0x284/0x458)
 r6:c073d008 r5:c35a1d00 r4:c36ac400
[<c0583a60>] (rpcb_getport_async) from [<c056ea4c>] (call_bind+0x6c/0xbc)
 r10:c35a1d00 r9:00000690 r8:c073d008 r7:fffffe00 r6:00000000 r5:c2c32000
 r4:c35a1d00
[<c056e9e0>] (call_bind) from [<c057a104>] (__rpc_execute+0x80/0x3c4)
 r5:c07a111c r4:00000000
[<c057a084>] (__rpc_execute) from [<c057abec>] (rpc_execute+0x78/0x84)
 r10:c2c31ae0 r9:c3423d7c r8:c073d008 r7:c2c46e00 r6:c3423b60 r5:00000000
 r4:c35a1d00
[<c057ab74>] (rpc_execute) from [<c05708fc>] (rpc_run_task+0x148/0x160)
 r5:c2c46e00 r4:c35a1d00
[<c05707b4>] (rpc_run_task) from [<c0570970>] (rpc_call_sync+0x5c/0xe4)
 r6:c3423ba8 r5:c073d008 r4:00000610
[<c0570914>] (rpc_call_sync) from [<c0571d5c>] (rpc_create_xprt+0x114/0x1fc)
 r7:c2c2a980 r6:c073d008 r5:c3423c74 r4:c2c46e00
[<c0571c48>] (rpc_create_xprt) from [<c057200c>] (rpc_create+0x1c8/0x284)

kernel算是启动成功吧,但是文件系统挂载宣告失败,暂时不去调试nfs挂载了然后尝试nandflash烧写后启动时候,发现之前TQ2440之前的是yaffs2,现在的内核5.4不支持此格式。

  1. ramdisk启动失败
    在内核配置中将文件系统的路径添加后,重新编译然后就可以看到文件系统编译到了内核中。这样通过ramdisk启动,结果依然失败。
    首先出错Loading Kernel Image ... Image too large: increase CONFIG_SYS_BOOTM_LEN
    在config/smdk2440.h添加宏定义值为0xA00000. 把8M改成10M的意思解决此问题。但是依然无法启动ram,网上搜索了下需要修改linuxrc的名字为init
    mv linuxrc init后重新编译kernel,能识别了,但是报错Kernel panic - not syncing,然后查看网上解决方案:(4096) Default RAM disk size (kbytes)改大,我是10M所以是10240K,把4096改成10240,问题依旧。Kernel panic,网上还查到肯能原因是gcc编译器版本太高了。
Freeing unused kernel memory: 5868K
This architecture does not have kernel memory protection.
kernel_init2
kernel_init3
Run /init as init process
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
CPU: 0 PID: 1 Comm: init Tainted: G        W         5.4.61 #82

三,总结

本来想想蛮简单的事情,结果搞了我一周也只是启动了kernel(timer都没打印出来),文件系统没有启动。好吧!过程中我也学习了些调试技巧,启动流程中的关键函数我也更加熟悉了,时间花的值。不过我搭建的目的是学习framebuffer的LCD,这个平台搭建超时了,所以我修改了方案,之后我依然用5.4Kernel,但是会采用非设备树启动TQ2440,虽然是在折腾,但是千万不能跑题,以后要做自制内核启动专题的时候再回来玩也不迟,哈哈~

上一篇下一篇

猜你喜欢

热点阅读