망고210에서 플랫폼 디바이스의 등록 절차 및 작성 방식을 나름대로 정리
물리주소 <=> 가상주소 매핑은 ppt파일에 따로 없다.
가상주소와 물리주소는 MMU Table을 통해 서로 연결된다.
디바이스 제어와 같이 특수한 상황에서는 물리주소에 직접 접근을 해야할 필요성이 존재.
=> 보통 arch/arm/target/cpu.c 에서 매핑을 하는 커널 API를 사용.
ex)
#include <sam/page.h>
#include <asm/memory.h>
void *phys_to_virt(unsigned long address); // 물리 => 가상 변환
unsigned long virt_to_phys(volatile void *address); // 가상 => 물리 변환
- 실제 망고보드에서 매핑의 예
./cpu.c: .pfn = __phys_to_pfn(S5PV210_PA_RTC),
./cpu.c: .pfn = __phys_to_pfn(S5P_PA_DMC0),
./cpu.c: .pfn = __phys_to_pfn(S5P_PA_DMC1),
./cpu.c: .pfn = __phys_to_pfn(S5PV210_PA_AUDSS),
./cpu.c: .pfn = __phys_to_pfn(S5PV210_PA_BUS_AXI_DSYS),
MMU가 존재하는 시스템의 경우 프로세서에서 사용하는 주소는 가상주소
따라서 물리주소에 직접 접근할 필요성이 있고 위와같이 cpu.c에 물리 <=> 가상 매핑이 되어 있는 경우
User level에서는 mmap()함수를 이용한 접근이 가능하고
Kernel level에서는 ioremap()함수를 이용한 접근을 한다.
또 다른 방법으로는
리눅스 커널에서는 물리 주소를 사용 할 수 없다. 가상 주소를 사용 한다. 페이징(Paging)이라는 기법을 써서 가상 주소를 물리 주소로 변환한다. 디바이스 I/O 하기 위해서 물리 주소를 가상 주소로 매핑해주어야 한다. 타겟에서 사용하는 디바이스의 I/O 물리 주소를 가상 정보로 매핑하는 정보를 작성한다.
static struct map_desc w5300e01_iodesc[] __initdata = { { 0xf0000000, __phys_to_pfn(S3C2410_CS2), SZ_1M, MT_DEVICE }, { 0xf8000000, __phys_to_pfn(S3C2410_CS3), SZ_1M, MT_DEVICE } }; |
(가상주소), (물리 메모리 페이지 프레임 번호), (크기), (타입) 순이다. '__phys_to_pfn()' 함수는 물리 주소를 페이지 프레임 번호로 변환해준다.
ioremap()함수와 phys_to_virt()함수는, 둘다 물리주소를 가상주소로 바꿀때 쓰인다. 하지만 차이점은 존재한다. ioremap()함수는 요구된 물리 주소로 시작하는 영역을 커널 모드에서 사용할 수 있도록 가상 주소 공간으로 등록 하지만, phys_to_virt() 함수는 PAGE_OFFSET과 같은 값을 이용하여 변환 처리만 계산하기 때문이다. void* ioremap(unsigned long offset , unsigned long size); 반환 값: 가상 주소의 선두 주소 offset : 물리 주소의 시작 주소 size : 크기 void* phys_to_virt(unsigned long address); 반환 값 : 변환된 가상주소 address : 물리 주소 * PAGE_OFFSET 매크로 상수값 : 물리 주소와 가상 주소간에 변환을 위해 쓰이며, #include <asm/page.h>에 정의된다. |