Document memory layout.
Change-Id: I3ddd6b355a77527063886065ab2c576364709fc0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3627453
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Auto-Submit: Andrew Walbran <qwandor@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Andrew Walbran <qwandor@google.com>
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index 9f46dee..28dd3a7 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -67,9 +67,9 @@
- `GuestMemory` is for sending around references to all of the guest memory. It can be cloned
freely, but the underlying guest memory is always the same. Internally, it's implemented using
- `MemoryMapping` and `SharedMemory`. Note that `GuestMemory` is mapped into the host address space,
- but it is non-contiguous. Device memory, such as mapped DMA-Bufs, are not present in
- `GuestMemory`.
+ `MemoryMapping` and `SharedMemory`. Note that `GuestMemory` is mapped into the host address space
+ (for non-protected VMs), but it is non-contiguous. Device memory, such as mapped DMA-Bufs, are not
+ present in `GuestMemory`.
- `SharedMemory` wraps a `memfd` and can be mapped using `MemoryMapping` to access its data.
`SharedMemory` can't be cloned.
- `VolatileMemory` is a trait that exposes generic access to non-contiguous memory. `GuestMemory`
@@ -86,6 +86,9 @@
available via `VolatileSlice` and several convenience functions. This type is most useful for
mapping memory unrelated to `GuestMemory`.
+See [memory layout](https://google.github.io/crosvm/appendix/memory_layout.html) for details how
+crosvm arranges the guest address space.
+
### Device Model
### `Bus`/`BusDevice`
diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md
index 3e6bc11..93de099 100644
--- a/docs/book/src/SUMMARY.md
+++ b/docs/book/src/SUMMARY.md
@@ -21,6 +21,7 @@
- [Appendix](./appendix/index.md)
- [Sandboxing](./appendix/sandboxing.md)
- [Seccomp](./appendix/seccomp.md)
+ - [Memory Layout](./appendix/memory_layout.md)
- [Minijail](./appendix/minijail.md)
______________________________________________________________________
diff --git a/docs/book/src/appendix/memory_layout.md b/docs/book/src/appendix/memory_layout.md
new file mode 100644
index 0000000..39085f5
--- /dev/null
+++ b/docs/book/src/appendix/memory_layout.md
@@ -0,0 +1,100 @@
+# Memory Layout
+
+## x86-64 guest physical memory map
+
+This is a survey of the existing memory layout for crosvm on x86-64 when booting a Linux kernel. Some of these values are different when booting a BIOS image or when compiled with features=direct (ManaTEE); see the source. All addresses are in hexadecimal.
+
+| Name/source link | Address | End (exclusive) | Size | Notes |
+| ---------------------------- | ------------- | --------------- | --------- | ---------------------------------------------------------------------------------------- |
+| | `0000` | `7000` | | RAM (may start at 0x1000 for crosvm-direct) |
+| [`ZERO_PAGE_OFFSET`] | `7000` | | | Linux boot_params structure |
+| [`BOOT_STACK_POINTER`] | `8000` | | | Boot SP value |
+| [`boot_pml4_addr`] | `9000` | | | Boot page table |
+| [`boot_pdpte_addr`] | `A000` | | | Boot page table |
+| [`boot_pde_addr`] | `B000` | | | Boot page table |
+| [`CMDLINE_OFFSET`] | `2_0000` | `20_0000` | ~1.87 MiB | Linux kernel command line |
+| [`ACPI_HI_RSDP_WINDOW_BASE`] | `E_0000` | | | ACPI RSDP table (TODO: technically overlaps command line buffer; check CMDLINE_MAX_SIZE) |
+| [`KERNEL_START_OFFSET`] | `20_0000` | | | Linux kernel image load address |
+| [`END_ADDR_BEFORE_32BITS`] | `20_0000` | `D000_0000` | ~3.24 GiB | RAM (\<4G) |
+| [`END_ADDR_BEFORE_32BITS`] | `D000_0000` | `F400_0000` | 576 MiB | Low (\<4G) MMIO allocation area |
+| [`PCIE_CFG_MMIO_START`] | `F400_0000` | `F800_0000` | 64 MiB | PCIe enhanced config (ECAM) |
+| [`RESERVED_MEM_SIZE`] | `F800_0000` | `1_0000_0000` | 128 MiB | LAPIC/IOAPIC/HPET/… |
+| [`TSS_ADDR`] | `FFFB_D000` | | | Boot task state segment |
+| | `1_0000_0000` | | | RAM (>4G) |
+| | (end of RAM) | | | High (>4G) MMIO allocation area |
+
+[`zero_page_offset`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=235?q=ZERO_PAGE_OFFSET
+[`boot_stack_pointer`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=208?q=BOOT_STACK_POINTER
+[`boot_pml4_addr`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/regs.rs;l=310?q=boot_pml4_addr
+[`boot_pdpte_addr`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/regs.rs;l=311?q=boot_pdpte_addr
+[`boot_pde_addr`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/regs.rs;l=312?q=boot_pde_addr
+[`cmdline_offset`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=239?q=CMDLINE_OFFSET
+[`acpi_hi_rsdp_window_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=252?q=ACPI_HI_RSDP_WINDOW_BASE
+[`kernel_start_offset`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=238?q=KERNEL_START_OFFSET
+[`end_addr_before_32bits`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=230?q=END_ADDR_BEFORE_32BITS
+[`pcie_cfg_mmio_start`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=227?q=PCIE_CFG_MMIO_START
+[`reserved_mem_size`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=224?q=RESERVED_MEM_SIZE
+[`tss_addr`]: https://crsrc.org/o/src/platform/crosvm-upstream/x86_64/src/lib.rs;l=236?q=TSS_ADDR
+
+## aarch64 guest physical memory map
+
+All addresses are IPA in hexadecimal.
+
+### Common layout
+
+These apply for all boot modes.
+
+| Name/source link | Address | End (exclusive) | Size | Notes |
+| --------------------------------- | --------------- | --------------- | ---------- | ------------------------------------------------------------- |
+| [`SERIAL_ADDR[3]`][serial_addr] | `2e8` | `2f0` | 8 bytes | Serial port MMIO |
+| [`SERIAL_ADDR[1]`][serial_addr] | `2f8` | `300` | 8 bytes | Serial port MMIO |
+| [`SERIAL_ADDR[2]`][serial_addr] | `3e8` | `3f0` | 8 bytes | Serial port MMIO |
+| [`SERIAL_ADDR[0]`][serial_addr] | `3f8` | `400` | 8 bytes | Serial port MMIO |
+| [`AARCH64_RTC_ADDR`] | `2000` | `3000` | 4 KiB | Real-time clock |
+| [`AARCH64_PCI_CFG_BASE`] | `1_0000` | `2_0000` | 64 KiB | PCI configuration (CAM) |
+| [`AARCH64_MMIO_BASE`] | `200_0000` | `400_0000` | 32 MiB | Low MMIO allocation area |
+| [`AARCH64_GIC_CPUI_BASE`] | `3ffd_0000` | `3fff_0000` | 128 KiB | vGIC |
+| [`AARCH64_GIC_DIST_BASE`] | `3fff_0000` | `4000_0000` | 64 KiB | vGIC |
+| [`AARCH64_AXI_BASE`] | `4000_0000` | | | Seemingly unused? Is this hard-coded somewhere in the kernel? |
+| [`AARCH64_PVTIME_IPA_START`] | `7fd0_0000` | `7fe0_0000` | 64 KiB | Paravirtualized time |
+| [`AARCH64_PROTECTED_VM_FW_START`] | `7fe0_0000` | `8000_0000` | 2 MiB | pVM firmware (if running a protected VM) |
+| [`AARCH64_PHYS_MEM_START`] | `8000_0000` | | --mem size | RAM (starts at IPA = 2 GiB) |
+| [`plat_mmio_base`] | after RAM | +0x800000 | 8 MiB | Platform device MMIO region |
+| [`high_mmio_base`] | after plat_mmio | max phys addr | | High MMIO allocation area |
+
+### Layout when booting a kernel
+
+These apply when no bootloader is passed, so crosvm boots a kernel directly.
+
+| Name/source link | Address | End (exclusive) | Size | Notes |
+| ------------------------- | ----------------- | --------------- | ----- | ---------------------------- |
+| [`AARCH64_KERNEL_OFFSET`] | `8080_0000` | | | Kernel load location in RAM |
+| [`initrd_addr`] | after kernel | | | Linux initrd location in RAM |
+| [`fdt_offset`] | before end of RAM | | 2 MiB | Flattened device tree in RAM |
+
+### Layout when booting a bootloader
+
+These apply when a bootloader is passed with `--bios`.
+
+| Name/source link | Address | End (exclusive) | Size | Notes |
+| ----------------------------------- | ----------- | --------------- | ----- | ---------------------------- |
+| [`AARCH64_FDT_OFFSET_IN_BIOS_MODE`] | `8000_0000` | `8020_0000` | 2 MiB | Flattened device tree in RAM |
+| [`AARCH64_BIOS_OFFSET`] | `8020_0000` | | | Bootloader image in RAM |
+
+[serial_addr]: https://crsrc.org/o/src/platform/crosvm-upstream/arch/src/serial.rs;l=70?q=SERIAL_ADDR
+[`aarch64_rtc_addr`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=93?q=AARCH64_RTC_ADDR
+[`aarch64_pci_cfg_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=100?q=AARCH64_PCI_CFG_BASE
+[`aarch64_mmio_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=104?q=AARCH64_MMIO_BASE
+[`aarch64_gic_cpui_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/devices/src/irqchip/kvm/aarch64.rs;l=44?q=AARCH64_GIC_CPUI_BASE
+[`aarch64_gic_dist_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=64?q=AARCH64_GIC_DIST_BASE
+[`aarch64_axi_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=45?q=AARCH64_AXI_BASE
+[`aarch64_pvtime_ipa_start`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=59?q=AARCH64_PVTIME_IPA_START
+[`aarch64_protected_vm_fw_start`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=55?q=AARCH64_PROTECTED_VM_FW_START
+[`aarch64_phys_mem_start`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=44?q=AARCH64_PHYS_MEM_START
+[`plat_mmio_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=551?q=plat_mmio_base
+[`high_mmio_base`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=554?q=high_mmio_base
+[`aarch64_kernel_offset`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=35?q=AARCH64_KERNEL_OFFSET
+[`initrd_addr`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=270?q=initrd_addr
+[`fdt_offset`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=184?q=fdt_offset
+[`aarch64_fdt_offset_in_bios_mode`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=49?q=AARCH64_FDT_OFFSET_IN_BIOS_MODE
+[`aarch64_bios_offset`]: https://crsrc.org/o/src/platform/crosvm-upstream/aarch64/src/lib.rs;l=51?q=AARCH64_BIOS_OFFSET
diff --git a/tools/fmt b/tools/fmt
index 8e2a005..151eaeb 100755
--- a/tools/fmt
+++ b/tools/fmt
@@ -36,6 +36,7 @@
# Files not under our control or auto-generated.
IGNORE = [
+ "docs/book/src/appendix/memory_layout.md", # mdformat messes up the tables.
"infra/README.recipes.md",
"infra/recipes.py",
]