一,前言,
uboot已经移植成功了,接着就是要用kernel 5.4,而且要用设备树。一开始网上看了下,评估下难度,看上去不难。然后我就开始了menuconfig参考smkd2410_defconfig,然后设备树都是基于smdk2410-s3c2416.dts修改。
二,问题记录
- 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
- 解决了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还是要加的。就成功了哦!
- 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不支持此格式。
- 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,虽然是在折腾,但是千万不能跑题,以后要做自制内核启动专题的时候再回来玩也不迟,哈哈~
四,后记
tq2440不支持设备树的启动kernel很顺利,大数nfs挂载不了。我抓包看看通信,UDP, bad length 2576 > 132。只是大概了解了nfs会用到rpc协议。就是函数参数通过tcp或udp传给主机,然后主机调用函数将返回结果再通过tcp或udp传给客户端。这个主机就是ubuntu,客户端就是tq2440开发板。可能是dm9000移植有问题吧。然后直接烧写jffs到nand启动也移植报nand ecc error。然后又尝试了ramdisk启动,报错can not start 0。3种方法都无法系统文件系统。算了,我先放弃了,这个已经背离了我的学习目标。之后有空再研究吧!
root@applecaiHP:/home/applecai/studybr/buildroot-2020.05.2/images# tcpdump -i eno1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno1, link-type EN10MB (Ethernet), capture size 262144 bytes
14:19:43.979363 IP6 :: > ff02::16: HBH ICMP6, multicast listener report v2, 1 group record(s), length 28
14:19:44.102299 ARP, Request who-has applecaiHP tell 192.168.0.17, length 46
14:19:44.102334 ARP, Reply applecaiHP is-at c4:34:6b:01:04:10 (oui Unknown), length 28
14:19:44.102796 IP 192.168.0.17.51569 > applecaiHP.sunrpc: UDP, length 88
14:19:44.103150 IP applecaiHP.sunrpc > 192.168.0.17.51569: UDP, length 28
14:19:44.106574 IP 192.168.0.17 > applecaiHP: udp
14:19:44.399599 IP6 :: > ff02::1:ff49:c1b2: ICMP6, neighbor solicitation, who has ::803b:f8ff:fe49:eb2, length 32
14:19:45.460057 IP6 fe80::803b:f8ff:fe49:c1b2 > ff02::16: HBH ip-proto-5 12
14:19:45.460554 IP6 truncated-ip6 - 15087 bytes missing!fe80::803b:f8ff:fe49:c1b2 > ip6-allrouters: ICMP6, router solicitation, length 15103
14:19:46.339933 IP6 fe80::803b:f8ff:fe49:ff02 > ff02::16: HBH ICMP6, unknown icmp6 type (117), length 28
0x0000: 75d5 75d5 0000 0001 0400 0000 ff02 0000
0x0010: 0000 0000 0000 0001 ff49 c1b2
14:19:49.141167 IP 192.168.0.17.784 > applecaiHP.52634: UDP, length 40
14:19:49.141667 IP applecaiHP.52634 > 192.168.0.17.784: UDP, length 24
14:19:49.143598 IP 192.168.0.17 > applecaiHP: trunk-2 140
14:19:54.182520 82:3b:f8:49:c1:b2 (oui Unknown) > c4:34:6b:01:04:10 (oui Unknown), ethertype Unknown (0x4500), length 174:
0x0000: 4500 00a0 d9d9 4000 4011 dea3 c0a8 0011 E.....@.@.......
0x0010: c0a8 006e 0310 cd9a 008c 0a18 d621 7097 ...n.........!p.
0x0020: 0000 0000 0000 0001 0001 86a5 0000 0003 ................
0x0030: 0000 0001 0000 0001 0000 0020 0000 0000 ................
0x0040: 0000 000c 3139 322e 3136 382e 302e 3137 ....192.168.0.17
0x0050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x0060: 0000 0000 0000 0038 2f68 6f6d 652f 6170 .......8/home/ap
0x0070: 706c 6563 6169 2f73 7475 6479 6272 2f62 plecai/studybr/b
0x0080: 7569 6c64 726f 6f74 2d32 3032 302e 3035 uildroot-2020.05
0x0090: 2e32 2f69 6d61 6765 732f 726f 6f74 6673 .2/images/rootfs
14:19:57.782886 IP6 fe80::803b:f8ff:fe49:ff02 > ip6-allrouters: ICMP6, router solicitation, length 16
14:20:04.825296 IP 192.168.0.17.784 > applecaiHP.52634: UDP, bad length 2576 > 132