在linux4.15 移植设备树到JZ2440

注:本文参考了韦东山设备树视频和pengdonglin的博客讓TQ2440也用上設備樹(1),只用于学习记录。

    在前面的博客Linux设备树学习笔记(三、修改uboot、linux-4.15内核在JZ2440使用设备树)记录过设备树在JZ2440的简单使用,但是后来学到gpio、pinctrl子系统发现在使用gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH)函数获取LED引脚时,老是识别不了名为led的gpio,于是参考了韦东山老师的设备树视频和博客讓TQ2440也用上設備樹(1),重新移植了设备树到JZ2440,以支持serial0、rtc、watchdog、DM9000网卡。
注:本次的移植是在前前面的博客Linux设备树学习笔记(三、修改uboot、linux-4.15内核在JZ2440使用设备树)的基础上进行的,即已修改uboot支持设备树、修改好uboot、kernel分区。

1. 添加设备树文件

(1) 进入内核linux-4.15的目录arch/arm/boot/dts查看发现并没有支持2440的设备树文件,最接近的也就只有2416的设备树。于是,我们可以仿照s3c2416的添加JZ2440的设备树文件,把s3c2416.dtsis3c2416-pinctrl.dtsis3c2416-smdk2416.dts分别复制为s3c2440.dtsis3c2440-pinctrl.dtsis3c2440-jz2440.dts,下面是设备树的结构:

s3c2440-jz2440.dts
	  ----> s3c2440.dtsi
        	----> s3c24xx.dtsi
               		 ----> skeleton.dtsi
        	----> s3c2440-pinctrl.dtsi 

上面的文件介绍:
skeleton.dtsi 存放的是一个设备树必备的一些基本属性;
s3c24xx.dtsi 中存放的是整个s3c24xx系列SoC公共的一些属性,如中段控制器、串口、看门狗、RTC、I2C控制器等等;
s3c2440-pinctrl.dtsi 存放的是s3c2440这款SoC中GPIO控制器、外部中断控制器、引脚复用等信息的配置;
s3c2440.dtsi 存放的是s3c2440这个SoC跟其他s3c24xx系列不同的一些硬件信息,如clock控制器、串口等等;
s3c2440-jz2440.dts 存放的是jz2440的硬件信息。

(2) 修改设备树文件
s3c2440.dtsi修改为如下:(只支持serial0、rtc、watchdog、DM9000网卡,nand flash(添加),其余的已删掉,后续学到对应的驱动再添加

/*
 * Samsung's S3C2416 SoC device tree source
 *
 * Copyright (c) 2013 Heiko Stuebner <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <dt-bindings/clock/s3c2410.h>
#include "s3c24xx.dtsi"
#include "s3c2440-pinctrl.dtsi"

/ {
    
    
	model = "Samsung S3C2440 SoC";
	compatible = "samsung,s3c2440";
	
	cpus {
    
    
		#address-cells = <1>;
		#size-cells = <0>;

		cpu {
    
    
			compatible = "arm,arm920t";
		};
	};

	interrupt-controller@4a000000 {
    
    
		compatible = "samsung,s3c2410-irq";
	};

	clocks: clock-controller@0x4c000000 {
    
    
		compatible = "samsung,s3c2440-clock";
		reg = <0x4c000000 0x20>;
		#clock-cells = <1>;
	};

	pinctrl@56000000 {
    
    
		compatible = "samsung,s3c2440-pinctrl";
	};

	timer@51000000 {
    
    
		clocks = <&clocks PCLK_PWM>;
		clock-names = "timers";
	};

	uart_0: serial@50000000 {
    
    
		compatible = "samsung,s3c2440-uart";
		clock-names = "uart";
		clocks = <&clocks PCLK_UART0>;
	};

	watchdog: watchdog@53000000 {
    
    
		interrupts = <1 9 27 3>;
		clocks = <&clocks PCLK>;
		clock-names = "watchdog";
	};

	rtc: rtc@57000000 {
    
    
		compatible = "samsung,s3c2410-rtc";
		clocks = <&clocks PCLK_RTC>;
		clock-names = "rtc";
	};
	/* */
    nand0: nand@4e000000 {
    
    
    	compatible = "samsung,s3c2440-nand";
	    reg = <0x4e000000 0x40>;
	    interrupts = <0 0 24 3>;
	    clocks = <&clocks HCLK_NAND>;
	    clock-names = "nand";
        pinctrl-names = "default";
        pinctrl-0 = <&nand_pinctrl>;
        status = "disabled";
   };
};

s3c2440-pinctrl.dtsi 修改为如下:

