日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux io映射,【原创】Linux 文件系统移植全解密以linux-2.6.35内核源码为例说明一下IO静态映射的过程...

發布時間:2024/1/23 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux io映射,【原创】Linux 文件系统移植全解密以linux-2.6.35内核源码为例说明一下IO静态映射的过程... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近不斷有人跟我說起靜態映射的問題,今天就以linux-2.6.35內核源碼為例說明一下IO靜態映射的過程(ARM平臺)。

//init/main.c

asmlinkage void __init start_kernel(void){

...

setup_arch(&command_line);

...

}

//arch/arm/kernel/setup.c

void __init setup_arch(char **cmdline_p){

...

paging_init(mdesc);

...

}

//arch/arm/mm/mmu.c

void __init paging_init(struct machine_desc *mdesc){

...

devicemaps_init(mdesc);

...

}

//arch/arm/mm/mmu.c

static void __init devicemaps_init(struct machine_desc *mdesc){

...

if (mdesc->map_io) ?//回調map_io

mdesc->map_io();

...

}

//arch/arm/include/asm/mach/arch.h

struct machine_desc {

/*

* Note! The first four elements are used

* by assembler code in head.S, head-common.S

*/

unsigned int ? ? ? ?nr; ? ? ? ?/* architecture number ? ?*/

unsigned int ? ? ? ?phys_io; ? ?/* start of physical io ? ?*/

unsigned int ? ? ? ?io_pg_offst; ? ?/* byte offset for io page tabe entry ? ?*/

const char ? ? ? ?*name; ? ? ? ?/* architecture name ? ?*/

unsigned long ? ? ? ?boot_params; ? ?/* tagged list ? ? ? ?*/

unsigned int ? ? ? ?video_start; ? ?/* start of video RAM ? ?*/

unsigned int ? ? ? ?video_end; ? ?/* end of video RAM ? ?*/

unsigned int ? ? ? ?reserve_lp0 :1; ? ?/* never has lp0 ? ?*/

unsigned int ? ? ? ?reserve_lp1 :1; ? ?/* never has lp1 ? ?*/

unsigned int ? ? ? ?reserve_lp2 :1; ? ?/* never has lp2 ? ?*/

unsigned int ? ? ? ?soft_reboot :1; ? ?/* soft reboot ? ? ? ?*/

void ? ? ? ? ? ?(*fixup)(struct machine_desc *,struct tag *, char **,struct meminfo *);

void ? ? ? ? ? ?(*map_io)(void);/* IO mapping function ? ?*/

void ? ? ? ? ? ?(*init_irq)(void);

struct sys_timer ? ?*timer; ? ? ? ?/* system tick timer ? ?*/

void ? ? ? ? ? ?(*init_machine)(void);

};

該結構體對象初始化在對應板子的BSP文件中(這里以S5PC100平臺為例)

//arch/arm/mach-s5pc100/mach-smdkc100.c

MACHINE_START(SMDKC100, "SMDKC100")

/* Maintainer: Byungho Min */

.phys_io ? ?= S3C_PA_UART & 0xfff00000,

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

.boot_params ? ?= S5P_PA_SDRAM + 0x100,

.init_irq ? ?= s5pc100_init_irq,

.map_io ? ? ? ?= smdkc100_map_io,

.init_machine ? ?= smdkc100_machine_init,

.timer ? ? ? ?= &s3c24xx_timer,

MACHINE_END

//MACHINE_START宏定義在arch/arm/include/asm/mach/arch.h

#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 ? ? ? ? ? ? ? ?\

即struct machine_desc中的域.map_io登記為smdkc100_map_io

static void __init smdkc100_map_io(void)

{

s5p_init_io(NULL, 0, S5P_VA_CHIPID);

...

}

//arch/arm/plat-s5p/cpu.c

/* minimal IO mapping */

