linux内核驱动学习(八)----驱动分类 | 学习方法 | 硬件访问
驱动分类:
驱动学习方法:
硬件访问:
一、地址映射
struct map_desc { unsigned long virtual; /* 映射后的虚拟地址 */ unsigned long pfn; /* 物理地址所在的页帧号 */ unsigned long length; /* 映射长度 */ unsigned int type; /* 映射的设备类型 */ };
pfn: 利用 __phys_to_pfn(物理地址)可以计算出物理地址所在的物理页帧号
/* minimal IO mapping */ static struct map_desc s3c_iodesc[] __initdata = { { .virtual = (unsigned long)S3C_VA_SYS, .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON), .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_MEM, .pfn = __phys_to_pfn(S3C64XX_PA_SROM), .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS), .pfn = __phys_to_pfn(S3C_PA_UART), .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)VA_VIC0, .pfn = __phys_to_pfn(S3C64XX_PA_VIC0), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = (unsigned long)VA_VIC1, .pfn = __phys_to_pfn(S3C64XX_PA_VIC1), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_TIMER, .pfn = __phys_to_pfn(S3C_PA_TIMER), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C64XX_VA_GPIO, .pfn = __phys_to_pfn(S3C64XX_PA_GPIO), .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C64XX_VA_MODEM, .pfn = __phys_to_pfn(S3C64XX_PA_MODEM), .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_WATCHDOG, .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG), .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_USB_HSPHY, .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY), .length = SZ_1K, .type = MT_DEVICE, }, };
/* read cpu identification code */ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) { unsigned long idcode; /* initialise the io descriptors we need for initialisation */ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); //建立映射 iotable_init(mach_desc, size); idcode = __raw_readl(S3C_VA_SYS + 0x118); if (!idcode) { /* S3C6400 has the ID register in a different place, * and needs a write before it can be read. */ __raw_writel(0x0, S3C_VA_SYS + 0xA1C); idcode = __raw_readl(S3C_VA_SYS + 0xA1C); } s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); }
二、寄存器读写
/* read cpu identification code */ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) { unsigned long idcode; /* initialise the io descriptors we need for initialisation */ iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); //建立映射 iotable_init(mach_desc, size); idcode = __raw_readl(S3C_VA_SYS + 0x118); if (!idcode) { /* S3C6400 has the ID register in a different place, * and needs a write before it can be read. */ __raw_writel(0x0, S3C_VA_SYS + 0xA1C); idcode = __raw_readl(S3C_VA_SYS + 0xA1C); } s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。