엑시노스의 dtb를 보면 메모리의 시작 주소가 0x2000_0000이며 그 크기는 0x8000_0000(2G) 입니다. 엑시노스의 경우를 가정하고 스터디 중 나온 그림을 그려보면 다음과 같습니다. 조금 더 정확한 그림을 그리고 싶어서 그러는데, 커널이미지의 시작 물리주소는 어디에 잡히게 되나요? app영역은 어디로 잡힐지 몰라서 그냥 가상주소처럼 커널영역 아래에 뒀습니다.
* 그림1. Phys Addr (2G로 가정)
* +-----------------------+ 0xa000_0000
* | |
* | highmem |
* | |
* +-----------------------+ <--------------+ __pa(vmalloc_min) = vmalloc_min + (PHYS_OFFSET - PAGE_OFFSET)
* | | = 커널이미지 시작 물리주소 + 768M
* | direct_mapping | 768M
* | |
* +-----------------------+ <--------------+ 커널이미지의 시작 물리주소(가상주소 0xc000_0000)
* | |
* | app?? | 사용자 공간?(커널 이미지가 뱅크의 시작위치에 적재되지 않을 경우 가정)
* | |
* +-----------------------+ 0x2000_0000
그리고 아래는 위와 같은 그림을 그리게 된 배경 내용으로 이번 후기입니다. 내용이 맞는지 모르겠어서 묻고 답하기에 올려봅니다.
----------------------------------------------------------------------------------------------------------------------------------------------------------
(5) 가상주소인 vmalloc_min을 물리주소로 바꾸어 highmem의 기준점으로 삼을경우 발생하는 의문점
sanity_check_meminfo() 함수에서 highmem의 경계를 vmalloc_min으로 잡고 있습니다. 이 vmalloc_min을 물리주소로 바꾸어 이 값을 경계로 bank를 나누고 있습니다.
static void * __initdata vmalloc_min = (void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
- 의문점 1. 그럼 이 경계는 과연 물리주소의 어디에 셋팅되는 걸까요?
우선 현재 분석중인 엑시노스의 dts로 생각해서 메모리를 2G로 잡아보겠습니다. 우선 __pa()에서 고정값인 0x8100_0000은 __fixup_a_pv_table을 통해 하위 오프셋이 (PHYS_OFFSET - PAGE_OFFSET)으로 바뀝니다.(이 부분은 pv_stup, pv_table, __fixup_a_pv_table을 다시 보니 확실한 것 같습니다. 참고URL: http://stackcanary.com/?p=616)그래서 정확히 물리주소의 어디를 가르킬지는 잘 모르겠습니다.
- 의문점 2. 여기서 direct_mapping 영역이 보장될지 아니면 vmalloc 공간이 보장될 것인가?
우선 direct맵핑 영역이 보장될 것 같습니다. 우선 커널 이미지가 올라가는 가상주소는 0xc000_0000입니다. 이 부분은 물리주소에 커널이미지의 시작주소로 고정될 것 입니다. 그렇다면 이 0xc000_0000(가상주소)와 커널이미지 시작 물리주소의 차이가 물리주소와 가상주소간의 차이가 되겠죠. 이게 바로 __fixup_a_pv_table에서 조절해주는 pv_table의 delta_offset(PHYS_OFFSET - PAGE_OFFSET)이 될 것 입니다.
그리고 vmalloc_min은 0xff00_0000에서부터 240M와 8M를 빼주죠. 이 가상주소를 물리주소로 바꾼다면 커널이미지 시작 물리주소에서 768M를 더한 값이 될 것 같습니다. 그럼 물리메모리는 대충 아래 그림처럼 구성 될 것 같습니다. 즉 커널이미지가 적재된 위치에서부터 충분한 메모리가 존재 한다면 highmem을 전부 보장할 수 있을 것 같습니다.
반대로 메모리가 256M라면 두번째 그림처럼 highmem의 경계까지 도달하지 못하므로 direct_mapping영역만 적당한 크기로 보장되지 않을까 생각됩니다.
사용자 영역의 경우 위치를 몰라서 그냥 가상주소처럼 커널영역아래에 두었습니다.
이 부분은 스터디에서 나온 내용이 기억이 부분부분 기억나서, 기억나는 부분과 제가 생각한 부분을 더하여 적었습니다. 스터디원분들과 OB분들 태클날려주세요~
* 그림1. Phys Addr (2G로 가정)
* +-----------------------+ 0xa000_0000
* | |
* | highmem |
* | |
* +-----------------------+ <--------------+ __pa(vmalloc_min) = vmalloc_min + (PHYS_OFFSET - PAGE_OFFSET)
* | | = 커널이미지 시작 물리주소 + 768M
* | direct_mapping | 768M
* | |
* +-----------------------+ <--------------+ 커널이미지의 시작 물리주소(가상주소 0xc000_0000)
* | |
* | app?? | 사용자 공간?(커널 이미지가 뱅크의 시작위치에 적재되지 않을 경우 가정)
* | |
* +-----------------------+ 0x2000_0000
* 그림2. Phys Addr (256M로 가정)
* +-----------------------+
* ---------------------------
* - highmem -
* ---------------------------
* +-----------------------+ <--------------+ __pa(vmalloc_min) = vmalloc_min + (PHYS_OFFSET - PAGE_OFFSET)
* --------------------------- = 커널이미지 시작 물리주소 + 768M
* ---------------------------
* +-----------------------+ 0x2001_0000 <----------+물리메모리의 끝
* | direct_mapping |
* +-----------------------+ <--------------+ 커널이미지의 시작 물리주소(가상주소 0xc000_0000)
* | |
* | app?? | 사용자 공간?(커널 이미지가 뱅크의 시작위치에 적재되지 않을 경우 가정)
* | |
* +-----------------------+ 0x2000_0000 <----------+물리메모리의 시작
댓글 0
.