Linux(Ram)

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.5\arch\arm\product\board_bu.c

Kernel Module

makefile

1
2
3
4
5
6
7
8
9
10
ARCH=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 Ram

1
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)

參考

參考-1

參考-2

參考-3

參考-4

參考-5

參考-6

參考-7

參考-8