您的位置 首页 编程

根据S3C2410-ARM-Linux静态映射剖析

s3c2410_gpio_cfgpin(S3C2410_GPB0,S3C2410_GPB0_TOUT0);我们可以这样控制外设寄存器,想过它怎么实现的吗?首先分析下structmachi…

s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_TOUT0);

咱们能够这样操控外设寄存器,想过它怎样完成的吗?
首要剖析下structmachine_desc (include/asm-arm/Mach/Arch.h)
这是一个非常重要的结构体,内核经过 machine_desc 来操控系统架构相关部分的初始化,包含map_io,init_irq,init_machine,pthys_io,timer等

structmachine_desc{
/*
* Note! The first five elements are used
* by assembler code in head-armv.S
*/
unsignedintnr;/* architecture number*/
unsignedintphys_ram;/* start of physical ram */
unsignedintphys_io;/* start of physical io*/
unsignedintio_pg_offst;/* byte offset for io
* page tabe entry*/
constchar*name;/* architecture name*/
unsignedlongboot_params;/* tagged list*/
unsignedintvideo_start;/* start of video RAM*/
unsignedintvideo_end;/* end of video RAM*/
unsignedintreserve_lp0:1;/* never has lp0*/
unsignedintreserve_lp1:1;/* never has lp1*/
unsignedintreserve_lp2:1;/* never has lp2*/
unsignedintsoft_reboot:1;/* soft reboot*/
void(*fixup)(structmachine_desc*,
structtag*,char**,
structmeminfo*);
void(*map_io)(void);/* IO mapping function*/
void(*init_irq)(void);
structsys_timer*timer;/* system tick timer*/
void(*init_machine)(void);
};

那咱们怎样创立自己的machine_desc呢?
内核给咱们供给了一个宏:

#defineMACHINE_START(_type,_name)/
conststructmachine_desc __mach_desc_##_type/
__attribute__((__section__(“.arch.info.init”)))={/
.nr=MACH_TYPE_##_type,/
.name=_name,
#defineMACHINE_END/
};

这样咱们就能够界说自己的machine_desc了

MACHINE_START(SMDK2410,”SMDK2410″)/* @TODO: request a new identifier and switch
* to SMDK2410 */
/* Maintainer: Jonas Dietsche */
.phys_ram=S3C2410_SDRAM_PA,
.phys_io=S3C2410_PA_UART,
.io_pg_offst=(((u32)S3C24XX_VA_UART)>>18)&0xfffc,
.boot_params=S3C2410_SDRAM_PA+0x100,
.map_io=smdk2410_map_io,
.init_irq=smdk2410_init_irq,
.init_machine=sdmk2410_init,
.timer=&s3c24xx_timer,
MACHINE_END

这儿咱们创立了 machine_desc,并给其间一些成员赋了值,这适当所以内核给咱们供给的编程接口,这样就能够调用自己的函数了。

这其间map_io 在 setup_arch 中调用调用,咱们跟进去会发现:

在smdk2410_map_io–>s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc))->iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)) 看到:

void__init iotable_init(structmap_desc*io_desc,intnr)
{
inti;
for(i=0;icreate_mapping(io_desc+i);
}

便是在这儿调用create_mapping()创立的页表,这儿的第一个参数,map_desc 界说如下:

structmap_desc{
unsignedlongvirtual;
unsignedlongphysical;
unsignedlonglength;
unsignedinttype;
};

create_mapping()便是经过这个结构体创立的映射表,这样咱们能够经过创立 map_desc 然后传给这个函数就能够创立相应的 虚拟地址–>物理地址 映射.

在 inlcude/asm-arch/Arch-s3c2410/Map.h

界说了每一种资源用于 map_desc变量的宏界说,如:

/* MMC controller – available on the S3C2400 */
#defineS3C2400_VA_MMC S3C2400_ADDR(0x00700000)
#defineS3C2400_PA_MMC (0x15A00000)
#defineS3C2400_SZ_MMC SZ_1M

/* UARTs */
#defineS3C24XX_VA_UART S3C2410_ADDR(0x00800000)
#defineS3C2400_PA_UART(0x15000000)
#defineS3C2410_PA_UART(0x50000000)
#defineS3C24XX_SZ_UART SZ_1M

/* Timers */
#defineS3C24XX_VA_TIMER S3C2410_ADDR(0x00900000)
#defineS3C2400_PA_TIMER(0x15100000)
#defineS3C2410_PA_TIMER(0x51000000)
#defineS3C24XX_SZ_TIMER SZ_1M

然后针对详细的某个外设,有详细寄存器的界说,如:

include/asm/arch-s3c2410/regs-timer.h

#ifndef__ASM_ARCH_REGS_TIMER_H
#define__ASM_ARCH_REGS_TIMER_H”$Id: timer.h,v 1.4 2003/05/06 19:30:50 ben Exp $”

#defineS3C2410_TIMERREG(x)(S3C24XX_VA_TIMER+(x))
#defineS3C2410_TIMERREG2(tmr,reg)S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c))

#defineS3C2410_TCFG0 S3C2410_TIMERREG(0x00)
#defineS3C2410_TCFG1 S3C2410_TIMERREG(0x04)
#defineS3C2410_TCON S3C2410_TIMERREG(0x08)

#defineS3C2410_TCFG_PRESCALER0_MASK(255<<0)
#defineS3C2410_TCFG_PRESCALER1_MASK(255<<8)
#defineS3C2410_TCFG_PRESCALER1_SHIFT(8)
#defineS3C2410_TCFG_DEADZONE_MASK(255<<16)
#defineS3C2410_TCFG_DEADZONE_SHIFT(16)
…………………….

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部