lowmem 영역을 페이지 테이블에 매핑하는데 각 영역에 따라 MT_MEMORY_RW 또는 MT_MEMORY_RWX 타입으로 매핑한다.
map_lowmem()
arch/arm/mm/mmu.c
static void __init map_lowmem(void)
{
struct memblock_region *reg;
phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
/* Map all the lowmem memory banks. */
for_each_memblock(memory, reg) {
phys_addr_t start = reg->base;
phys_addr_t end = start + reg->size;
struct map_desc map;
if (end > arm_lowmem_limit)
end = arm_lowmem_limit;
if (start >= end)
break;
- phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
- 커널의 물리 시작 주소를 1M round down
- phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
- 커널의 __init_end 주소를 1M round up
- __init_end
- 커널의 코드 영역 끝나고 .data 섹션 안에 위치한 init data 종료 주소
- __init_end
- 커널의 __init_end 주소를 1M round up
if (end < kernel_x_start) {
map.pfn = __phys_to_pfn(start);
map.virtual = __phys_to_virt(start);
map.length = end - start;
map.type = MT_MEMORY_RWX;
create_mapping(&map);
- 다음 그림과 같이 비교할 memblock이 커널보다 아래에 위치하는 경우 이 memblock을 MT_MEMORY_RWX 타입으로 매핑한다.
} else if (start >= kernel_x_end) {
map.pfn = __phys_to_pfn(start);
map.virtual = __phys_to_virt(start);
map.length = end - start;
map.type = MT_MEMORY_RW;
create_mapping(&map);
- 다음 그림과 같이 비교할 memblock이 커널보다 위에 위치하는 경우 이 memblock을 MT_MEMORY_RW 타입으로 매핑한다.
} else {
/* This better cover the entire kernel */
if (start < kernel_x_start) {
map.pfn = __phys_to_pfn(start);
map.virtual = __phys_to_virt(start);
map.length = kernel_x_start - start;
map.type = MT_MEMORY_RW;
create_mapping(&map);
}
map.pfn = __phys_to_pfn(kernel_x_start);
map.virtual = __phys_to_virt(kernel_x_start);
map.length = kernel_x_end - kernel_x_start;
map.type = MT_MEMORY_RWX;
create_mapping(&map);
if (kernel_x_end < end) {
map.pfn = __phys_to_pfn(kernel_x_end);
map.virtual = __phys_to_virt(kernel_x_end);
map.length = end - kernel_x_end;
map.type = MT_MEMORY_RW;
create_mapping(&map);
}
}
}
}
- 다음 그림과 같이 비교할 memblock이 커널을 포함하는 경우 이 memblock을 3등분 하여 각각의 영역을 아래와 같은 타입으로 매핑한다.
참고
- Memblock – (1) | 문c
- Memblock – (2) | 문c
- 페이지 테이블 | 문c
- 페이지 테이블 관련 명령(pgd, pud, pmd, pte) | 문c
- 페이지 테이블 매핑(create_mapping()) | 문c



