linux驅動移植的數據結構
內核移植工作主要是修改跟硬件平臺相關的代碼,一般不涉及 Linux 內核通用的程序。移植的難度也取決于兩種硬件平臺的差異。Linux 對于特定的硬件平臺的軟件就叫作 BSP(Board Support Package)。
本文引用地址:http://www.104case.com/article/201611/320472.htm由于 Linux 內核具備可移植性的特點,并且已經支持了各種體系結構的很多種目標板,我們很容易從中找到跟自己硬件類似的目標板。參考內核已經支持的目標板來移植 BSP,就如同使用模板開發程序。
因此,移植linux內核的過程大多數情況下就是移植BSP的過程。三星公司提供了smdk24xx開發板的BSP。對于mini2440開發板來說,移植linux內核,只要修改smdk24xx開發板的BSP使該linux支持mini2440開發板就可以了。
linux內核源代碼的ARCH目錄存放的是體系結構相關的代碼,對于每個架構的CPU,arm目錄下都有一個對應的目錄,比如arch/arm、arch/i386。而arm架構的處理器種類又有很多,所以,在arch/arm目錄下對于每種arm架構處理器也有一個對應的子目錄,比如arch/arm/mach-s3c2440、arch/arm/mach-s3c2410等。在arch/arm目錄下有一個plat-s3c24xx目錄,根據目錄名它應該是與s3c24xx系列處理器的平臺設備相關的一個目錄。注意,所謂的“平臺設備”并不是與字符設備、塊設備和網絡設備并列的概念,而是linux系統描述設備的一個附加手段。在plat-s3c24xx目錄下有一個common-smdk.c文件,根據文件名,它應該是三星公司的smdk24xx系列開發板都需要的一個文件。在移植驅動的時候經常需要修改arch/arm/plat-s3c24xx/common-smdk.c文件。對于arch/arm/mach-s3c2440目錄,它是專門用來保存 S3C2410 系列處理器平臺相關程序,其中 Kconfig 和 Makefile 是用于內核配置編譯的。其他文件分為 2 類,一類是處理器通用的,例如:clock.c clock.h cpu.c cpu.h s3c2410.c s3c2410.h等;另一類是目標板相關的,例如:bast.h bast-irq.c mach-bast.c等。在這些文件中,實現了處理器和目標板相關的一些定義和初始化函數。還有些相關的定義包含在 include/asm-arm/arch-s3c2410/下的頭文件中。
(1)
#define MACHINE_START(_type,_name)
static const struct machine_desc __mach_desc_##_type
#define MACHINE_END
};
在arch/arm/mach-s3c2410/mach-smdk2440.c中可以找到SMDK2440開發板的定義如下:
MACHINE_START(S3C2440, "SMDK2440")
MACHINE_END
把MACHINE_START、MACHINE_END擴展開來就是定義了一個名為__mach_desc_S3C2440的結構體變量:
const struct machine_desc __mach_desc_S3C2440
{
};
MACH_TYPE_S3C2440可以看作是系統平臺號,它包含在include/asm- arm/mach-types.h頭文件中,不過這個頭文件是在配置內核或編譯內核時自動生成的,所以不能更改。。真正系統平臺號
的定義位置在arch/arm/tools/mach-types文件中。
# machine_is_xxx
s3c2440
arch/arm/tools/mach-types中每一行定義一個系統平臺號。 “machine_is_xxx”是用來判斷當前的平臺號是否正確的函數; “CONFIG_xxxx”是在內核配置時生成的; “MACH_TYPE_xxx”
是系統平臺號的定義; “number”是系統平臺的值。 __mach_desc_S3C2440結構體中的函數將在內核啟動過程中,完成系統平臺的初始化工作
(2)linux設計了一個通用的數據結構resource來描述各種I/O資源(比如,IO端口,DMA,中斷等)
include/linux/ioport.h
struct resource
{
};
flags:資源標記,用于標識各種資源,例如IORESOURCE_MEM表示內存資源,IORESOURCE_IRQ表示中斷資源
對于內存資源,start表示內存起始物理地址,end:表示內存末尾物理地址
對于中斷資源,start表示起始中斷號,end表示最后一個中斷號
常用資源數組來表示一個設備所擁有的各類資源,比如s3c2440的片內LCD控制器擁有的資源如下
static struct resource s3c_lcd_resource[]=
{
[0]={
}
[1]={
};
其中S3C24XX_PA_LCD被定義為0x4D000000,S3C24XX_SZ_LCD被定義為1M。所以,在這里給LCD控制器分配的物理地址空間范圍為0x4D000000~0x4D0FFFFF,這些是LCD控制器各寄存器使用的地址,但實際上LCD控制器的寄存器地址的范圍為0x4D000000~0x4D000060,使用0x4D000000和0x4D000060給他們賦值也應該是可以的。IRQ_LCD算得是32,它會將GPG4引腳設為LCD_PWREN功能,因為GPG4為LCD_PWREN/EINT12復用。
(3)在內核文件include/linux/platform_device.h中,定義了兩個數據結構來表示設備和驅動程序:platform_device結構用來描述設備的名稱、ID、所占用的資源(比如內存地址/大小、中斷號)等;platform_driver結構用來描述各種操作函數,比如枚舉函數、移除設備函數、驅動名稱等。
//平臺設備
struct platform_device
{
};
//平臺驅動
struct platform_driver
{
};
內核啟動后,首先構造鏈表將描述設備的platform_device構造組織起來,得到一個設備的列表;當加載某個驅動程序的platform_driver結構時,使用一些匹配函數來檢查驅動程序能否支持這些設備,常用的檢查方法很簡單:比較驅動程序和設備的名稱。
以S3C2440開發板為例,在arch/arm/mach-s3c2440/mach-smdk2440.c中定義了如下設備:
static struct platform_device *smdk2440_devices[] __initdata =
{
};
在arch/arm/plat-s3c24xx/common-smdk.c中定義了如下設備:
static struct platform_device __initdata *smdk_devs[] =
{
};
評論