/*
 * Samsung S3C2416 pinctrl settings
 *
 * Copyright (c) 2013 Heiko Stuebner <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <dt-bindings/pinctrl/samsung.h>

&pinctrl_0 {
    
    
	/*
	 * Pin banks
	 */
    /*s3c2440只有GPA~GPJ*/
	gpa: gpa {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpb: gpb {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpc: gpc {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpd: gpd {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpe: gpe {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpf: gpf {
    
    
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
	};

	gpg: gpg {
    
    
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
	};

	gph: gph {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpj: gpj {
    
    
		gpio-controller;
		#gpio-cells = <2>;
	};

	/*
	 * Pin groups
	 */
	uart0_data: uart0-data {
    
    
		samsung,pins = "gph-2", "gph-3";
		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
	};
	/*添加NAND flash所用的管脚*/
	nand_pinctrl: nand_pinctrl {
    
    
	    samsung,pins = "gpa-17", "gpa-18", "gpa-19",
				     "gpa-20", "gpa-22";
	    samsung,pin-function = <1>;
    };

};

s3c2440-jz2440.dts 修改为如下:

/*
 * SAMSUNG SMDK2416 board device tree source
 *
 * Copyright (c) 2013 Heiko Stuebner <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;
#include "s3c2440.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
    
    
	model = "JZ2440";
	compatible = "samsung,jz2440";
	
	memory {
    
    
		reg =  <0x30000000 0x4000000>;
	};
	/*设置内核启动参数*/
	 chosen {
    
    
         bootargs = "console=ttySAC0,115200n8 rw root=/dev/mtdblock4 rootfstype=yaffs2";
		 /*bootargs = "console=ttySAC0,115200n8 rw root=/dev/mtdblock4 rootfstype=yaffs2 ignore_loglevel earlyprintk";*/
	 };
	clocks {
    
    
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;

		xti: xti {
    
    
			compatible = "fixed-clock";
			clock-frequency = <12000000>;
			clock-output-names = "xti";
			#clock-cells = <0>;
		};
	};
    /*添加DM9000 网卡,以便于后面的驱动开发调试*/
	srom-cs4@20000000 {
    
    
		compatible = "simple-bus";
        #address-cells = <1>;
        #size-cells = <1>;
		reg = <0x20000000 0x8000000>;
		ranges;
		ethernet@20000000 {
    
    
			compatible = "davicom,dm9000";
			reg = <0x20000000 0x2 0x20000004 0x2>;
			interrupt-parent = <&gpf>;
			interrupts = <7 IRQ_TYPE_EDGE_RISING>;
			local-mac-address = [00 00 de ad be ef];
			davicom,no-eeprom;
		};
	};
};

&rtc {
    
    
	status = "okay";
};

&uart_0 {
    
    
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&uart0_data>;
};

&watchdog {
    
    
	status = "okay";
};

&nand0 {
    
    
	status = "okay";
	nand,tacls = <0xa>;
	nand,twrph0 = <0x19>;
	nand,twrph1 = <0xa>;

	#address-cells = <1>;
	#size-cells = <1>;
    /*Nand flash 分区*/
	partitions {
    
    
		/* MTD partition table */
		#address-cells = <1>;
		#size-cells = <1>;
		nr-chips = <1>;
		set-name = "jz2440-0";

		partition@0 {
    
    
			label = "bootloader";
			reg = <0x0000000 0x00080000>;
			read-only;
		};

		partition@80000 {
    
    
			label = "device_tree";
			reg = <0x00080000 0x00020000>;
			read-only;
		};

		partition@a0000 {
    
    
			label = "params";
			reg = <0x000a0000 0x00040000>;
			read-only;
		};

		partition@e0000 {
    
    
			label = "kernel";
			reg = <0x000e0000 0x00400000>;
			read-only;
		};

		partition@4e0000 {
    
    
			label = "rootfs";
			reg = <0x004e0000 0x0>;
			/*read-only;*/ /*若rootfs为read-only,内核加载文件系统后,文件系统只能读不能写*/
		};
	};
};

(3) 修改arch/arm/boot/dts目录下的Makefile,以便在make dtbs(在linux-4.15顶层目录输入该命令)时,编译s3c2440-jz2440.dts,生成s3c2440-jz2440.dtb文件。修改如下图所示:
在这里插入图片描述

2. 修改Makefile和Kconfig,添加JZ2440板子的信息

2.1 修改arch/arm/mach-s3c24xx/Kconfig

添加的信息如下:
在这里插入图片描述
注:在博客讓TQ2440也用上設備樹(1)的第一个 “select” 是 选择CLKSRC_OF,这里用select TIMER_OF替代。其实select CLKSRC_OFselect TIMER_OF所配置的内容是一样的,这只是内核Linux-4.9 与 Linux-4.15 的微小差异(不过也正因为这个差异,搞了好久,最终是参考韦老师的做法,在内核添加early_print("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);打印才找出来的),我们可以分别在linux-4.9和linux-4.15搜索CONFIG_TIMER_OFCONFIG_CLKSRC_OF,搜索结果如下图所示:
在这里插入图片描述
对比两个内核的drivers/clocksource/samsung_pwm_timer.c第421行后的代码,发现它们是一样的。

言归正传,在make menuconfig的时候,选上这个配置,CONFIG_TIMER_OFCONFIG_USE_OFCONFIG_PINCTRLCONFIG_S3C24XX配置都会被选上。配置如下:

System Type —>
    SAMSUNG S3C24XX SoCs Support —>
在这里插入图片描述

2.2 修改arch/arm/mach-s3c24xx/Makefile

在Makefile添加 obj-$(CONFIG_MACH_JZ2440_DT) += mach-jz2440-dt.o,如下图图所示:
在这里插入图片描述

2.3 添加arch/arm/mach-s3c24xx/mach-jz2440-dt.c文件

mach-jz2440-dt.c文件内容如下:

#include <linux/clocksource.h>
#include <linux/irqchip.h>
#include <linux/serial_s3c.h>
#include <asm/mach/arch.h>
#include <mach/map.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#include "common.h"
#include <linux/of_platform.h>

static void __init jz2440_dt_map_io(void)
{
    
    
     s3c24xx_init_io(NULL, 0);
}

static void __init jz2440_dt_machine_init(void)
{
    
    
    s3c_pm_init();
}

static const char *const jz2440_dt_compat[] __initconst = {
    
    
    "samsung,jz2440",
    NULL,
};

DT_MACHINE_START(JZ2440_DT, "Samsung S3C2440 (Flattened Device Tree)")
    .dt_compat    = jz2440_dt_compat,
    .map_io       = jz2440_dt_map_io,
    .init_irq     = irqchip_init,
    .init_machine = jz2440_dt_machine_init,
MACHINE_END

注:如果内核配置make menuconfig中选择支持设备树

make menuconfig ---> 
              Boot options ---> 
                       Flattened Device Tree support

以前没有设备树的时候是内核启动通过u-boot传入的machine id来找到对应的单板,而使用设备树后内核启动则通过上面的jz2440_dt_compat数组的信息和设备树的compatible 属性比较匹配来对应的单板。

3. 配置打开内核调试

在启动kernel的時候最烦人的是,uboot打印出”Starting kernel …”后,整个系统就沒有任何动静了,此时,就需要打开内核早期的调试log,方法如下:
为了能够尽量看到更多内核启动早期的log,一定要在内核配置文件中把内核早期的log配置打开:

Kernel hacking  --->

    [*] Kernel low-level debugging functions (read help!)

        Kernel low-level debugging port (Use Samsung S3C UART 0 for low-level debug)  --->

    [*] Early printk

除了上面的配置,还必须在bootargs中添加一个earlyprintk字符串,否则这些log还是是打印不出来,此外,建议再在bootargs中添加一个ignore_loglevel参数,防止有些模块的log由于loglevel的问题无法输出log。
因此:chosen节点可以写成:

	 chosen {
    
    
		 bootargs = "console=ttySAC0,115200n8 rw root=/dev/mtdblock4 rootfstype=yaffs2 ignore_loglevel earlyprintk";
	 };

4. 配置编译内核

make s3c2410_defconfig之后,配置内核支持设备树,选择JZ2440单板支持设备树(前面已讲),重新编译内核(make uImage -j8), 最后把编译好的uImage烧写到JZ2440开发板,启动信息如下:

U-Boot 2016.03 (May 24 2020 - 00:33:54 +0800)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0

NAND read: device 0 offset 0xe0000, size 0x400000
 4194304 bytes read: OK

NAND read: device 0 offset 0x80000, size 0x20000
 131072 bytes read: OK
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-4.15.0
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3479496 Bytes = 3.3 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 32000000
   Booting using the fdt blob at 0x32000000
   Loading Kernel Image ... OK
   Loading Device Tree to 33afa000, end 33afe1da ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.15.0 (book@book-virtual-machine) (gcc version 4.9.4 (Linaro GCC 4.9-2017.01)) #3 Thu May 21 22:24:54 CST 2020
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c000717f
CPU: VIVT data cache, VIVT instruction cache
OF: fdt: Machine model: JZ2440
Memory policy: Data cache writeback
arch/arm/mach-s3c24xx/mach-jz2440-dt.c jz2440_dt_map_io 14
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: console=ttySAC0,115200n8 rw root=/dev/mtdblock4 rootfstype=yaffs2
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 57936K/65536K available (5013K kernel code, 213K rwdata, 1180K rodata, 188K init, 202K bss, 7600K 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)   (5015 kB)
      .init : 0x(ptrval) - 0x(ptrval)   ( 188 kB)
      .data : 0x(ptrval) - 0x(ptrval)   ( 214 kB)
       .bss : 0x(ptrval) - 0x(ptrval)   ( 203 kB)
NR_IRQS: 103
irq: clearing pending status 00000002
_get_rate: could not find clock xti
sched_clock: 16 bits at 1000kHz, resolution 1000ns, wraps every 32767500ns
clocksource: samsung_clocksource_timer: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 29163075 ns
Console: colour dummy device 80x30
Calibrating delay loop... 199.06 BogoMIPS (lpj=995328)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x300081e0 - 0x30008238
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 256 (order: -1, 3072 bytes)
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
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.
clocksource: Switched to clocksource samsung_clocksource_timer
NET: Registered protocol family 2
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
NetWinder Floating Point Emulator V0.97 (extended precision)
Initialise system trusted keyrings
workingset: timestamp_bits=30 max_order=14 bucket_order=0
jffs2: version 2.2. (NAND) (SUMMARY)  © 2001-2006 Red Hat, Inc.
romfs: ROMFS MTD (C) 2007 Red Hat, Inc.
Key type asymmetric registered
Asymmetric key parser 'x509' registered
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
io scheduler mq-deadline registered
io scheduler kyber registered
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
50000000.serial: ttySAC0 at MMIO 0x50000000 (irq = 32, base_baud = 0) is a S3C2440
console [ttySAC0] enabled
lp: driver loaded but no devices found
ppdev: user-space parallel port driver
brd: module loaded
loop: module loaded
s3c24xx-nand 4e000000.nand: Tacls=1, 10ns Twrph0=5 50ns, Twrph1=2 20ns
nand: device found, Manufacturer ID: 0xec, Chip ID: 0xda
nand: Samsung NAND 256MiB 3,3V 8-bit
nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
s3c24xx-nand 4e000000.nand: ECC disabled
nand: NAND_ECC_NONE selected by board driver. This is not recommended!
Scanning device for bad blocks
Bad eraseblock 1027 at 0x000008060000
5 ofpart partitions found on MTD device partitions
Creating 5 MTD partitions on "partitions":
0x000000000000-0x000000080000 : "bootloader"
0x000000080000-0x0000000a0000 : "device_tree"
0x0000000a0000-0x0000000e0000 : "params"
0x0000000e0000-0x0000004e0000 : "kernel"
0x0000004e0000-0x000010000000 : "rootfs"
s3c24xx-nand 4e000000.nand: Tacls=1, 10ns Twrph0=5 50ns, Twrph1=2 20ns
eth0: dm9000b at ab428955,46df3c1c IRQ 7 MAC: 00:0c:29:4d:e4:f4 (platform data)
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-s3c2410: OHCI S3C2410 driver
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver ftdi_sio
usbserial: USB Serial support registered for FTDI USB Serial Device
usbcore: registered new interface driver pl2303
usbserial: USB Serial support registered for pl2303
s3c-rtc 57000000.rtc: rtc disabled, re-enabling
rtc rtc0: invalid alarm value: 1900-2-1 0:0:0
s3c-rtc 57000000.rtc: rtc core: registered s3c as rtc0
s3c2410-wdt 53000000.watchdog: watchdog inactive, reset disabled, irq disabled
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
s3c-rtc 57000000.rtc: setting system clock to 2000-10-17 09:22:55 UTC (971774575)
ALSA device list:
  No soundcards found.
yaffs: dev is 32505860 name is "mtdblock4" rw
yaffs: passed flags ""
VFS: Mounted root (yaffs2 filesystem) on device 31:4.
Freeing unused kernel memory: 188K
This architecture does not have kernel memory protection.
dm9000 20000000.ethernet eth0: link down
IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
dm9000 20000000.ethernet eth0: link down

Please press Enter to activate this console.
/ #

最后,关于设备树的修改,大家可以阅读pengdonglin的博客讓TQ2440也用上設備樹(1),这博客写得非常好。

猜你喜欢

转载自blog.csdn.net/qq_35031421/article/details/106089658