当前位置: 技术问答>linux和unix
s3c6410的patform中, PA與VA的問題..
来源: 互联网 发布时间:2016-12-02
本文导语: 請教一個問題,就是在s3c6410的patform中, PA與VA的問題.... 在s3c6410的spec中,定義register的位置為 0x70000000 開始, IRQ,LCD,...等也有 各自定義的位置, 但是在linux的kernel中,卻定義VA的位置如下.... #define S3C_ADDR_BASE (0xF4000000) #defi...
請教一個問題,就是在s3c6410的patform中, PA與VA的問題....
在s3c6410的spec中,定義register的位置為 0x70000000 開始, IRQ,LCD,...等也有
各自定義的位置, 但是在linux的kernel中,卻定義VA的位置如下....
#define S3C_ADDR_BASE (0xF4000000)
#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */
#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */
#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
#define S3C_VA_LCD S3C_ADDR(0x01100000) /* LCD */
#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x))
在以上定義中,
1. #define S3C_ADDR_BASE (0xF4000000), 0xF4000000為何定義這裡,如何告知kernel呢??
2. S3C_ADDR(0x00000000), S3C_ADDR(0x00100000), S3C_ADDR(0x00300000)....這些相對的offset是怎麼定義出來的呢??
謝謝....
|
我想#define S3C_ADDR_BASE (0xF4000000)
0xF4000000应该是这些硬件模块的基地址吧,而
#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */
#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */
#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
#define S3C_VA_LCD S3C_ADDR(0x01100000) /* LCD */
#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x))
应该是这些具体模块各自的偏移地址的首地址。
比如说memory control 模块的首地址应该是S3C_ADDR_BASE + S3C_VA_MEM S3C_ADDR,其他的模块的首地址计算方法也是类似的,至于“在s3c6410的spec中,定義register的位置為 0x70000000 開始”这个我也不知道为什么,这个需要看datasheet吧。
0xF4000000应该是这些硬件模块的基地址吧,而
#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */
#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */
#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
#define S3C_VA_LCD S3C_ADDR(0x01100000) /* LCD */
#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x))
应该是这些具体模块各自的偏移地址的首地址。
比如说memory control 模块的首地址应该是S3C_ADDR_BASE + S3C_VA_MEM S3C_ADDR,其他的模块的首地址计算方法也是类似的,至于“在s3c6410的spec中,定義register的位置為 0x70000000 開始”这个我也不知道为什么,这个需要看datasheet吧。
|
Linux规定,系统4G的空间的前面3G都是给用户态使用的,内核空间都在后1G,也就是0xc0000000到0xFFFFFFFF的地址空间。不管模块的物理地址在哪里,都可以通过MMU将其映射到期望的虚拟地址,楼主的0xF400_0000就是这个虚拟地址了。其实不一定非得是0xF400_0000,只要不和系统的其它映射冲突就可以了。至于各个模块的Offset问题,有了MMU,可以将其映射想映射的位置,因此Offset也是没有关系的。这些映射在start_kernel里面会通过map_io进行映射,因此系统是知道的。
当然映射也不是说可以乱映射的,ARM的最小映射单位是4K,因此两个模块的地址如果都在一个4K区域里面就没法映射开了。
楼主可以参看ARM的相关资料和Linux的内存管理方面的资料
当然映射也不是说可以乱映射的,ARM的最小映射单位是4K,因此两个模块的地址如果都在一个4K区域里面就没法映射开了。
楼主可以参看ARM的相关资料和Linux的内存管理方面的资料
|
想问一下你S3C2410_WTCON,跟踪之后 #define S3C2410_WTCON S3C_WDOGREG(0x00);
#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
#define S3C_ADDR_BASE (0xF4000000)
而wtcon的物理地址为0x7E004000,如何转换?
#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
#define S3C_ADDR_BASE (0xF4000000)
而wtcon的物理地址为0x7E004000,如何转换?
|
其实这个虚拟地址是你自己指定的,只要这个地址没有被使用,并且页对齐就可以了。你可以参考http://blog.chinaunix.net/space.php?uid=24517893&do=blog&id=164217中后面的几段,也许对你会有帮助。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。