Linux
Linux Kernel 通常放在 Ram 開頭 1 MB 的位置
利用 mmap 和 /dev/mem 來直接使用實體 ram
可利用 devmem 指令確認是否正確讀寫實體 ram
/dev/kmem : kernel virtual address (0x0 - 0xFFFFFFFF(4GB) )
/dev/mem : physical address (0x0 - 0x7FFFFFFF(2GB) )
特定 process 的 VMA(Virtual Memory Areas),可從 /proc/pid/maps 看到
以下欄位分別對應 vm_area_struct() 結構1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# cat /proc/1/maps
#start-end perm offset major:minor inode imagename
00008000-000a7000 r-xp 00000000 00:01 141 /bin/busybox
000af000-000b0000 rw-p 0009f000 00:01 141 /bin/busybox
000b0000-000b1000 rw-p 00000000 00:00 0
00dd5000-00dda000 rw-p 00000000 00:00 0 [heap]
b6eb9000-b6f0f000 r-xp 00000000 00:01 17 /lib/libuClibc-0.9.33.2.so
b6f0f000-b6f17000 ---p 00000000 00:00 0
b6f17000-b6f18000 r--p 00056000 00:01 17 /lib/libuClibc-0.9.33.2.so
b6f18000-b6f19000 rw-p 00057000 00:01 17 /lib/libuClibc-0.9.33.2.so
b6f19000-b6f1d000 rw-p 00000000 00:00 0
b6f1d000-b6f23000 r-xp 00000000 00:01 83 /lib/ld-uClibc-0.9.33.2.so
b6f28000-b6f2a000 rw-p 00000000 00:00 0
b6f2a000-b6f2b000 r--p 00005000 00:01 83 /lib/ld-uClibc-0.9.33.2.so
b6f2b000-b6f2c000 rw-p 00006000 00:01 83 /lib/ld-uClibc-0.9.33.2.so
bec5e000-bec7f000 rw-p 00000000 00:00 0 [stack]
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
DMA
配置一塊適合DMA的緩衝區,需靠核心的開機期參數配合,如原有32M,當 mem=31,
可用 dmabuf=ioremap(0x1f00000,0x100000) 來存取保留的1M記憶體
0x1f00000 = 31M,0x100000 = 1M
ioremap 需要用在 kernel module
System.map
Linux source code 目錄下編譯完會出現 System.map
內容等於實際在 kernel 中輸入 cat /proc/kallsyms
裡面內容表示某個變數或函式的 address
Cpu map
進入 Linux 之後,要使用實體記憶體
需要看 CPU Spec,Spec 會顯示 memory mapping 位置
例如在 Linux 下面 0x60000000 可能是對應實體 ram 的 0x0
如果沒有 DTS,則 driver init 寫在 linux-3.6.5archarmproductboard_bu.c
Kernel Module
makefile1
2
3
4
5
6
7
8
9
10ARCH=arm
COMPILER=/home/.../host/usr/bin/arm-linux- # 絕對路徑
KERNELDIR=../ProjectPath/linux-3.6.5
obj-m += hello.o
all:
make ARCH=arm CROSS_COMPILE=$(COMPILER) -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
Linux 下操作1
2
3
4
5
6
7
8# 載入 modules
insmod hello.ko
# 檢查是否成功載入
dmesg | tail -5
# 移除 modules
rmmod ./hello.ko
Test Ram1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29# 可用範圍
0x6000_0000 - (0m)
| 可用
0x6100_0000 - (16m)
| 不可用
0x6640_0000 - (100m)
| 可用
0x8580_0000 - (600m)
| 不可用
0x9200_0000 - (800m)
| 可用
0xDFFF_FFFF - (2048m)
# 對應 Ram
0x6000_0000 - (0m)
0x6100_0000 - (16m)
0x6640_0000 - (100m)
0x6C80_0000 - (200m)
0x72C0_0000 - (300m)
0x7900_0000 - (400m)
0x7F40_0000 - (500m)
0x8580_0000 - (600m)
0x8BC0_0000 - (700m)
0x9200_0000 - (800m)
0x9840_0000 - (900m)
0x9E80_0000 - (1000m)
0xBDC0_0000 - (1500m)
0xDD00_0000 - (2000m)
0xDFFF_FFFF - (2048m)
參考