우선, virt board의 메모리 구조를 참조하기 위해서 QEMU의 source code에서 memory map을 직접 찾아 확인하였다.
소스코드는 다음과 같았다.
Virt Board Memory Map
hw/arm/virt.c
Link to original
즉, 이를 정리하면 다음과 같은 메모리 구조를 가지고 있다.
NAME | START_ADDR | END_ADDR | LEN |
---|---|---|---|
Boot Rom RESERVED (0 to 0x08000000) | < | < | < |
VIRT_FLASH | 0x00000000 | 0x08000000 | 0x08000000 |
VIRT_CPUPERIPHS | 0x08000000 | 0x08020000 | 0x00020000 |
GICD & GICC sits inside CPU Peripheral space | < | < | < |
VIRT_GIC_DIST | 0x08000000 | 0x08010000 | 0x00010000 |
VIRT_GIC_CPU | 0x08010000 | 0x08020000 | 0x00010000 |
VIRT_GIC_V2M | 0x08020000 | 0x08021000 | 0x00001000 |
VIRT_GIC_HYP | 0x08030000 | 0x08040000 | 0x00010000 |
VIRT_GIC_VCPU | 0x08040000 | 0x08050000 | 0x00010000 |
The space in between here is reserved for GICv3 CPU/vCPU/HYP | < | < | < |
VIRT_GIC_ITS | 0x08080000 | 0x080A0000 | 0x00020000 |
This redistributor space allows up to 264kB123 CPUs | < | < | < |
VIRT_GIC_REDIST | 0x080A0000 | 0x09000000 | 0x00F60000 |
VIRT_UART | 0x09000000 | 0x09001000 | 0x00001000 |
VIRT_RTC | 0x09010000 | 0x09011000 | 0x00001000 |
VIRT_FW_CFG | 0x09020000 | 0x09020018 | 0x00000018 |
VIRT_GPIO | 0x09030000 | 0x09031000 | 0x00001000 |
VIRT_SECURE_UART | 0x09040000 | 0x09041000 | 0x00001000 |
VIRT_SMMU | 0x09050000 | 0x09070000 | 0x00020000 |
VIRT_PCDIMM_ACPI | 0x09070000 | 0x09070018 | 0x00000018 |
VIRT_ACPI_GED | 0x09080000 | 0x09080004 | 0x00000004 |
VIRT_NVDIMM_ACPI | 0x09090000 | 0x09090004 | 0x00000004 |
VIRT_PVTIME | 0x090A0000 | 0x090B0000 | 0x00010000 |
VIRT_SECURE_GPIO | 0x090B0000 | 0x090B1000 | 0x00001000 |
VIRT_MMIO | 0x0A000000 | 0x0A000200 | 0x00000200 |
VIRT_PLATFORM_BUS | 0x0C000000 | 0x0E000000 | 0x02000000 |
VIRT_SECURE_MEM | 0x0E000000 | 0x01000000 | 0x01000000 |
VIRT_PCIE_MMIO | 0x10000000 | 0x3EFF0000 | 0x2eff0000 |
VIRT_PCIE_PIO | 0x3EFF0000 | 0x3F000000 | 0x00010000 |
VIRT_PCIE_ECAM | 0x3F000000 | 0x40000000 | 0x01000000 |
VIRT_MEM | 0x40000000 | 0x4040000000 | 0x4000000000 |
Customizable Area | < | < | < |
QEMU_DTB | 0x40000000 | 0x40200000 | 0x00200000 |
COSMOS_RAM_START | 0x40200000 |
이제 커널의 memory map을 linker script를 이용하여 구성하도록 한다.
크게 text, rodata, data, bss 섹션이 있으며, stack을 위한 공간도 다음의 코드와 같이 충분히 할당해 주었다.
Linker Script - Align
equals to..
Linux Memory Layout
Text Segment (=Code Segment)
- 프로그램에서 실행할 코드가 위치할 메모리 영역
- 쓰기 권한 없음, 실행 권한 있음
Data Segment
- 컴파일 시에 값이 정해지는 전역 변수
- 쓰기 권한 존재
ROData Segment
- 컴파일 시에 값이 정해지고 변경되지 않는 전역 상수
- 쓰기 권한 없음
BSS Segment
- 컴파일 시에 초기값이 할당되지 않은 전역변수
- 초기값은 0으로 할당되며, 쓰기 권한 존재
Heap Segment
- 동적으로 할당받는 메모리의 영역
Stack Segment
- 프로세스의 스택이 위치하는 메모리 영역
Reference
- Hermit Kernel: https://hermit-os.org/kernel
- Hermit Loader: http://hermit-os.org/loader
- ALIGN in Linker Scripts: https://stackoverflow.com/questions/8458084/align-in-linker-scripts
- Linux Memory Layout: https://hackyboiz.github.io/2022/01/14/poosic/linux-memory-layout/