ARM 架構下,Linux 核心將周邊暫存器映射至核心虛擬位址空間。arch/arm/plat-samsung/include/plat/map-base.h 定義了 Samsung 平台的基礎映射巨集與常用虛擬位址常數。
#define S3C_ADDR_BASE (0xF4000000)
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
#else
#define S3C_ADDR(x) (S3C_ADDR_BASE + (x))
#endif
S3C_ADDR_BASE 設為 0xF4000000,留出足夠空間給 vmalloc 區。S3C_ADDR(x) 將實體位址偏移轉換為核心虛擬位址,C 語言與組合語言版本略有不同。
| 巨集 | 虛擬位址 | 對應實體偏移 | 功能 |
|---|---|---|---|
| S3C_VA_IRQ | 0xF4000000 | 0x00000000 | 中斷控制器 |
| S3C_VA_SYS | 0xF4100000 | 0x00100000 | 系統控制 |
| S3C_VA_MEM | 0xF4200000 | 0x00200000 | 記憶體控制器 |
| S3C_VA_TIMER | 0xF4300000 | 0x00300000 | 定時器區塊 |
| S3C_VA_WATCHDOG | 0xF4400000 | 0x00400000 | 看門狗 |
| S3C_VA_OTG | 0xF4E00000 | 0x00E00000 | USB OTG |
| S3C_VA_OTGPHY | 0xF4F00000 | 0x00F00000 | OTG PHY |
| S3C_VA_UART | 0xF5000000 | 0x01000000 | UART 序列埠 |
| S3C_VA_RTC | 0xF4C00000 | 0x00C00000 | 即時時鐘 |
#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x))
保留 0x00500000~0x00DFFFFF 區間供特定 CPU 實作(如 S3C2410/S3C6410/S5P 等)擴充專用暫存器映射,避免汙染通用定義。
驅動程式中直接引用巨集進行 ioremap 或存取:
void __iomem *uart_base = S3C_VA_UART; // 已映射區域可直接使用
writel(val, uart_base + UART_OFFSET);
ioremap,存取效率最高。S3C_ADDR_CPU 機制讓新 SoC 只需補充專屬偏移,不修改通用標頭檔。此檔案是 Samsung ARM 平台所有驅動開發的基石,熟悉映射分佈能快速定位暫存器位址並除錯記憶體存取錯誤。