[커널 17차] 31주차

2021.04.04 21:01

ㅇㅇㅇ 조회 수:158

arm64_memblock_init() 진행 중

 

CONFIG_ZONE_DMA가 enable된 경우
- http://jake.dothome.co.kr/zone-types/ 참고
- arm64는 기본적으로 ZONE_DMA32를 사용한다고 함
- ARM64_ZONE_DMA_BITS = 30이므로 zone bit 30을 기준으로 DMA 물리주소 최대값을 정한다
- 첫 1GB 물리주소 영역에 해당한다

 

max_zone_phys()
- zone bit를 인수로 받아서 최대 zone 물리주소값을 리턴한다
- memblock 상 실제 물리 주소 시작점 (memblock_start_of_DRAM()) 부터 1 << zone bit만큼 더해서 최대 물리주소값을 구한다
- memblock상 base부터 offset을 더해 주는 이유가 명확치 않다
- 주석에서는 4GB 이후 값을 DMA device가 접근한다고 가정하는 듯 하나 무슨 의도인지 정확하게는 불분명함
- https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d50314a6b0702c630c35b88148c1acb76d2e4ede
- 물리주소가 4GB 이상인 시스템에서는 DMA device도 그에 맞게 offset이 hardwired 되어 있을 것이라고 가정하고 이 offset이 DT binding되어 있다면 리눅스에서도 지원함(?)
- 그러나 offset이 부팅 초반에는 얻기 어려우므로 일단 DRAM start 주소를 offset으로 추정하여 ZONE_DMA 영역을 구성하는 듯 함


GENMASK_ULL(h, l)
- l bit부터 h bit position까지의 bitmask를 만든다
- GENMASK_ULL(39, 21) = 0x000000ffffe00000

 

CONFIG_ZONE_DMA32가 enable된 경우
- 전역변수 arm64_dma32_phys_limit값을 max zone 32bit으로 하여 지정한다
- enable이 안된 경우에는 ARM64_PA_BITS에서 지정된 물리주소 최대값으로 지정한다
- ZONE_DMA이후부터 4GB까지의 물리주소에 해당한다


reserve_crashkernel()
- http://jake.dothome.co.kr/reserve_crashkernel/
- dump capture kernel이 사용할 메모리 영역을 reserve한다
- 이 영역은 kernel command line에서 "crashkernel=" option에 의해 정해진다
- boot_command_line에서 crash kernel 영역의 base와 size를 parsing한 후 memblock에 reserve한다
- 이 때 다음 사항들을 체크한다
- base가 0이면 arm64 boot protocol에 따라 2MB align하여 base를 지정한다. 이 경우 0번지부터 arm64_dma32_phys_limit까지 범위에서 찾는다
- base가 0이 아니면
+-- memblock memory region에 포함되어야 한다
+-- reserve 영역과 겹치면 안된다
+-- 2MB align이 되어야 한다
- 이후 crashk_res.start와 crashk_res.end에 reserve한 영역의 base와 end 주소를 기록한다


parse_crashkernel()
- cmdline에서 "crashkernel=" option을 찾아서 parsing한다
- 이 때 suffix는 NULL로 고정한다
- 실제 동작은 __parse_crashkernel() 함수를 호출하여 수행한다


__parse_crashkernel()
- get_last_crashkernel()로 마지막 crashkernel option을 parsing해서 가져온다
- 마지막 option string을 parsing해서 crash kernel 영역 base와 size를 구한다
- 이 때 option에 따라 parse_crashkernel_mem() 함수 또는 parse_crashkernel_simple() 함수를 사용한다
- option에 ":"이 포함되면 parse_crashkernel_mem() 수행


parse_crashkernel_simple()
- 기본 옵션 선택시 수행된다 (crashkernel=size[@offset] 형태)
- memparse()를 이용해서 size와 offset을 unsigned long long으로 바꾸어 리턴한다


memparse()
- string을 받아서 strtoull() 함수를 이용, 숫자로 바꿔준다


parse_crashkernel_mem()
- 옵션 crashkernel=ramsize-range:size[,...][@offset] 선택시 사용한다
- 옵션 중에서 ramsize range의 start와 end가 둘 다 시스템 물리 메모리 크기보다 작은 것들을 고른다
- 시스템마다 물리 메모리 크기가 다를 수 있으므로 각 크기 범위 별로 사용할 crashkernel을 여러 개 만들어 놓고 각각의 크기와 base 주소를 적는 것으로 보인다
- 그 중 마지막에 적혀진 것만 골라서 그 size와 offset을 crash_size와 crash_base 포인터에 전달한다
- 시스템 물리 메모리 크기와 맞는 옵션이 여러 개 있으면 마지막 옵션을 선택하도록 되어 있는 듯함


parse_crashkernel_suffix()
- suffix option을 사용했을 때만 동작
- 옵션은 crashkernel=size,[high|low] 형태이다
- size를 읽어서 crash_size 포인터로 넘겨준다
- suffix에는 ",high", ",low"가 존재한다


get_last_crashkernel()
- name에 해당하는 마지막 string을 cmdline에서 찾아서 리턴한다
- suffix가 NULL이면 suffix가 포함된 string은 건너 뛴다
- suffix가 유효하면 해당 suffix가 포함된 string을 찾는다

 

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

 

오후 시간 : spinlock 스터디
- http://jake.dothome.co.kr/spinlock/
- https://0xax.gitbooks.io/linux-insides/content/SyncPrim/linux-sync-2.html

XE Login