JZ2440支持設備樹(1)-添加設備樹以後kernel的啓動參數跟dts裏面不一致

在作以前參考了以下博客文章,再次很是感謝:html

http://www.cnblogs.com/pengdonglin137/p/6241895.htmlnode

Uboot中須要在config中添加以下宏:linux

#define CONFIG_FIT        1 

 在內核裏面make menuconfig以後配置支持設備樹:xcode

Boot options-> 
[*] Flattened Device Tree support

而後分別編譯uboot和kernel,最後按照網上介紹製做dtb文件,將uboot經過jlink直接燒到nor flash的0地址處,而後用tftp將kernel下載到內存的30000000,將dtb文件燒到內存的31000000,而後用bootm 30000000 - 31000000啓動系統,但只能看到:dom

SMDK2440 # bootm 30000000 - 31000000
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-4.15.1-gc1aaab686-dirty
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3498656 Bytes = 3.3 MiB
   Load Address: 30108000
   Entry Point:  30108000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 31000000
   Booting using the fdt blob at 0x31000000
   Loading Kernel Image ... OK
   Loading Device Tree to 33ba6000, end 33baa6ea ... OK

Starting kernel ...

由於以前使用tags內核能正確啓動,因此目前就是懷疑dtb文件沒有正確傳到linux,可是在uboot的/include/common.h裏面添加#define DEBUG將uboot的因此調試信息打開,能看到dtb文件已經被uboot識別而且拷貝到內存的另外一個地方了,若是按下開發板上的reset按鍵再一次進到uboot的console,在用dm.w去看dtb,能正確的看到dtb的內容,因此目前懷疑2點:函數

1.設備樹不被kernel識別。ui

2.設備樹被正確識別,但bootargs沒有被正確讀取,處處串口沒有正確配置。spa

 

解決問題:debug

1.剛開始沒法定位在linux kernel哪裏掛掉的,因而添加了led燈,在沒有開啓MMU以前,能夠直接操做物理地址,一直查到:3d

ENTRY(__turn_mmu_on)
    mov    r0, r0
    instr_sync
    mcr    p15, 0, r0, c1, c0, 0        @ write control reg
    mrc    p15, 0, r3, c0, c0, 0        @ read id reg
    instr_sync
    mov    r3, r3
    mov    r3, r13
    ret    r3

這裏的MMU被打開了,就不能直接操做物理地址了,再日後執行就是調用__mmap_switched,由於很早就有ldr r13, =__mmap_switched @ address to jump to after而後在__mmap_switched的最後就是執行C代碼入口b start_kernel

因而判定確定執行到了c階段,但此時MMU已經開啓,不清楚如何調試,因而又想到了earlyprintk,不爽的就是earlyprintk須要添加到bootargs裏面,由於kernel C代碼裏面回去解析,暫時還沒分析爲何非要uboot傳過來。

我如今的問題就頗有可能uboot的bootargs沒有正確傳過來,原本想動腦筋在代碼裏面寫死bootargs裏面有earlyprintk的,後來忽然想到make menuconfig有一個默認的Default kernel command string,因而我配置以下:

 

再次編譯內核,燒到板子上運行,終於有進步了:

SMDK2440 # bootm 30000000 - 31000000
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-4.15.1-gc1aaab686-dirty
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3498656 Bytes = 3.3 MiB
   Load Address: 30108000
   Entry Point:  30108000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 31000000
   Booting using the fdt blob at 0x31000000
   Loading Kernel Image ... OK
   Loading Device Tree to 33ba6000, end 33baa6ea ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.

我在misc.c裏面添加了寫打印信息,以下:
static void puthex(const int dat)
{
	char c;
    unsigned char temp[4]={0};
    
	temp[0] = dat/1000 + 0x30;
	temp[1] = dat%1000/100 + 0x30;
	temp[2] = dat%100/10 + 0x30;	
	temp[3] = dat%10 + 0x30;
	putc(temp[0]);	
	putc(temp[1]);	
	putc(temp[2]);	
	putc(temp[3]);	
	putc('\r');
	putc('\n');    
	flush();
}

