포럼 회원으로 등록하신분만 다운로드가 가능합니다. 최대 업로드 가능한 용량은 20MB 입니다.
현재 최신 삼성 계열의 프로세서는 U-Boot에서 MMU를 매핑 합니다.
과거 S3C24XX나 XScale 등의 프로세서를 사용하셨던 분들은 부트로더에서 MMU 매핑에 대해 거부감이 있습니다.
따라서 다음의 코드를 보셔서, MMU 매핑 코드에 대해 이해하시면 될 듯 힙니다.
1. FL_SECTION_ENTRY
FL_SECTION_ENTRY 스크립트는 MMU에서 도메인, 캐시, 버퍼 및 퍼미션에 대한 권한을 설정해주는 매크로 입니다.
이것은, ARM Reference Manual의 MMU에도 동일하게 기술되어 있습니다.
보통 U-Boot와 같은 펌웨어의 MMU 매핑 이전에 꼭 한번은 반드시 기술되는 스크립트 입니다.
// form a first-level section entry
.macro FL_SECTION_ENTRY base,x,ap,p,d,c,b
.word (base << 20) | (x << 12) | (ap << 10) | (p << 9) |
(d << 5) | (c << 3) | (b << 2) | 2
.endm
base: section base address
x: not used
ap: access permission, 3 -- Read/Write
p: not used
d: Domain 0 -- No access
c: Cachable 1 -- enable 0 -- disable
b: Bufferable 1 -- enable 0 -- disable
Bit[1:0]: Identify the type of descriptor 2 -- section descriptor
2. MMU 매핑 테이블 예제
다음은 WinCE와 비슷한 MMU 매핑 테이블 예제이며, 여기에서는 CPU에 다음과 같이 MMU를 매핑 한다고 가정 합니다.
The total mapping like this,
// This page table sets up the preferred mapping:
//
// Virtual Address Physical Address XCB Size (MB) Description
// --------------- ---------------- --- --------- -----------
// 0x00000000 0x00000000 010 32 SDRAM (cached)
// 0x10000000 0x10000000 000 32 SDRAM (alias)
// 0x20000000 0x00000000 000 32 SDRAM (uncached)
// 0x48000000 0x48000000 000 64 PCI Data
// 0x50000000 0x50000000 010 16 Flash (CS0)
// 0x51000000 0x51000000 000 112 CS1 - CS7
// 0x60000000 0x60000000 000 64 Queue Manager
// 0xC0000000 0xC0000000 000 1 PCI Controller
// 0xC4000000 0xC4000000 000 1 Exp. Bus Config
// 0xC8000000 0xC8000000 000 1 Misc IXP425 IO
// 0xCC000000 0xCC000000 000 1 SDRAM Config
3. MMU 매핑 방법
위의 테이블에서 보면, 물리 0x2000_00000 번지를 0x0000_0000 번지로 Uncahed Buffer 타입으로 매핑 합니다.
이 외의 번지들은 1:1 매핑 처리 합니다. 코드는 다음과 같습니다.
// 32MB SDRAM (uncached)
.set __base,0x000 ;; map to 0x0000000
.rept 0x240 - 0x200 ;; virtual from 0x20000000 -- 0x24000000
FL_SECTION_ENTRY __base,0,3,0,0,0,0 ;; c = 0 uncached
.set __base,__base+1
.endr
위의 코드에서 보면, MMU 테이블의 0x0 번지부터 Data를 채워 나가며, __base는 가상 0x0 번지에,
매핑할 물리 주소의 데이터를 채워 넣는 것 입니다.
.rept와 endr은, C언어에서 for 문이라고 생각하시면 됩니다.
.rept 0x240 - 0x200은 0x240 - 0x200 = 0x40 즉, 0x40 만큼 위의 루프를 반복한다는 뜻이며,
.set __base, base__+1은 MMU의 가상 번지를 1씩 증가하며 매핑할 물리 주소 데이터를 채워 넣어간다는 뜻 입니다.
4. 정리
1) MMU는 MMU 매핑 테이블을 저장할 메모리 베이스 어드레스 번지를 우선 지정 해야 하며, 형식은 다음과 같습니다.
보통 MMU 메핑 태이블은 offsets + 0x4000 번지에 위치하며 형식은 다음과 같습니다.
// Set the TTB register to DRAM mmu_table
ldr r0, =(SDRAM_PHYS_BASE | 0x4000) // RAM tables
mcr p15, 0, r0, c2, c0, 0 // load page table pointer
2) 다음 코드의 형식으로 지정된 MMU 테이블에 데이터를 채우게 됩니다. 다음은 Windows CE의 코드이나,
리눅스에서도 동일 합니다.
code in hal_platform_extras.h
Notes: In this code, the physical address for every access is equle to its virtual address,This is known as a "flat address mapping".
code explains:
// 64MB SDRAM
.set __base,0x000 ;; set a symbol __base as value 0
.rept 0x040 - 0x000 ;; repeat the next data (FL_SECTION_ENTRY __base,0,3,0,0,1,0) from 0x000 to 0x040
FL_SECTION_ENTRY __base,0,3,0,0,1,0 ;; this is 32bit value as "First Level descriptor format"
.set __base,__base+1 ;; __base++ until 0x40
.endr
// 202MB Unused
.rept 0x100 - 0x080
.word 0
.set __base,__base+1
.endr
So this code fill 0x40*32bit (0x100Byte) mmu_table buffer.
Every entry mapping/translate 1Mbyte memory.
// form a first-level section entry
.macro FL_SECTION_ENTRY base,x,ap,p,d,c,b
.word (base << 20) | (x << 12) | (ap << 10) | (p << 9) |
(d << 5) | (c << 3) | (b << 2) | 2
.endm
base: section base address
x: not used
ap: access permission, 3 -- Read/Write
p: not used
d: Domain 0 -- No access
c: Cachable 1 -- enable 0 -- disable
b: Bufferable 1 -- enable 0 -- disable
Bit[1:0]: Identify the type of descriptor 2 -- section descriptor
After you dump the elf, it looks like that:
4000: 00000c0a
4004: 00100c0a
4008: 00200c0a
400c: 00300c0a
4010: 00400c0a
4014: 00500c0a
4018: 00600c0a
401c: 00700c0a
4020: 00800c0a
4024: 00900c0a
4028: 00a00c0a
402c: 00b00c0a
4030: 00c00c0a
4034: 00d00c0a
4038: 00e00c0a
403c: 00f00c0a
4040: 01000c0a
4044: 01100c0a
4048: 01200c0a
404c: 01300c0a
4050: 01400c0a
4054: 01500c0a
4058: 01600c0a
405c: 01700c0a
4060: 01800c0a
4064: 01900c0a
4068: 01a00c0a
406c: 01b00c0a
4070: 01c00c0a
4074: 01d00c0a
4078: 01e00c0a
407c: 01f00c0a
4080: 02000c0a
4084: 02100c0a
4088: 02200c0a
408c: 02300c0a
4090: 02400c0a
4094: 02500c0a
4098: 02600c0a
409c: 02700c0a
40a0: 02800c0a
40a4: 02900c0a
40a8: 02a00c0a
40ac: 02b00c0a
40b0: 02c00c0a
40b4: 02d00c0a
40b8: 02e00c0a
40bc: 02f00c0a
40c0: 03000c0a
40c4: 03100c0a
40c8: 03200c0a
40cc: 03300c0a
40d0: 03400c0a
40d4: 03500c0a
40d8: 03600c0a
40dc: 03700c0a
40e0: 03800c0a
40e4: 03900c0a
40e8: 03a00c0a
40ec: 03b00c0a
40f0: 03c00c0a
40f4: 03d00c0a
40f8: 03e00c0a
40fc: 03f00c0a
4100: 00000000
4104: 00000000
4108: 00000000
410c: 00000000
4110: 00000000
4114: 00000000
4118: 00000000
411c: 00000000
안녕하세요, 최신 u-boot에 s5pc1xx 코드가 반영되었습니다. 여기에는 MMU를 사용하지 않습니다.
참고하시기 바랍니다.
http://git.denx.de/?p=u-boot/u-boot-samsung.git;a=summary