历史上的今天
今天是:2025年02月16日(星期日)
2020年02月16日 | 讓TQ2440也用上設備樹(1)
2020-02-16 来源:eefocus
開發板
TQ2440 + 64MB 內存 + 256MB Nand
軟件
Linux: Linux-4.9 (https://github.com/pengdonglin137/linux-4.9 )
u-boot:U-Boot 2015.04 (http://www.cnblogs.com/pengdonglin137/p/4541705.html 以及 https://github.com/pengdonglin137/u-boot )
busybox:1.25.0
工具鏈:
編譯內核使用的是arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2(下載)
編譯busybox使用的是EABI-4.3.3_EmbedSky_20100610.tar.bz2 (開發板自帶的工具鏈),因爲發現,如果用跟編譯kernel同樣的那個工具鏈的話,啓動init進程啓動會有問題
以往TQ2440上移植Linux內核都沒有支持設備樹,而設備樹纔是潮流,tq2440沒用上設備樹這件事我心裏糾結了很長時間,所以特意花了一天時間搞一搞,同時爲想研究學習設備樹的同志鋪一鋪路。好在Samsung已經做了很多工作,最後我發現,需要我們修改的基本都是設備樹文件,而kernel代碼幾乎不用怎麼大動。
在移植的時候,需要對Linux下的中斷子系統、時鐘子系統有一些認識。
目前這個版本支持:
1. serial0
2. rtc
3. watchdog (如果沒有這個的話,reboot的時候板子不會自動復位)
4. DM9000 (有了這個,就可以用nfs掛載遠程目錄,對於調試工作很有益處)
下面是下載代碼的鏈接:
git clone git@github.com:pengdonglin137/linux-4.9.git -b tq2440_dt
使用方法:
下載代碼後,修改Makefile文件,設置ARCH和CROSS_COMPILE
make tq2440_dt_defconfig
編譯uImage,然後將uImage拷貝到/tftpboot下: make uImage -j4
編譯設備樹,然後將s3c2440-tq2440-dt.dtb拷貝到/tftpboot下:make dtbs
製作ramdisk:下載tq2440_ramdisk.tar.gz,解壓後,執行下面的腳本mk_ramdisk.sh,會生成一個ramdisk.img文件
進入u-boot:注意:後下載的鏡像不要把前面的鏡像覆蓋了
下載uImage:tftp 0x30008000 uImage;
下載ramdisk:tftp 0x31000000 ramdisk.img;
下載設備樹文件:tftp 0x33000000 s3c2440-tq2440-dt.dtb;
啓動:bootm 0x30008000 0x31000000 0x33000000
在移植的時候參考了s3c2416的代碼,因爲目前s3c2416採用的就是設備樹,但是畢竟跟s3c2440不同,無法直接使用,需要修改設備樹配置。
在移植初期,kernel啓動的時候會在很多地方卡住,臨時的處理辦法是先把卡住的函數注掉,把出問題的模塊先從內核配置中拿掉。最後,板子起來後,再回頭分析前面模塊被卡住的原因。目前我是在tq2440上面移植的,由於mini2440跟tq2440基本一樣(初期我使用的內核配置文件copy的就是mini2440_defconfig,然後在此基礎上修改),所以理論上使用上面的鏡像也可以將mini2440啓動起來。
下面的移植記錄不會很全,詳細的代碼改動請參考上面我上傳到github上的代碼。
一、添加設備樹文件,我仿照s3c2416-smdk2416.dts的結構添加了tq2440的設備樹需要的文件,下面是設備樹的結構
s3c2440-tq2440-dt.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-tq2440-dt.dts 存放的是tq2440的硬件信息
設備樹這樣一層層包含的好處是: 在同名節點中,後出現的屬性會覆蓋前面出現的同名屬性,不同的屬性將來會合併到所隸屬的同名的節點下面。
然後修改arch/arm/boot/dts/Makefile:
1 diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
2 index c558ba7..28381c0 100644
3 --- a/arch/arm/boot/dts/Makefile
4 +++ b/arch/arm/boot/dts/Makefile
5 @@ -661,7 +661,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) +=
6 rk3288-veyron-pinky.dtb
7 rk3288-veyron-speedy.dtb
8 dtb-$(CONFIG_ARCH_S3C24XX) +=
9 - s3c2416-smdk2416.dtb
10 + s3c2416-smdk2416.dtb
11 + s3c2440-tq2440-dt.dtb
12 dtb-$(CONFIG_ARCH_S3C64XX) +=
13 s3c6410-mini6410.dtb
14 s3c6410-smdk6410.dtb
這樣在make dtbs編譯設備樹的時候就會編譯s3c2440-tq2440-dt.dts,在arch/arm/boot/dts/下生成s3c2440-tq2440-dt.dtb
二、修改Makefile和Kconfig,添加tq2440板子的信息,以便在kernel啓動的時候能夠用從設備樹鏡像中解析到的信息匹配到tq2440板子
修改arch/arm/mach-s3c24xx/Kconfig
1 diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
2 index 4b1690a..5b2e34f 100644
3 --- a/arch/arm/mach-s3c24xx/Kconfig
4 +++ b/arch/arm/mach-s3c24xx/Kconfig
5 @@ -475,6 +475,15 @@ config MACH_MINI2440
6 Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
7 available via various sources. It can come with a 3.5" or 7" touch LCD.
8
9 +config MACH_TQ2440_DT
10 + bool "TQ2440 development board using device tree"
11 + select CLKSRC_OF
12 + select USE_OF
13 + select PINCTRL
14 + select PINCTRL_S3C24XX
15 + help
16 + Say Y here to select support for the TQ2440.
17 +
18 config MACH_NEXCODER_2440
19 bool "NexVision NEXCODER 2440 Light Board"
20 select S3C2440_XTAL_12000000
這樣在make menuconfig的時候,選擇上這個配置。選擇這個配置的時候,CONFIG_CLKSRC_OF/CONFIG_USE_OF/CONFIG_PINCTRL/CONFIG_S3C24XX都會被配置上。
修改arch/arm/mach-s3c24xx/Makefile
1 diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
2 index 8ac2f58..2be494d100644
3 --- a/arch/arm/mach-s3c24xx/Makefile
4 +++ b/arch/arm/mach-s3c24xx/Makefile
5 @@-60,6+60,8@@ obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
6 obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o
7 obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o
8 +obj-$(CONFIG_MACH_TQ2440_DT) += mach-tq2440-dt.o
9 +
10 obj-$(CONFIG_MACH_JIVE) += mach-jive.o
11 obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
12 obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
在Kconfig配置上CONFIG_MACH_TQ2440_DT後,在make uImage的時候就會編譯mach-tq2440-dt.c
添加arch/arm/mach-s3c24xx/mach-tq2440-dt.c
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include "common.h" 9 static void __init tq2440_dt_map_io(void) 10 { 11 s3c24xx_init_io(NULL, 0); 12 } 13 static void __init tq2440_dt_machine_init(void) 14 { 15 s3c_pm_init(); 16 } 17 static const char *const tq2440_dt_compat[] __initconst = { 18 "samsung,s3c2440", 19 "samsung,tq2440", 20 NULL 21 }; 22 DT_MACHINE_START(TQ2440_DT, "Samsung S3C2440 (Flattened Device Tree)") 23 .dt_compat = tq2440_dt_compat, 24 .map_io = tq2440_dt_map_io, 25 .init_irq = irqchip_init, 26 .init_machine = tq2440_dt_machine_init, 27 MACHINE_END 第11行會對一些常用的內存進行靜態映射。 這裏我們需要注意的是第30行的dt_compat數組,其中的值要跟設備樹中的compatible匹配,如arch/arm/boot/dts/s3c2440-tq2440-dt.dts: 1 /dts-v1/; 2 #include "s3c2440.dtsi" 3 #include 4 #include 5 / { 6 model = "TQ2440"; 7 compatible = "samsung,s3c2440", "samsung,tq2440"; 8 memory { 9 reg = <0x30000000 0x34000000>; 10 }; 如上面的第7行,跟tq2440_dt_compat是相匹配的。 三、打開內核調試開關 如果uboot中設置了bootargs屬性的話,在boot的之前它會修改設備樹鏡像,覆蓋其中chosen節點中的bootargs屬性,爲了便於調試,我在uboot中執行setenv bootargs命令,這樣就可以刪除uboot中bootargs環境變量。 在啓動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 下面是設備樹(s3c2440-tq2440-dt.dts)中chosen節點的定義: 1 chosen { 2 bootargs = "root=/dev/ram0 rw rootfstype=ext2 console=ttySAC0,115200n8 init=/linuxrc ignore_loglevel earlyprintk"; 3 }; 四、剩下的工作就是修改設備樹了 這也是導致kernel無法啓動的原因,當然前期並不確定問題是出在設備樹還是kernel,下面提示幾個比較關鍵的點。 fixed-clock時鐘配置 在移植以前不支持設備樹的內核代碼的時候(https://github.com/pengdonglin137/linux-3-14-y/tree/transplant_to_tq2440 )在mach-tq2440.c中: 1 static void __init tq2440_map_io(void) 2 { 3 s3c24xx_init_io(tq2440_iodesc, ARRAY_SIZE(tq2440_iodesc)); 4 s3c24xx_init_clocks(12000000); 5 s3c24xx_init_uarts(tq2440_uartcfgs, ARRAY_SIZE(tq2440_uartcfgs)); 6 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); 7 } 第4行設置了XTI的時鐘是12MKHz,但是有了設備樹後,就不能這樣做了,你可以看看在linux-4.9下面s3c24xx_init_clocks函數的實現,由於cpu->init_clocks爲NULL,會導致kernel panic。 那爲什麼是12M呢?在TQ2440的核心板上可以看到XTIpll上接了一個12M的晶振: 對應在設備樹中的配置(s3c2440-tq2440-dt.dts)是: 1 clocks { 2 compatible = "simple-bus"; 3 #address-cells = <1>; 4 #size-cells = <0>; 5 xti: oscillator@0 { 6 compatible = "fixed-clock"; 7 reg = <0>; 8 clock-frequency = <12000000>; 9 clock-output-names = "xti"; 10 #clock-cells = <0>; 11 }; 12 }; 這個還是比較關鍵的,s3c2416並沒有這個節點,如果這個沒有配置的話,會導致很多問題,如後面的在bootconsole被disable後,由於時鐘問題,串口輸出會出問題,此外,也會導致很多內核除0異常。 clock控制器配置 這個也非常關鍵,在某個模塊在get_clk的時候就會用到,此外,在某個節點的屬性中配置了clocks和clock-names屬性的時候也會用到它,如果配置有問題,也會出現很多問題。 
史海拾趣
|
单脉冲序列对双激式开关电源变压器铁心的磁化开关电源原理与设计(连载53) 2-1-1-4.脉冲序列对双激式开关电源变压器铁心的磁化 双激式变压器与单激式变压器的区别主要是两者输入电压的参数不一样。单激式变压器输入的电压是单极性直流脉冲,而双激式变压器输入的电压是双极性交流脉冲。为了简单起见,我们把双激式变压器 ...… 查看全部问答> |
|
数字视频监控系统主要包括DVR、DVS、IP-Camera等,涉及到嵌入式系统技术、视频编解码技术、音频编解码技术、联网及域名处理技术等。硬件对于系统而言,相当于建筑的地基,地基牢,建筑才可靠,才能够经历风风雨雨的考验。 概述 & ...… 查看全部问答> |
|
我做摄像头的数据采集,用CreateFile打开设备,然后调用DeviceIoControl函数,第二个参数需要的是控制CODE,这个CODE需要驱动来提供?不是标准调用吧。如果驱动没有提供读数据的控制CODE,那我是不是就没有办法用DeviceIoControl得到数据了?… 查看全部问答> |
|
driverStudio 生成的驱动程序 实现 IO读写功能 驱动程序代码中两个操作如下: NTSTATUS RW6070Device::RW6070_IOCTL_800_Handler(KIrp I) { NTSTATUS status = STATUS_SUCCESS; //t … 查看全部问答> |
|
RT-Thread开源实时操作系统/STM32F103VB0.3.0b3版本 这个版本更新有些多,RT-Thread/STM32F103VB 0.3.0 beta3更改记录:- 内核,添加IAR EWARM 5.x工程,在内核定义中做相应的平台定义;- 添加文件系统组件DFS,DFS是一套虚拟文件系统(类似Linux的VFS,但几乎不占 ...… 查看全部问答> |
|
有关2812的资料其寄存器都没有地址,所见的都是C语言的头文件,用了结构体和共用体,找不出起物理地址了,想用一段汇编,找不到外设和寄存器的地址,没法编那.谁有这方面的资料?或给指点一下… 查看全部问答> |