void DispDeviceTree(int arch_id,unsigned long* dev_tree)
{
    char temp_str[100];
	
    sprintf(temp_str,"machid=%d",arch_id);
	putstr(temp_str);
	sprintf(temp_str,"devTree=%s",dev_tree);	
	putstr(temp_str);
}
 
 

而後在head.s裏面添加了加上這個函數

/*
 * The C runtime environment should now be setup sufficiently.
 * Set up some pointers, and start decompressing.
 *   r4  = kernel execution address
 *   r7  = architecture ID
 *   r8  = atags pointer
 */
		mov	r0, r4
		mov	r1, sp			@ malloc space above stack
		add	r2, sp, #0x10000	@ 64k max
		mov	r3, r7
		bl	decompress_kernel

        mov r0, r7
        mov r1, r8
        bl  DispDeviceTree
        mov r0, r4
        mov r1, sp

竟然打印出了,說明我破壞了寄存器裏面的值,致使連設備樹都找不到了,machine id的值不須要關心,由於咱們是用dts來匹配的,如今的kernel是支持兩種匹配方式的,因此在兩種都找不到的狀況下就報錯了,相信之後kernel會徹底刪除tags的方式的。

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Machid=0362

dev tree:

Error: unrecognized/unsupported device tree compatible list:
[ 'samsung,s3c2440' 'samsung,jz2440' ]

Available machine support:

ID (hex)        NAME
00000400        AML_M5900
0000014b        Simtec-BAST
0000015b        IPAQ-H1940
0000039f        Acer-N35
00000290        Acer-N30
000002a8        Nex Vision - Otom 1.1
00000454        QT2410
000000c1        SMDK2410
000005b4        TCT_HAMMER
000001db        Thorcom-VR1000
000005d2        JIVE
000003fe        SMDK2413
000003f1        SMDK2412
00000377        S3C2413
00000474        VSTMS
00000695        SMDK2416
000002de        Simtec-Anubis
00000707        AT2440EVB
000007cf        MINI2440
000002a9        NexVision - Nexcoder 2440
0000034a        Simtec-OSIRIS
00000250        IPAQ-RX3715
00000518        GTA02
000003b8        HP iPAQ RX1950
0000043c        SMDK2443

Please check your kernel config and/or bootloader.
後來我將misc.c和head.S還原,仍是打印了這些信息,挺好的。

SMDK2440 # bootm 30000000 - 31000000
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-4.15.1-gc1aaab686-dirty
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3488904 Bytes = 3.3 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 31000000
   Booting using the fdt blob at 0x31000000
   Loading Kernel Image ... OK
   Loading Device Tree to 33ba6000, end 33baa506 ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
bootcmd line:
arch/arm/kernel/devtree.c:setup_machine_fdt __machine_arch_type=ffffffff
bootcmd line:noinitrd console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=
jffs2 earlyprintk

find fdt,and tags
r1=0xffffffff, r2=0x33ba6000
machine name:Samsung S3C2440 (Flattened Device Tree)
Booting Linux on physical CPU 0x0
Linux version 4.15.1-gc1aaab686-dirty (kent@hu) (gcc version 4.4.3 (ctng-1.6.1
)) #27 Mon Sep 3 22:21:31 CST 2018
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c000717f
CPU: VIVT data cache, VIVT instruction cache
OF: fdt: Machine model: JZ2440
bootcmd line:
arch/arm/kernel/devtree.c:setup_machine_fdt __machine_arch_type=ffffffff
bootcmd line:noinitrd console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=
jffs2 earlyprintk

