Booting Process
- Reverse Engineering from Hermit OS: ARM 부팅과 관련한 배경지식이나 레퍼런스가 x86에 비해 상대적으로 적어, arm기반의 os인 hermit-os의 부팅과정을 참조하며 제작하였다.
- Hermit-OS의 booting process는 rust-embedded/rust-raspberrypi-OS-tutorials를 참조하여 만들어져, 이후에는 이를 참조하였다.
Hermit Booting Process
link.ld
- Entry Point가 명시되어 있음
- 각 섹션의 구조, 메모리상의 위치 등이 정의되어 있음
- DTB는 0x40000000에 로딩되어 있으므로, 이를 덮어쓰지 않기 위해서 0x40200000부터 로딩하도록 함
ENTRY(_start)
phys = 0x40200000;
...(생략)
SECTIONS
{
. = phys;
...(생략)
}
entry.s
_start:
...(검증 과정 생략)
...(초기화 과정 생략)
b _start_rust
...(생략)
위와 같이, 검증 및 초기화 과정을 거친 뒤에 _start_rust
로 브랜치하여 rust로 제작된 코드로 점프하게 된다.
entry.rs
_start_rust
→ pre_init
→ loader_main
_start_rust
: callingpre_init
pre_init
- 초기화 과정 수행..
- disable interrupts
- reset tid registers
- disable mmu
- setup memory attribute type table
- setup TCU (translation control register)
- enable FP/ASIMD in Architectural Feature Access Control Register
- reset debug control register
- prepare system control register (SCTRL)
loader_main
- initialize logging
- finds kernel
- boots kernel
Initialize Logging
- Device Tree에서
/chosen
field 의stdout-path
의 주소를 참조 - arm의 경우 pl011 디바이스에서 stdout을 수행하는 것으로 확인됨
- pl011의 주소는 0x09000000
- dtb에서 0x09000000 주소를 확인하여 해당 주소에 원하는 값을 입력하면 화면에 출력된다.
chosen {
stdout-path = "/pl011@9000000";
rng-seed = <0x45efbb7b 0x6d473e1e 0xc4883b80 0x72c67d86 0x5215531b 0x9cb909a4 0x775c5488 0x864f215b>;
kaslr-seed = <0x2b1e6ddd 0xe1b43dc9>;
};
Finding Kernel
Bootloader에서 Kernel을 찾는 과정에서 메모리 정렬과 관련된 이슈로 올바르게 찾지 못하는 문제가 있어 우선 bootloader 부분을 제외한 Kernel을 바로 부팅하는 형태로 구현하였음
Reference
- Hermit Kernel: https://hermit-os.org/kernel
- Hermit Loader: http://hermit-os.org/loader