[커널 17차] 40주차

2021.06.05 23:32

ㅇㅇㅇ 조회 수:283

acpi_table_upgrade() 부터 시작

 

acpi 내용 복습
- https://namu.wiki/w/ACPI
- https://kbench.com/?q=node/696
- https://thinkpro.tistory.com/28
- https://acpica.org/sites/acpica/files/ACPI-Introduction.pdf
- https://acpica.org/sites/acpica/files/asl_tutorial_v20190625.pdf
- https://web.archive.org/web/20190525060308/http://www.acpi.info/presentations/ACPI_Overview.pdf

 

ARM ACPI
- https://developer.arm.com/architectures/system-architectures/software-standards/acpi
- https://developer.arm.com/architectures/system-architectures/software-standards/psci
- ARM은 PSCI로 전원 관리 및 CPU 부팅 등을 수행하며, 이는 ACPI로 implementation 되어 있다
- PSCI command 수행을 위해서는 PSCI 문서에 나와있는 대로 레지스터를 세팅하고 SMC를 날리면 된다
- PSCI 문서 : https://developer.arm.com/documentation/den0022/latest/

 

acpi_table_upgrade()
- 가상주소로 세팅되어 있는 initrd_start, initrd_end로부터 initrd data와 size를 읽어 온다
- initrd_start, initrd_end는 arm64_memblock_init()에서 세팅했음
- NR_ACPI_INITRD_TABLES 개수만큼 루프를 돌면서 아래와 같이 acpi table data를 parsing한다
+-- find_cpio_data() 함수로 apci table data pointer를 가져온다 (가상주소 포인터)
+-- 이 때 init ramdisk의 "kernel/firmware/acpi/" path에서 값을 읽어오게 되어 있음
+-- sanity check 수행 후 전체 table size와 각 entry table 포인터(data)와 size, table 개수를 업데이트한다
- 전체 table size가 들어갈 수 있는 memblock을 요청한다
- 구해진 memblock 영역을 reverse한다
- 해당 memblock 영역을 nomap으로 세팅한다
- early_ioremap API를 이용해서 방금 할당된 memblock 영역에 parsing한 table data들을 복사한다
- early_ioremap API는 한번에 256KB씩 mapping할 수 있으므로 각 table entry들을 256KB 단위로 잘라서 하나씩 카피한다
- 할당된 memblock 영역은 물리주소이므로 접근을 위해 임시주소가 필요한다. 따라서 fixmap을 이용해서 임시 가상주소를 할당/해제하며, 이를 위해 early_memremap() 함수와 early_memunmap() 함수가 사용된다

 

early_ioremap 관련
- http://jake.dothome.co.kr/early-ioremap/

 

early_memremap()
- early_memremap_pgprot_adjust() 함수를 이용해서 FIXMAP_PAGE_NORMAL page property를 구한다
- __early_ioremap() 함수를 호출하여 임시 가상주소를 할당받는다
- 여기서 페이지 속성은 FIXMAP_PAGE_NORMAL 이다. (PAGE_KERNEL과 동일)

 

__early_ioremap()
- early_ioremap이 가지고 있는 7개 슬롯 중 빈 슬롯을 찾는다
- 슬롯으로부터 fixmap 시작 index를 구한다
- prev_size[slot] = size;
- 요청된 size로부터 필요한 페이지 개수를 구한다
- 요청된 phys_addr로부터 page align offset을 구한다
- 페이지 개수에 대해서 루프를 돌면서 __early_set_fixmap(idx, phys_addr, prot) 함수로 요청된 물리주소(phys_addr)에 idx(가상주소에 해당)를 매핑한다
- 매핑된 가상 주소 slot_virt[slot](첫 번째 idx에 해당하는 가상주소) + offset을 리턴한다

 

early_memunmap(addr, size)
- early_iounmap()으로 addr에서 size만큼 fixmap 가상주소를 unmap한다

 

early_iounmap(addr, size)
- addr == prev_map[slot]인 slot을 찾는다
- addr에 대해 page align offset을 구한다
- offset + size로 필요한 페이지 수를 구한다
- slot으로부터 시작 fixmap idx를 계산한다
- 각 페이지에 대해서 idx를 __early_set_fixmap() 함수를 이용해서 unmapping한다
- prev_map[slot] = NULL로 처리하고 종료


acpi_boot_table_init()
- early_param_init()에서 초기화한 변수들 : param_acpi_off, param_acpi_on, param_acpi_force
+-- parse_acpi() 함수에서 파라미터에 따라 초기화 된다
+-- arm64의 경우 대부분 acpi off일 것으로 판단된다
- param_acpi_off 이거나 !param_acpi_on & !param_acpi_force & depth 1에 chosen도 아니고 xen property가 있는 hypervisor도 아닌 node가 있으면 acpi boot table init을 생략하고 done으로 점프한다
- 위 조건에 해당되지 않으면 enable_acpi() 실행해서 acpi_disabled, acpi_pci_disabled, acpi_noirq를 모두 0으로 만든다 (원래는 모두 1)
- acpi_table_init() 함수로 acpi table 초기화를 수행하고 acpi_fadt_sanity_check() 함수로 sanity check도 수행한다
- acpi table 초기화에 실패하면 disable_acpi() 수행하여 다시 acpi_disabled, acpi_pci_disabled, acpi_noirq를 1로 만든다
+-- 초기화 실패해도 param_acpi_force = 1이면 disable_acpi() 수행하지 않는다
- 이후 done으로 이동
- acpi_disable이면 earlycon_acpi_spcr_enable인지 확인하고 맞으면 early_init_dt_scan_chosen_stdout() 함수를 수행한다. 아니면 그냥 종료
- acpi_disable이 아니면 acpi_parse_spcr() 함수로 SPCR table을 parsing하고 preferred console을 추가한다
- 이어서 CONFIG_ACPI_BGRT가 enable되어 있으면 acpi_parse_bgrt() 함수로 Boot Graphics Resource Table을 parsing한다


unflatten_device_tree()
- FDT로부터 device node의 tree를 구성한다
- __unflatten_device_tree() 함수를 실행하여 device node tree 구성

 

__unflatten_device_tree()
- 3 단계로 나누어서 실행된다
1) 각 node 및 property의 size를 총 합을 계산
2) 계산된 size를 바탕으로 memory allocation 수행
3) 실제 unflatten 수행

 

KOBJECT 관련 설명
- https://lwn.net/Articles/54651/
- https://www.kernel.bz/boardPost/118679/9
- https://www.win.tue.nl/~aeb/linux/lk/lk-13.html

 

gcc __align__ 매크로
- https://jybaek.tistory.com/160
- http://egloos.zum.com/studyfoss/v/5409933

XE Login