一:當我們開啟了MMU之後,使用的都是虛拟位址,這時就需要考慮實體位址到虛拟位址的映射問題。建立映射表的三個關鍵部分是:
(1)映射表
(2)映射表建立函數
(3)映射表建立函數被調用
1:映射表
(1)映射表是具體的實體位址和虛拟位址的起始位址定義,在我們前面使用靜态映射來操作LED時有介紹,三星版本的移植的核心,其主映射表在arch/arm/plat-s5p/include/plat/map-s5p.h和arch/arm/plat-samsung/include/plat/map-base.h中
arch/arm/plat-s5p/include/plat/map-s5p.h的主要内容如下
arch/arm/plat-samsung/include/plat/map-base.h的主要内容如下:
在這裡,我們指定了虛拟位址的基位址,也就是宏S3C_ADDR_BASE 0XFD000000,在我們開啟了MMU之後,其映射的虛拟位址都是根據這個基位址+偏移量來得到的某個具體的寄存器的,這樣當我們建立了映射之後,就可以直接操作虛拟位址來操作我們對應的寄存器,在這裡,也隻是映射了需要用到的寄存器的虛拟位址,假如要添加,則隻需在map-s5p.h中添加相應的映射即可。
(2)GPIO相關的主映射表位于:arch/arm/machs5pv210/include/mach/regs-gpio.h
GPIO的具體寄存器定義位于:arch/arm/mach-s5pv210/include/mach/gpio-bank.h
需要注意的是,不同版本的核心其映射表的位置是不同的,,但是一般都在arch/arm/xxx/map_xx.h檔案中
2:映射表的建立過程
上面,我們介紹了核心通過宏定義定義了很多寄存器對應虛拟位址的基位址,那麼這些宏是在哪被調用的呢,映射表又是如何被調用的呢。
答案就是kernel/arch/arm/mach-s5pv210/mach-smdkc110.c中的smdkc110_map_io函數。它的調用層級如下:
smdkc110_map_io
s5p_init_io
iotable_init
iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
iotable_init函數就是最終實作建立虛拟位址映射的函數。其中S5P_iodesc是一個數組,它裡面包括了我們上面用大量的宏定義得到的映射表。也就是說我們上面建立的宏都在這裡被使用到了。
是以當我們需要添加新的虛拟位址映射時隻需要做兩步
(1)在我們的map-s5p.h或者是map-base.h中添加相應的宏定義
(2)在我們的s5p_iodesc中添加相應的數組元素
3:映射表建立函數的調用過程
本文轉自 菜鳥養成記 51CTO部落格,原文連結:http://blog.51cto.com/11674570/1937462