Static mapping analysis based on S3C2410-ARM-Linux

Publisher:算法之手Latest update time:2016-08-13 Source: eefocusKeywords:S3C2410 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_TOUT0);   
 
   We can control peripheral registers in this way. Have you ever thought about how it is implemented?
 
   First analyze struct machine_desc (include/asm-arm/Mach/Arch.h)
This is a very important structure. The kernel uses machine_desc to control the initialization of architecture-related parts, including map_io, init_irq, init_machine, pthys_io, timer, etc.
   

 

struct machine_desc {
    /*
     * Note! The first five elements are used
     * by assembler code in head-armv.S
     */
    unsigned int        nr;        /* architecture number    */
    unsigned int        phys_ram;    /* start of physical ram */
    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);
};

 

   So how do we create our own machine_desc?
    The kernel provides us with a macro:
 

 

#define MACHINE_START(_type,_name)        /
const struct machine_desc __mach_desc_##_type    /
 __attribute__((__section__(".arch.info.init"))) = {    /
    .nr        = MACH_TYPE_##_type,    /
    .name        = _name,
#define MACHINE_END                /
};

 


So we can define our own 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

 

Here we create machine_desc and assign values ​​to some of its members. This is equivalent to the programming interface provided by the kernel so that we can call our own functions.

Among them, map_io is called in setup_arch. If we follow it, we will find:

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

 

void __init iotable_init(struct map_desc *io_desc, int nr)
{
    int i;
    for (i = 0; i < nr; i++)
        create_mapping(io_desc + i);
}

 

It is here that create_mapping() is called to create the page table. The first parameter, map_desc, is defined as follows:

 

struct map_desc {
    unsigned long virtual;
    unsigned long physical;
    unsigned long length;
    unsigned int type;
};

 

create_mapping() is a mapping table created by this structure, so we can create the corresponding virtual address --> physical address mapping by creating map_desc and passing it to this function.

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

Defines macros for each resource used in the map_desc variable, such as:

 

/* MMC controller - available on the S3C2400 */
#define S3C2400_VA_MMC      S3C2400_ADDR(0x00700000)
#define S3C2400_PA_MMC      (0x15A00000)
#define S3C2400_SZ_MMC      SZ_1M

/* UARTs */
#define S3C24XX_VA_UART     S3C2410_ADDR(0x00800000)
#define S3C2400_PA_UART     (0x15000000)
#define S3C2410_PA_UART     (0x50000000)
#define S3C24XX_SZ_UART     SZ_1M

/* Timers */
#define S3C24XX_VA_TIMER S3C2410_ADDR(0x00900000)
#define S3C2400_PA_TIMER (0x15100000)
#define S3C2410_PA_TIMER (0x51000000)
#define S3C24XX_SZ_TIMER SZ_1M

 

 

Then for a specific peripheral, there is a definition of specific registers, such as:

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 $"

#define S3C2410_TIMERREG(x) (S3C24XX_VA_TIMER + (x))
#define S3C2410_TIMERREG2(tmr,reg) S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c))

#define S3C2410_TCFG0     S3C2410_TIMERREG(0x00)
#define S3C2410_TCFG1     S3C2410_TIMERREG(0x04)
#define S3C2410_TCON     S3C2410_TIMERREG(0x08)

#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
#define S3C2410_TCFG_DEADZONE_MASK (255<<16)
#define S3C2410_TCFG_DEADZONE_SHIFT (16)
.........................

 

Keywords:S3C2410 Reference address:Static mapping analysis based on S3C2410-ARM-Linux

Previous article:Memory Management of S3C2440
Next article:Introduction to ARM DSP X86 POWERPC MIPS FPGA

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号