[커널 17차] 38주차

2021.05.23 01:30

ㅇㅇㅇ 조회 수:366

map_kernel()
- kasan_copy_shadow() 실행하고 끝

 

kasan_copy_shadow()
- init_pg_dir에 매핑되어 있는 kasan shadow region 영역을 swapper_pg_dir로 복사 매핑한다

 

head.S에서 mmu를 켠 후에 kasan_early_init()을 수행해서 init_pg_dir에 kasan shadow region을 매핑했었음
- mm/kasan/init.c에 전역변수 배열이 있고 이걸 이용해서 물리영역을 사용한다.
- kasan_early_shadow_page
- kasan_early_shadow_pte
- kasan_early_shadow_pmd
- kasan_early_shadow_pud
- kasan_early_shadow_p4d
- kasan_early_init()에서는 모든 pte 가상주소가 kasan_early_shadow_page 물리주소를 바라보게 초기화한다
- loop를 중복해서 돌지 않도록 pte_none/pmd_none/pud_none 등으로 NULL인 경우에만 looping을 하도록 한다

 

map_mem()
- 모든 물리 주소 영역에 대해서 linear mapping 생성
- rodata_full이거나 debug_pagealloc_enabled이면 나중에 RO 설정을 바꿔야 해서 page 단위로 매핑해야 하므로 no block 및 no cont mapping으로 설정한다
- _text ~ _etext, rodata ~ inittext_begin까지는 kernel image 및 RO 데이터 + init_pg_dir, swapper_pg_dir에 해당한다 --> writable alias를 만들지 않기 위해 일단 nomap처리
- 모든 memblock memory 영역에 대해서 nomap 영역을 제외하고 linear map 가상주소로 매핑한다 (PAGE_KERNEL --> UXN & PXN & writable)
- 이후 kernel image 및 RO 데이터에 대해서 다시 linear mapping한다. 이 때 non-executable로 매핑하고 나중에 mark_linear_text_alias_ro()에서 RO로 바꿀 예정이므로 cont mapping을 사용하지 않는다 (PAGE_KERNEL --> UXN & PXN & writable)
- KEXEC가 설정되어 있으면 crashk_res 영역에 대해서도 nomap으로 해서 처음에 alias를 제외하고 나중에 page-level로 따로 linear 매핑한다 (no block / no cont mapping)

 

rodata_enabled
- kernel 페이지 영역을 ROX로 설정한다

 

rodata_full
- 가상 주소 영역의 R/O attribute를 linear mapping alias에게도 똑같이 적용한다
- 이를 위해 page 단위 매핑을 해야 하므로 linear mapping 영역에 cont mapping/section mapping을 쓰지 않도록 한다
- 디폴트는 Y

 

rodata=off --> rodata_enabled = rodata_full = false
rodata=on --> rodata_enabled = true, rodata_full = false
rodata=full --> rodata_enabled = rodata_full = true

 

debug_pagealloc_enabled
- free_pages()를 실행하면 linear mapping에서 해당 페이지를 unmap해서 use-after-free corruption을 디버깅할 수 있도록 함
- 디폴트는 off

 

__map_memblock()
- start부터 end까지의 물리주소를 flag와 page attribute를 이용해서 linear mapping 가상주소에 매핑한다


KEXEC
- 현재 돌아가는 커널에서 새로운 커널을 부팅하게 해주는 기술
- 현재 진행 중인 커널의 메모리를 작동 중에 새로운 커널로 덮어쓴다
- https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_kexec
- https://wiki.archlinux.org/title/kexec

 

==========================================================

 

Memory Model
- http://jake.dothome.co.kr/mm-1/
- https://www.kernel.org/doc/html/latest/vm/memory-model.html
- https://lwn.net/Articles/789304/

- 물리 메모리를 관리하는 모델로 flat/discontiguous/sparse 모델이 있음

- 처음엔 flat으로 시작하여 모든 물리주소를 연속된 공간으로 관리했으나 여러 메모리 노드를 관리하게 되는 경우 hole 공간 때문에 메모리 낭비가 생김

- 이를 보완하기 위해 불연속 물리주소를 지원할 수 있는 disconguous를 사용하였으나 이는 hot-plug/hot-remove가 안됨

- Sparse 모델을 도입하여 hot-plug/hot-remove를 section 단위로 지원할 수 있도록 하였으나 성능이 떨어지는 문제가 있었음

- vmemmap을 도입하여 모든 물리 주소를 커버하는 연속된 1:1 가상주소를 사용하여 성능을 높이게 되고 현재는 sparse 모델 + vmemmap을 사용한다

 

Memmap
- http://jake.dothome.co.kr/mem_map/

 

Vmemmap
- http://jake.dothome.co.kr/sparsemem/
- https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8f6aac419bd

 

Anonymous union
- https://www.ibm.com/docs/en/i/7.4?topic=unions-anonymous

 

#define vmemmap    ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
- 가상주소의 PFN를 넣으면 해당 페이지의 page struct가 나온다

XE Login