find fdt,and tags
r1=0xffffffff, r2=0x33ba6000
machine name:Samsung S3C2440 (Flattened Device Tree)
bootconsole [earlycon0] enabled
Memory policy: Data cache writeback
CPU S3C2440A (id 0x32440001)
DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map
random: fast init done
Built 1 zonelists, mobility grouping on.  Total pages: 16256
Kernel command line: noinitrd console=ttySAC0,115200 root=/dev/mtdblock3 
rootfstype=jffs2 earlyprintk
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 57764K/65536K available (5319K kernel code, 216K rwdata, 1164K rodata
, 204K init, 203K bss, 7772K reserved, 0K cma-reserved)
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
    lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .text : 0x(ptrval) - 0x(ptrval)   (5321 kB)
      .init : 0x(ptrval) - 0x(ptrval)   ( 204 kB)
      .data : 0x(ptrval) - 0x(ptrval)   ( 217 kB)
       .bss : 0x(ptrval) - 0x(ptrval)   ( 204 kB)
NR_IRQS: 103
_get_rate: could not find clock xti
sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 
21474836475000000ns
Console: colour dummy device 80x30

這裏注意到,打印的command line不是我在dts裏面定義的,我當時懷疑是否是kernel沒識別dts裏面的bootargs成員,由於打印出了OF: fdt: Machine model: JZ2440,說明確實是找到了設備樹,因而我在arch\arm\kernel\devtree.c中的setup_machine_fdt函數裏面根據實際地址和虛擬地址將內存裏面的設備樹以08x的形式所有打印出來了,而後跟我編譯出來的dts作對比,發現確實不同,後來懷疑是uboot傳錯了,因而去查uboot。

將uboot中的include/common.h裏面的debug打開,這樣就能夠看到更多的信息,因而看到打印出瞭如下信息:

SMDK2440 # bootm 30000000 - 31000000
## Current stack ends at 0x33ba7ba0 *  kernel: cmdline image address = 0x30000000
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-4.15.1-gc1aaab686-dirty
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3489048 Bytes = 3.3 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   kernel data at 0x30000040, len = 0x00353d18 (3489048)
## Skipping init Ramdisk
## No init Ramdisk
   ramdisk start = 0x00000000, ramdisk end = 0x00000000
*  fdt: cmdline image address = 0x31000000
## Checking for 'FDT'/'FDT Image' at 31000000
*  fdt: raw FDT blob
## Flattened Device Tree blob at 31000000
   Booting using the fdt blob at 0x31000000
   of_flat_tree at 0x31000000 size 0x00001507
Initial value for argc=3
Final value for argc=3
   Loading Kernel Image ... OK
   kernel loaded at 0x30008000, end = 0x3035bd18
images.os.start = 0x30000000, images.os.end = 0x30353d58
images.os.load = 0x30008000, load_end = 0x3035bd18
using: FDT
## initrd_high = 0xffffffff, copy_to_ram = 1
   ramdisk load start = 0x00000000, ramdisk load end = 0x00000000
## device tree at 31000000 ... 31001506 (len=17671 [0x4507])
   Loading Device Tree to 33ba2000, end 33ba6506 ... OK

Initial value for argc=3
Final value for argc=3
No alias for ethernet0
## Transferring control to Linux (at address 30008000)...

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
phys:33ba2000
virt:c3ba2000

最後兩句是我加在arch\arm\kernel\devtree.c中的setup_machine_fdt函數裏面的:

說明kernel是從uboot傳給它的地址去取的dts,難道真是uboot傳錯dts了?

因而在uboot裏面的common\image-fdt.c裏的boot_relocate_fdt函數裏添加打印信息,將dts所有打印出來,發現dts仍是錯的,並且很明顯是跟在configs/smdk2440.h裏面定義的CONFIG_BOOTARGS徹底同樣,因而猜測,是否是uboot優先取CONFIG_BOOTARGS定義的bootargs,因而將其屏蔽,將存在nand上面的環境變量所有刪除,再次將編譯出來的uboot.bin經過jlink燒到nor上啓動,在uboot的界面下經過tftp下載kernel和dts到ddr,再次執行bootm 30000000 - 31000000

此次kernel裏面打印的bootargs跟我在dts裏面定義的一致,至此纔敢肯定的說,個人JZ2440支持設備樹了。

相關文章
相關標籤/搜索