In the process of porting Linux to the target board, a static mapping of the physical address of the peripheral I/O memory to the virtual address is usually established:
//The structure used is struct map_desc {unsigned long virtual; //virtual address unsigned long pfn; //__ phys_to_pfn (physical address), is the physical page frame number unsigned long length; //size unsigned int type; //type};
Here is the plat level map_io:
in linux/arch/arm/plat-s5p/cpu.c:
/* table of supported CPUs supported cpu types*/static const char name_s5pv210 [] = " S5PV210 /S5PC110 "; static struct cpu_table cpu_ids [] __initdata = {{.idcode = 0x43110000, .idmask = 0xfffff000, .map_io = s5pv210_map_io, //this is the mach level map_io.init_clocks = s5pv210_init_clocks, .init_uarts = s5pv210_init_uarts, .init = s5pv210_init, .name = name_s5pv210,},};
/* 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, //The size of the page in ARM Is 4K, so this length must be a multiple of the .type 4K = 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,}, { .virtual = (unsigned long) S3C_VA_WATCHDOG, .pfn = __phys_to_pfn (S5P_PA_WDT) ,. length = SZ_4K, .type = MT_DEVICE,}, {.virtual = (unsigned long) S3C_VA_OTG, .pfn = __phys_to_pfn (S5P_PA_OTG) ,. length = SZ_1M,.type = MT_DEVICE,}, {.virtual = (unsigned long)S3C_VA_OTGPHY,.pfn = __ph ys_to_pfn (S5P_PA_OTGPHY) ,. length = SZ_1M, .type = MT_DEVICE,},};
void __init s5p_init_io (struct map_desc * mach_desc, int size, void __iomem * cpuid_addr) {/* initialize the io descriptors we need for initialization * /iotable_init (s5p_iodesc, ARRAY_SIZE (s5p_iodesc)); //ultimately establish the function of the page map (here mainly is a plat level map_io)
idcode = __raw_readl ( Cpuid_addr);s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); //This function will eventually call mach level map_io}
/kernel/arch/arm/mach-s5pv210 /mach-smdkv210.c in which: //initialize the plate called static void __init smdkv210_map_io (void) {s5p_init_io (NULL, 0, S5P_VA_CHIPID); .....} MACHINE_START (SMDKV210, " smdkv210 ") phys_io = S3C_PA_UART. & 0xfff00000, .io_pg_offst = (((u32) S3C_VA_UART) & gt; & gt; 18) & 0xfffc, .boot_params = S5P_PA_SDRAM + 0x100, .fixup = s5pv210_fixup, .init_irq = s5pv210_init_irq, .map_io = smdkv210_map_io, .init_machine = smdkv210_machine_init ,.timer = &s5p_systim Er,MACHINE_END
After this, when the device driver accesses the statically mapped I/O memory, it can directly add the offset to the corresponding virtual address, without using ioremap(). . But I tried using ioremap(), I don't know if it is wrong? ? ?
Additional (mach level map_io ):
in the linux /arch /arm /mach-s5pv210 /cpu.c in:
/* Initial IO mappings * /static struct map_desc s5pv210_iodesc [] __initdata = {{.virtual = (unsigned long) S5P_VA_SYSTIMER, .pfn = __phys_to_pfn (S5PV210_PA_SYSTIMER) ,. length = SZ_1M, .type = MT_DEVICE,}, {.virtual = (unsigned long) VA_VIC2, .pfn = __phys_to_pfn (S5PV210_PA_VIC2) ,. length = SZ_16K ,. type = MT_DEVICE,}, {.virtual = (unsigned long) VA_VIC3, .pfn = __phys_to_pfn (S5PV210_PA_VIC3) ,. length = SZ_16K, .type = MT_DEVICE,}, {.virtual = (unsigned long) S5P_VA_SROMC, .pfn = __phys_to_pfn (S5PV210_PA_SROMC) ,. length = SZ_4K, .type = MT_DEVICE,}, {.virtual = (unsigned long) S5P_VA_AUDSS, .pfn = __phys_to_pfn (S5PV210_PA_AUDSS) ,. length = SZ_1M, .type = MT_DEVICE,}, {.virtual = (unsigned long) S5P_VA_DMC0, .pfn = __phys_to_pfn (S5PV210_PA_DMC0) ,. length = SZ_4K, .type = MT_DEVICE,}, {.virtual = (unsigned long) S5P_VA_DMC1, .pfn = __phys_to_pfn (S5PV210_PA_DMC1) ,. le ngth = SZ_4K, .type = MT_DEVICE,}};
/* s5pv210_map_io ** register the standard cpu IO areas * /void __init s5pv210_map_io (void) {iotable_init (s5pv210_iodesc, ARRAY_SIZE (s5pv210_iodesc));} < Br>
A.Linux files can be divided into four types: ordinary files, directory files, link files, and devi
Managing the performance of a Linux host often seems like magic. Many administrat
1. When Liunx just started rebooting. Here we press the “e” key to enter the Grub config
According to foreign media reports, many users, like the author, have been intere
Linux Squid build transparent proxy gateway server
How to let CentOS automatically install rar and unrar
Easily build your own DNS server under Linux
Linux under the lack of boot space solution
Neighbor subsystem of linux protocol stack (related process 5)
Linux operating system startup process detailed
Install ADSL Internet Dialer under SUSE Linux
Centos6 opens the disk quota function of the EXT4 file system
Telecom User VPN Dial-in Service Settings
Linux View Port Status and Close Port Method
Add a password to the Apache directory under the Linux operating system
Linux shell different binary data conversion (binary, octal, hexadecimal, base64)
Windows7 Ultimate system under the local connection is missing how to solve
Introduction to Windows Server 2008 Failover Clustering
What happens when Win7 is invaded by malware?
Win7 system double-click can not open the folder but enter the search interface how to do?
Win8 cloud connection: Microsoft cloud is no longer a problem
How to win special characters in win8?
Win7 upgrade key input error modification method
Install win7 & ubuntu10.04 pain
How to cancel Win10 "Do you want to modify the computer to modify the computer" prompt