中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux驅(qū)動(dòng)移植的數(shù)據(jù)結(jié)構(gòu)

        linux驅(qū)動(dòng)移植的數(shù)據(jù)結(jié)構(gòu)

        作者: 時(shí)間:2016-11-23 來源:網(wǎng)絡(luò) 收藏
        對(duì)于嵌入式 Linux 系統(tǒng)來說,有各種體系結(jié)構(gòu)的處理器和硬件平臺(tái),并且用戶需要根據(jù)需求自己定制硬件板。只要是硬件平臺(tái)有些變化,即使非常小,可能也需要做一些移植工作。內(nèi)核移植是嵌入式Linux系統(tǒng)中最常見的一項(xiàng)工作。

        內(nèi)核移植工作主要是修改跟硬件平臺(tái)相關(guān)的代碼,一般不涉及 Linux 內(nèi)核通用的程序。移植的難度也取決于兩種硬件平臺(tái)的差異。Linux 對(duì)于特定的硬件平臺(tái)的軟件就叫作 BSP(Board Support Package)。

        本文引用地址:http://www.antipu.com.cn/article/201611/320472.htm

        由于 Linux 內(nèi)核具備可移植性的特點(diǎn),并且已經(jīng)支持了各種體系結(jié)構(gòu)的很多種目標(biāo)板,我們很容易從中找到跟自己硬件類似的目標(biāo)板。參考內(nèi)核已經(jīng)支持的目標(biāo)板來移植 BSP,就如同使用模板開發(fā)程序。

        因此,移植linux內(nèi)核的過程大多數(shù)情況下就是移植BSP的過程。三星公司提供了smdk24xx開發(fā)板的BSP。對(duì)于mini2440開發(fā)板來說,移植linux內(nèi)核,只要修改smdk24xx開發(fā)板的BSP使該linux支持mini2440開發(fā)板就可以了。

        linux內(nèi)核源代碼的ARCH目錄存放的是體系結(jié)構(gòu)相關(guān)的代碼,對(duì)于每個(gè)架構(gòu)的CPU,arm目錄下都有一個(gè)對(duì)應(yīng)的目錄,比如arch/arm、arch/i386。而arm架構(gòu)的處理器種類又有很多,所以,在arch/arm目錄下對(duì)于每種arm架構(gòu)處理器也有一個(gè)對(duì)應(yīng)的子目錄,比如arch/arm/mach-s3c2440、arch/arm/mach-s3c2410等。在arch/arm目錄下有一個(gè)plat-s3c24xx目錄,根據(jù)目錄名它應(yīng)該是與s3c24xx系列處理器的平臺(tái)設(shè)備相關(guān)的一個(gè)目錄。注意,所謂的“平臺(tái)設(shè)備”并不是與字符設(shè)備、塊設(shè)備和網(wǎng)絡(luò)設(shè)備并列的概念,而是linux系統(tǒng)描述設(shè)備的一個(gè)附加手段。在plat-s3c24xx目錄下有一個(gè)common-smdk.c文件,根據(jù)文件名,它應(yīng)該是三星公司的smdk24xx系列開發(fā)板都需要的一個(gè)文件。在移植驅(qū)動(dòng)的時(shí)候經(jīng)常需要修改arch/arm/plat-s3c24xx/common-smdk.c文件。對(duì)于arch/arm/mach-s3c2440目錄,它是專門用來保存 S3C2410 系列處理器平臺(tái)相關(guān)程序,其中 Kconfig 和 Makefile 是用于內(nèi)核配置編譯的。其他文件分為 2 類,一類是處理器通用的,例如:clock.c clock.h cpu.c cpu.h s3c2410.c s3c2410.h等;另一類是目標(biāo)板相關(guān)的,例如:bast.h bast-irq.c mach-bast.c等。在這些文件中,實(shí)現(xiàn)了處理器和目標(biāo)板相關(guān)的一些定義和初始化函數(shù)。還有些相關(guān)的定義包含在 include/asm-arm/arch-s3c2410/下的頭文件中。

        linux內(nèi)核中對(duì)于每種支持的開發(fā)板都會(huì)使用宏MACHINE_START、MACHINE_END來定義一個(gè)machine_desc結(jié)構(gòu)。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開發(fā)板的定義如下:

        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擴(kuò)展開來就是定義了一個(gè)名為__mach_desc_S3C2440的結(jié)構(gòu)體變量:

        const struct machine_desc __mach_desc_S3C2440__used

        __attribute__((__section__(".arch.info.init"))) =

        {

        .nr = MACH_TYPE_S3C2440, //開發(fā)板的機(jī)器類型ID

        .name = "SMDK2440", //開發(fā)板名稱

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

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

        .boot_params = S3C2410_SDRAM_PA + 0x100, //內(nèi)核啟動(dòng)參數(shù)的地址

        .init_irq = s3c24xx_init_irq, //中斷初始化函數(shù)

        .map_io = smdk2440_map_io, //IO映射函數(shù)(在這里修改時(shí)鐘頻率)

        .init_machine = smdk2440_machine_init,

        .timer = &s3c24xx_timer,

        };

        MACH_TYPE_S3C2440可以看作是系統(tǒng)平臺(tái)號(hào),它包含在include/asm- arm/mach-types.h頭文件中,不過這個(gè)頭文件是在配置內(nèi)核或編譯內(nèi)核時(shí)自動(dòng)生成的,所以不能更改。。真正系統(tǒng)平臺(tái)號(hào)

        的定義位置在arch/arm/tools/mach-types文件中。

        # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number

        s3c2440 ARCH_S3C2440 S3C2440 362

        arch/arm/tools/mach-types中每一行定義一個(gè)系統(tǒng)平臺(tái)號(hào)。 “machine_is_xxx”是用來判斷當(dāng)前的平臺(tái)號(hào)是否正確的函數(shù); “CONFIG_xxxx”是在內(nèi)核配置時(shí)生成的; “MACH_TYPE_xxx”

        是系統(tǒng)平臺(tái)號(hào)的定義; “number”是系統(tǒng)平臺(tái)的值。 __mach_desc_S3C2440結(jié)構(gòu)體中的函數(shù)將在內(nèi)核啟動(dòng)過程中,完成系統(tǒng)平臺(tái)的初始化工作

        對(duì)于具有相同處理器的系統(tǒng)平臺(tái),并不需要對(duì)每一個(gè)平臺(tái)都編寫一個(gè)BSP,如果他們的外圍接口電路基本相同,也許只需修改一些數(shù)據(jù)的定義,修改幾個(gè)函數(shù)的參數(shù)就可以了。

        (2)linux設(shè)計(jì)了一個(gè)通用的數(shù)據(jù)結(jié)構(gòu)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:資源標(biāo)記,用于標(biāo)識(shí)各種資源,例如IORESOURCE_MEM表示內(nèi)存資源,IORESOURCE_IRQ表示中斷資源

        對(duì)于內(nèi)存資源,start表示內(nèi)存起始物理地址,end:表示內(nèi)存末尾物理地址

        對(duì)于中斷資源,start表示起始中斷號(hào),end表示最后一個(gè)中斷號(hào)

        常用資源數(shù)組來表示一個(gè)設(shè)備所擁有的各類資源,比如s3c2440的片內(nèi)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控制器各寄存器使用的地址,但實(shí)際上LCD控制器的寄存器地址的范圍為0x4D000000~0x4D000060,使用0x4D000000和0x4D000060給他們賦值也應(yīng)該是可以的。IRQ_LCD算得是32,它會(huì)將GPG4引腳設(shè)為L(zhǎng)CD_PWREN功能,因?yàn)镚PG4為L(zhǎng)CD_PWREN/EINT12復(fù)用。

        (3)在內(nèi)核文件include/linux/platform_device.h中,定義了兩個(gè)數(shù)據(jù)結(jié)構(gòu)來表示設(shè)備和驅(qū)動(dòng)程序:platform_device結(jié)構(gòu)用來描述設(shè)備的名稱、ID、所占用的資源(比如內(nèi)存地址/大小、中斷號(hào))等;platform_driver結(jié)構(gòu)用來描述各種操作函數(shù),比如枚舉函數(shù)、移除設(shè)備函數(shù)、驅(qū)動(dòng)名稱等。

        //平臺(tái)設(shè)備

        struct platform_device

        {

        const char* name; //設(shè)備名

        int id;

        struct device dev;

        u32 num_resources; // 設(shè)備所使用的各類資源數(shù)量

        struct resource * resource; // 設(shè)備的資源數(shù)組

        struct platform_device_id *id_entry;

        struct pdev_archdata archdata;

        };

        //平臺(tái)驅(qū)動(dòng)

        struct platform_driver

        {

        int (*probe)(struct platform_device *); //探測(cè)

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

        void (*shutdown)(struct platform_device *); //關(guān)閉

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

        int (*resume)(struct platform_device *); //恢復(fù)

        //描述驅(qū)動(dòng)的名稱(name)和屬主(owner)等信息

        struct device_driver driver;

        struct platform_device_id *id_table;

        };

        內(nèi)核啟動(dòng)后,首先構(gòu)造鏈表將描述設(shè)備的platform_device構(gòu)造組織起來,得到一個(gè)設(shè)備的列表;當(dāng)加載某個(gè)驅(qū)動(dòng)程序的platform_driver結(jié)構(gòu)時(shí),使用一些匹配函數(shù)來檢查驅(qū)動(dòng)程序能否支持這些設(shè)備,常用的檢查方法很簡(jiǎn)單:比較驅(qū)動(dòng)程序和設(shè)備的名稱。

        以S3C2440開發(fā)板為例,在arch/arm/mach-s3c2440/mach-smdk2440.c中定義了如下設(shè)備:

        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中定義了如下設(shè)備:

        static struct platform_device __initdata *smdk_devs[] =

        {

        &s3c_device_nand, //NAND FLASH

        &smdk_led4,

        &smdk_led5,

        &smdk_led6,

        &smdk_led7,

        };



        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