static struct map_desc s5p_iodesc[] __initdata = {

{

.virtual ? ?= (unsigned long)S5P_VA_CHIPID,

.pfn ? ? ? ?= __phys_to_pfn(S5P_PA_CHIPID),

.length ? ? ? ?= SZ_4K,

.type ? ? ? ?= MT_DEVICE,

}, {

.virtual ? ?= (unsigned long)S3C_VA_SYS,

.pfn ? ? ? ?= __phys_to_pfn(S5P_PA_SYSCON),

.length ? ? ? ?= SZ_64K,

.type ? ? ? ?= MT_DEVICE,

}, {

.virtual ? ?= (unsigned long)S3C_VA_UART,

.pfn ? ? ? ?= __phys_to_pfn(S3C_PA_UART),

.length ? ? ? ?= SZ_4K,

.type ? ? ? ?= MT_DEVICE,

}, {

.virtual ? ?= (unsigned long)VA_VIC0,

.pfn ? ? ? ?= __phys_to_pfn(S5P_PA_VIC0),

.length ? ? ? ?= SZ_16K,

.type ? ? ? ?= MT_DEVICE,

}, {

.virtual ? ?= (unsigned long)VA_VIC1,

.pfn ? ? ? ?= __phys_to_pfn(S5P_PA_VIC1),

.length ? ? ? ?= SZ_16K,

.type ? ? ? ?= MT_DEVICE,

}, {

.virtual ? ?= (unsigned long)S3C_VA_TIMER,

.pfn ? ? ? ?= __phys_to_pfn(S5P_PA_TIMER),

.length ? ? ? ?= SZ_16K,

.type ? ? ? ?= MT_DEVICE,

}, {

.virtual ? ?= (unsigned long)S5P_VA_GPIO,

.pfn ? ? ? ?= __phys_to_pfn(S5P_PA_GPIO),

.length ? ? ? ?= SZ_4K,

.type ? ? ? ?= MT_DEVICE,

},

};

/* read cpu identification code */

void __init s5p_init_io(struct map_desc *mach_desc,

int size, void __iomem *cpuid_addr){

unsigned long idcode;

/* initialize the io descriptors we need for initialization */

iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));

if (mach_desc)

iotable_init(mach_desc, size);

idcode = __raw_readl(cpuid_addr);

s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));

}

上面的 iotable_init函數完成IO映射。

結構體static struct map_desc定義在asm/io.h中

struct map_desc {

unsigned long virtual; //映射后的虛擬地址

unsigned long pfn; ? ? ?//被映射的物理地址所在頁幀號

unsigned long length;//被映射的IO資源長度

unsigned int type; ? ? ? ?//IO類型

};

這里比較難理解的是“映射后的虛擬地址virtual”,這個是自己定義的,可以修改,但是不能和已經映射的重復。

可以參看內核文檔\Documentation\arm\memory.txt,其中描述如下:

VMALLOC_START ? ?VMALLOC_END-1 ? ?vmalloc() / ioremap() space.

Memory returned by vmalloc/ioremap will

be dynamically placed in this region.

VMALLOC_START may be based upon the value

of the high_memory variable.

VMALLOC_START 定義在arch/arm/include/asm/pgtable.h中

/*

* Just any arbitrary offset to the start of the vmalloc VM area: the

* current 8MB value just means that there will be a 8MB "hole" after the

* physical memory until the kernel virtual memory starts. ?That means that

* any out-of-bounds memory accesses will hopefully be caught.

* The vmalloc() routines leaves a hole of 4kB between each vmalloced

* area for the same reason. ;)

*

* Note that platforms may override VMALLOC_START, but they must provide

* VMALLOC_END. ?VMALLOC_END defines the (exclusive) limit of this space,

* which may not overlap IO space.

*/

#ifndef VMALLOC_START

#define VMALLOC_OFFSET ? ? ? ?(8*1024*1024)

#define VMALLOC_START ? ? ? ?(((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))

#endif

S5PC100中IO映射從S3C_ADDR_BASE開始線性偏移

#define S3C_ADDR_BASE ? ?(0xF4000000)

總結

以上是生活随笔為你收集整理的linux io映射,【原创】Linux 文件系统移植全解密以linux-2.6.35内核源码为例说明一下IO静态映射的过程...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。