浅析armlinux-paging_init()->at91rm9200_map_io()函数5-3
文章来源:http://gliethttp.cublog.cn
建议首先参考《浅析armlinux2_4_19启动程序[head-armv.s文件]》[http://gliethttp.cublog.cn]
//---------------------------------------- //1.arch/arm/mach-at91rm9200/Core.c->at91rm9200_map_io() static struct map_desc at91rm9200_io_desc[] __initdata = { /* virtual, physical, length, domain, r, w, c, b */ { AT91C_VA_BASE_SYS, AT91C_BASE_SYS, SZ_4K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_SPI, AT91C_BASE_SPI, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_SSC2, AT91C_BASE_SSC2, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_SSC1, AT91C_BASE_SSC1, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_SSC0, AT91C_BASE_SSC0, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_US3, AT91C_BASE_US3, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_US2, AT91C_BASE_US2, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_US1, AT91C_BASE_US1, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_US0, AT91C_BASE_US0, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_EMAC, AT91C_BASE_EMAC, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_TWI, AT91C_BASE_TWI, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_MCI, AT91C_BASE_MCI, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_UDP, AT91C_BASE_UDP, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_TCB1, AT91C_BASE_TCB1, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, { AT91C_VA_BASE_TCB0, AT91C_BASE_TCB0, SZ_16K, DOMAIN_IO, 0, 1, 0, 0}, LAST_DESC }; //---------------------------------------- //2. //#define LAST_DESC { last: 1 } /* * Serial port configuration. * 0 .. 3 = USART0 .. USART3 * 4 = DBGU */ //#define AT91C_UART_MAP { 4, 1, -1, -1, -1 }/* ttyS0, ..., ttyS4 */ //#define AT91C_CONSOLE 0/* ttyS0 */ void __init at91rm9200_map_io(void) {int serial[AT91C_NR_UART] = AT91C_UART_MAP; int i; iotable_init(at91rm9200_io_desc);//映射控制寄存器的虚拟地址和物理地址对应关系 /* Register UARTs */ for (i = 0; i < AT91C_NR_UART; i++) { if (serial[i] >= 0) at91_register_uart(i, serial[i]); } } //---------------------------------------- //3.arch/arm/mm/Mm-armv.c->iotable_init() void __init iotable_init(struct map_desc *io_desc) {int i; for (i = 0; io_desc[i].last == 0; i++) //请参见《浅析armlinux-setup_arch()->create_mapping()函数5-2-2》[http://gliethttp.cublog.cn] //按照映射表at91rm9200_io_desc[]映射at91rm9200处理器的所有控制寄存器虚拟地址和物理地址的对应关系 create_mapping(io_desc + i); } //---------------------------------------- //4.drivers/at91/serial/At91_serial.c->at91_register_uart() void __init at91_register_uart(int idx, int port) { if ((idx < 0) || (idx >= AT91C_NR_UART)) { printk(KERN_ERR __FUNCTION__ ": bad index number %d\n", idx); return; } at91_ports[idx].iotype = SERIAL_IO_MEM; at91_ports[idx].flags = ASYNC_BOOT_AUTOCONF; at91_ports[idx].uartclk = AT91C_MASTER_CLOCK; at91_ports[idx].ops = &at91_pops;//登记串口统一操作集 at91_ports[idx].fifosize = 0; switch (port) { case 0: at91_ports[idx].membase = (void *) AT91C_VA_BASE_US0; at91_ports[idx].mapbase = AT91C_VA_BASE_US0;//虚拟基址 at91_ports[idx].irq = AT91C_ID_US0;//串口0的中断id号 AT91_CfgPIO_USART0();//很简单将io口配置串口模式 break; case 1: at91_ports[idx].membase = (void *) AT91C_VA_BASE_US1; at91_ports[idx].mapbase = AT91C_VA_BASE_US1; at91_ports[idx].irq = AT91C_ID_US1; AT91_CfgPIO_USART1();//很简单将io口配置串口模式 break; case 2: at91_ports[idx].membase = (void *) AT91C_VA_BASE_US2; at91_ports[idx].mapbase = AT91C_VA_BASE_US2;//虚拟基址 at91_ports[idx].irq = AT91C_ID_US2;//串口2的中断id号 AT91_CfgPIO_USART2(); break; case 3: at91_ports[idx].membase = (void *) AT91C_VA_BASE_US3; at91_ports[idx].mapbase = AT91C_VA_BASE_US3;//虚拟基址 at91_ports[idx].irq = AT91C_ID_US3;//串口3的中断id号 AT91_CfgPIO_USART3(); break; case 4: at91_ports[idx].membase = (void *) AT91C_VA_BASE_DBGU; at91_ports[idx].mapbase = AT91C_VA_BASE_DBGU;//虚拟基址 at91_ports[idx].irq = AT91C_ID_SYS;//dbgu的中断id号 AT91_CfgPIO_DBGU(); break; default: printk(KERN_ERR __FUNCTION__ ": bad port number %d\n", port); } }
|