您的位置 首页 方案

linux驱动移植的数据结构

对于嵌入式Linux系统来说,有各种体系结构的处理器和硬件平台,并且用户需要根据需求自己定制硬件板。只要是硬件平台有些变化,即使非

关于嵌入式 Linux 体系来说,有各种体系结构的处理器和硬件渠道,而且用户需求依据需求自己定制硬件板。只需是硬件渠道有些改变,即便十分小,或许也需求做一些移植作业。内核移植是嵌入式Linux体系中最常见的一项作业。

内核移植作业主要是修正跟硬件渠道相关的代码,一般不触及 Linux 内核通用的程序。移植的难度也取决于两种硬件渠道的差异。Linux 关于特定的硬件渠道的软件就叫作 BSP(Board Support Package)。

由于 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/下的头文件中。

linux内核中关于每种支撑的开发板都会运用宏MACHINE_START、MACHINE_END来界说一个machine_desc结构。MACHINE_START、MCHINE_END的界说如下:

(1)

#define MACHINE_START(_type,_name)

static const struct machine_desc __mach_desc_##_type

__used

__attribute__((__section__(“.arch.info.init”))) = {

.nr = MACH_TYPE_##_type,

.name = _name,

#define MACHINE_END

};

在arch/arm/mach-s3c2410/mach-smdk2440.c中能够找到SMDK2440开发板的界说如下:

MACHINE_START(S3C2440, “SMDK2440”)

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.init_irq = s3c24xx_init_irq,

.map_io = smdk2440_map_io,

.init_machine = smdk2440_machine_init,

.timer = &s3c24xx_timer,

MACHINE_END

把MACHINE_START、MACHINE_END扩展开来便是界说了一个名为__mach_desc_S3C2440的结构体变量:

const struct machine_desc __mach_desc_S3C2440__used

__attribute__((__section__(“.arch.info.init”))) =

{

.nr = MACH_TYPE_S3C2440, //开发板的机器类型ID

.name = “SMDK2440”, //开发板称号

.phys_io = S3C2410_PA_UART, //开始IO物理地址

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100, //内核发动参数的地址

.init_irq = s3c24xx_init_irq, //中止初始化函数

.map_io = smdk2440_map_io, //IO映射函数(在这里修正时钟频率)

.init_machine = smdk2440_machine_init,

.timer = &s3c24xx_timer,

};

MACH_TYPE_S3C2440能够看作是体系渠道号,它包含在include/asm- arm/mach-types.h头文件中,不过这个头文件是在装备内核或编译内核时主动生成的,所以不能更改。。真实体系渠道号

的界说方位在arch/arm/tools/mach-types文件中。

# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number

s3c2440 ARCH_S3C2440 S3C2440 362

arch/arm/tools/mach-types中每一行界说一个体系渠道号。 “machine_is_xxx”是用来判别当时的渠道号是否正确的函数; “CONFIG_xxxx”是在内核装备时生成的; “MACH_TYPE_xxx”

是体系渠道号的界说; “number”是体系渠道的值。 __mach_desc_S3C2440结构体中的函数将在内核发动进程中,完结体系渠道的初始化作业

关于具有相同处理器的体系渠道,并不需求对每一个渠道都编写一个BSP,假如他们的外围接口电路根本相同,或许只需修正一些数据的界说,修正几个函数的参数就能够了。

(2)linux规划了一个通用的数据结构resource来描绘各种I/O资源(比方,IO端口,DMA,中止等)

include/linux/ioport.h

struct resource

{
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};

flags:资源符号,用于标识各种资源,例如IORESOURCE_MEM表明内存资源,IORESOURCE_IRQ表明中止资源

关于内存资源,start表明内存开始物理地址,end:表明内存结尾物理地址

关于中止资源,start表明开始中止号,end表明最终一个中止号

常用资源数组来表明一个设备所具有的各类资源,比方s3c2440的片内LCD控制器具有的资源如下

static struct resource s3c_lcd_resource[]=

{

[0]={

.start=S3C24XX_PA_LCD,

.end=S3C24XX_PA_LCD+S3C24XX_SZ_LCD-1,

.flags=IORESOURCE_MEM,

}

[1]={

.start=IRQ_LCD,

.end=IRQ_LCD,

.flags=IORESOURCE_IRQ,

}

};

其间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

{

const char* name; //设备名

int id;

struct device dev;

u32 num_resources; // 设备所运用的各类资源数量

struct resource * resource; // 设备的资源数组

struct platform_device_id *id_entry;

struct pdev_archdata archdata;

};

//渠道驱动

struct platform_driver

{

int (*probe)(struct platform_device *); //勘探

int (*remove)(struct platform_device *); //移除

void (*shutdown)(struct platform_device *); //封闭

int (*suspend)(struct platform_device *, pm_message_t state);//挂起

int (*resume)(struct platform_device *); //康复

//描绘驱动的称号(name)和属主(owner)等信息

struct device_driver driver;

struct platform_device_id *id_table;

};

内核发动后,首要结构链表将描绘设备的platform_device结构组织起来,得到一个设备的列表;当加载某个驱动程序的platform_driver结构时,运用一些匹配函数来查看驱动程序能否支撑这些设备,常用的查看办法很简单:比较驱动程序和设备的称号。

以S3C2440开发板为例,在arch/arm/mach-s3c2440/mach-smdk2440.c中界说了如下设备:

static struct platform_device *smdk2440_devices[] __initdata =

{

&s3c_device_usb, //USB控制器

&s3c_device_lcd, //LCD控制器

&s3c_device_wdt, //看门狗

&s3c_device_i2c,

&s3c_device_iis,

};

在arch/arm/plat-s3c24xx/common-smdk.c中界说了如下设备:

static struct platform_device __initdata *smdk_devs[] =

{

&s3c_device_nand, //NAND FLASH

&smdk_led4,

&smdk_led5,

&smdk_led6,

&smdk_led7,

};

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/261493.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部