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