Introduction: Recently, people have been talking to me about the problem of static mapping. Today, I will take the linux-2.6.35 kernel source code as an example to explain the process of IO static mapping (ARM platform).
//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) //callback 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);
};
The structure object is initialized in the BSP file of the corresponding board (here S5PC100 platform is taken as an example)
//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 macro definition in 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 That is, the field .map_io in struct machine_desc is registered as 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)); } The iotable_init function above completes the IO mapping. The structure static struct map_desc is defined in asm/io.h struct map_desc { unsigned long virtual; //Mapped virtual address unsigned long pfn; //The page frame number where the mapped physical address is located unsigned long length; //The length of the mapped IO resource unsigned int type; //IO type }; What is more difficult to understand here is the "mapped virtual address virtual", which is self-defined and can be modified, but cannot be repeated with the already mapped one. You can refer to the kernel document Documentationarmmemory.txt, which describes it as follows: 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 is defined in 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 The IO mapping in S5PC100 is linearly offset from S3C_ADDR_BASE #define S3C_ADDR_BASE (0xF4000000)
Previous article:Design of HDLC protocol controller based on FPGA+ARM architecture
Next article:Physical design of microprocessor chip in wireless fire monitoring system
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- [Anxinke NB-IoT Development Board EC-01F-Kit] 2. TCP connection and NATAPP intranet penetration
- Boa application - web page configuration A40i development board - Feiling domestic industrial-grade Allwinner A40i series dry goods sharing
- [Recruitment] Part-time electronic hardware engineer located in Pudong, Shanghai
- How to select a display detector
- Basic Working Principle of Brushless DC Motor
- Ant basic antenna array comes with PPT
- 【AT-START-F425 Review】+ ERTC and the implementation of electronic clock
- How to use FPGA coprocessor to realize algorithm acceleration
- 【Gravity:AS7341 Review】+Garbage Sorting Video
- Construction of CCS v5 software development environment for TMS320C6000