diff --git a/docs/src/osdk/guide/create-project.md b/docs/src/osdk/guide/create-project.md index f793da5a3..20641bee0 100644 --- a/docs/src/osdk/guide/create-project.md +++ b/docs/src/osdk/guide/create-project.md @@ -105,20 +105,7 @@ Please avoid changing the default settings unless you know what you are doing. ```toml -[boot] -ovmf = "/usr/share/OVMF" -[qemu] -machine = "q35" -args = [ - "--no-reboot", - "-m 2G", - "-nographic", - "-serial chardev:mux", - "-monitor chardev:mux", - "-chardev stdio,id=mux,mux=on,signal=off", - "-display none", - "-device isa-debug-exit,iobase=0xf4,iosize=0x04", -] +{{#include ../../../../osdk/src/commands/new/lib.OSDK.toml.template}} ``` ### `rust-toolchain.toml` diff --git a/docs/src/osdk/reference/commands/build.md b/docs/src/osdk/reference/commands/build.md index 1e99693c8..a3ba38bff 100644 --- a/docs/src/osdk/reference/commands/build.md +++ b/docs/src/osdk/reference/commands/build.md @@ -38,32 +38,30 @@ or append values in `OSDK.toml`. The allowed values for each option can be found in the [Manifest Documentation](../manifest.md). -- `--kcmd_args `: +- `--kcmd-args `: Command line arguments for the guest kernel -- `--init_args `: +- `--init-args `: Command line arguments for the init process - `--initramfs `: Path of the initramfs -- `--boot.ovmf `: -Path of the OVMF directory -- `--boot.loader `: -Loader for booting the kernel -- `--boot.protocol `: -Protocol for booting the kernel -- `--qemu.path `: +- `--boot-method `: +The method to boot the kernel +- `--grub-boot-protocol `: +The boot protocol for booting the kernel +- `--display-grub-menu`: +To display the GRUB menu if booting with GRUB +- `--qemu-path `: Path of QEMU -- `--qemu.machine `: -QEMU machine type -- `--qemu.args `: -Arguments for running QEMU +- `--qemu-args `: +Extra arguments for running QEMU ## Examples - Build a project with `./initramfs.cpio.gz` -as the initramfs and `multiboot2` as the boot protocol: +as the initramfs and `multiboot2` as the boot protocol used by GRUB: ```bash -cargo osdk build --initramfs="./initramfs.cpio.gz" --boot.protocol="multiboot2" +cargo osdk build --initramfs="./initramfs.cpio.gz" --grub-boot-protocol="multiboot2" ``` - Build a project and append `sh`, `-l` diff --git a/docs/src/osdk/reference/manifest.md b/docs/src/osdk/reference/manifest.md index f06aba954..7a9c9abc3 100644 --- a/docs/src/osdk/reference/manifest.md +++ b/docs/src/osdk/reference/manifest.md @@ -10,92 +10,78 @@ If there is only one crate and no workspace, the file is placed in the crate's root directory. For a crate inside workspace, -it may have two related manifests, +it may have two distinct related manifests, one is of the workspace (in the same directory as the workspace's `Cargo.toml`) and one of the crate (in the same directory as the crate's `Cargo.toml`). -So which manifest should be used? - -The rules are: - -- If running commands in the workspace root directory, -the `OSDK.toml` of the workspace will be used -- If running commands in the crate directory - - If the crate has `OSDK.toml`, - the `OSDK.toml` of the crate will be used. - - Otherwise, the `OSDK.toml` of the workspace will be used. +OSDK will firstly refer to the crate-level manifest, then +query the workspace-level manifest for undefined fields. +In other words, missing fields of the crate manifest +will inherit values from the workspace manifest. ## Configurations Below, you will find a comprehensive version of -the available configuration options in the manifest. +the available configuration tree in the manifest. -```toml -[project] # <1> -type = "kernel" +Here are notes for some fields with special value treatings: + - `*` marks the field as "will be evaluated", that the final +value of string `"S"` will be the output of `echo "S"` using the +host's shell. + - `+` marks the path fields. The relative paths written in the +path fields will be relative to the manifest's enclosing directory. -[run] # <2> -kcmd_args = ["init=/bin/busybox", "path=/usr/local/bin"] # <3> -init_args = ["sh", "-l"] # <4> -initramfs="./build/initramfs.cpio.gz" # <5> -bootloader = "grub" # <6> -boot_protocol = "multiboot2" # <7> -grub-mkrescue = "/usr/bin/grub-mkrescue" # <8> -ovmf = "/usr/bin/ovmf" # <9> -qemu_path = "/usr/bin/qemu-system-x86_64" # <10> -qemu_args = [ # <11> - "-machine q35,kernel-irqchip=split", - "-cpu Icelake-Server,+x2apic", - "-m 2G", -] +If values are given in the tree that's the default value inferred +if that the field is not explicitly stated. -[test] # <2> -bootloader = "qemu" -qemu_args = [ # <10> - "-machine q35,kernel-irqchip=split", - "-cpu Icelake-Server,+x2apic", - "-m 2G", -] +``` +project_type # The type of the current crate. Can be lib/kernel[/module] -['cfg(arch="x86_64", scheme=microvm)'.run] # <12> -bootloader = "qemu" -qemu_args = [ # <10> - "-machine microvm,rtc=on", - "-cpu Icelake-Server,+x2apic", - "-m 2G", -] +# --------------------------- the default schema settings --------------------- +vars = [] # List of lists. These are the env vars that will be set before + # any evaluation happens. The variables will be evaluated + # **SEQUENTIALLY**. + # The reserved variables: + # - `OSDK_CWD`: The directory of the OSDK manifest. +build +|- features = [] # List of strings, the same as Cargo +|- profile = "dev" # String, the same as Cargo +boot +|- method # "grub-rescue-iso"/"qemu-direct"/"grub-qcow2" +|- kcmd_args # <1> +|- init_args # <2> +|- initramfs + # The path to the initramfs +grub # Grub options are only needed if boot method is related to GRUB +|- mkrescue_path + # The path to the `grub-mkrescue` executable +|- protocol # The protocol GRUB used. "linux"/"multiboot"/"multiboot2" +|- display_grub_menu # To display the GRUB menu when booting with GRUB +qemu +|- path + # The path to the QEMU executable +|- args * # String. <3> +run # Special settings for running, which will override default ones +|- vars # The run specific variables evaluate after .vars +|- build # Overriding .build +|- boot # Overriding .boot +|- grub # Overriding .grub +|- qemu # Overriding .qemu +test # Special settings for testing, which will override default ones +|- vars # The test specific variables evaluate after .vars +|- build # Overriding .build +|- boot # Overriding .boot +|- grub # Overriding .grub +|- qemu # Overriding .qemu +# ----------------------- end of the default schema settings ------------------ + +schema."user_custom_schema" +|- ... # All the other fields in the default schema. Missing but + # needed values will be firstly filled with the default + # value then the corresponding field in the default schema ``` -### Root level configurations +Here are some additional notes for the fields: -Fields in the given manifest marked with "1", "2" and "12" are -root level configurations. - -1. The OSDK project specs `project`. - - Currently, OSDK only need to know the type of the project. - We have two types of projects introduced with OSDK, which - are `kernel` and `library`. An OSDK project should be a - crate that reside in the directory of a crate or a workspace. - -2. Running and testing actions settings `run` and `test`. - - These two fields describe the action that are needed to - perform running or testing commands. The configurable values - of the actions are described by 3~11, which specifies how - would the OSDK invoke the VMM. The build action refers to - the run action and smartly build anything that the run action - need (e.g. a VM image or a kernel image with the appropriate - format). - - Also, you can specify different actions depending on the - scenarios. You can do that by the `cfg` feature described - in the section [Cfg](#Cfg). - -### Action configurations - -3. The arguments provided will be passed to the guest kernel. +1. The arguments provided will be passed to the guest kernel. Optional. The default value is empty. @@ -103,78 +89,117 @@ root level configurations. `KEY=VALUE` or `KEY` if no value is required. Each `KEY` can appear at most once. -4. The arguments provided will be passed to the init process, +2. The arguments provided will be passed to the init process, usually, the init shell. Optional. The default value is empty. -5. The path to the built initramfs. +3. Additional arguments passed to QEMU that is organized in a single string that +can have any POSIX shell compliant separators. Optional. The default value is empty. -6. The bootloader used to boot the kernel. - - Optional. The default value is `grub`. - - The allowed values are `grub` and `qemu` - (`qemu` indicates that QEMU directly boots the kernel). - -7. The boot protocol used to boot the kernel. - - Optional. The default value is `multiboot2`. - Except that for QEMU direct boot (when `bootloader` is "qemu"`), - `multiboot` will be used. - - The allowed values are `linux-efi-handover64`, - `linux-legacy32`, `multiboot`, and `multiboot2`. - -8. The path of `grub-mkrescue`, -which is used to create a GRUB CD_ROM. - - Optional. The default value is system path, - determined using `which grub-mkrescue`. - - This argument only takes effect - when the bootloader is `grub`. - -9. The path of OVMF. OVMF enables UEFI support for QEMU. - - Optional. The default value is empty. - - This argument only takes effect - when the boot protocol is `linux-efi-handover64`. - -10. The path of QEMU. - - Optional. If you want to use a customized QEMU this - is the way. Otherwise we will look from the `PATH` - environment variable for the QEMU command with appropriate - architecture. - -11. Additional arguments passed to QEMU. - - Optional. The default value is empty. - - Each argument should be in the form `KEY VALUE` - (separated by space), + Each argument should be in the form of `KEY` and `VALUE` or `KEY` if no value is required. Some keys can appear multiple times (e.g., `-device`, `-netdev`), while other keys can appear at most once. - Certain keys, such as `-cpu` and `-machine`, + Certain keys, such as `-kernel` and `-initrd`, are not allowed to be set here - as they may conflict with the internal settings of OSDK. + as they may conflict with the settings of OSDK. -### Cfg + The field will be evaluated, so it is ok to use environment variables + in the arguments (usually for paths or conditional arguments). You can + even use this mechanism to read from files by using command replacement + `$(cat path/to/your/custom/args/file)`. -Cfg is an advanced feature to create multiple profiles for -the same actions under different scenarios. Currently we -have two configurable keys, which are `arch` and `scheme`. -The key `arch` has a fixed set of values which is aligned -with the CLI `--arch` argument. If an action has no specified -arch, it matches all the architectures. The key `scheme` allows -user-defined values and can be selected by the `--scheme` CLI +### Example + +Here is a sound, self-explanatory example similar to our usage +of OSDK in the Asterinas project. + +In the script `./tools/qemu_args.sh`, the environment variables will be +used to determine the actual set of qemu arguments. + +```toml +project_type = "kernel" + +vars = [ + ["SMP", "1"], + ["MEM", "2G"], +] + +[boot] +method = "grub-rescue-iso" + +[run] +vars = [ + ["OVMF_PATH", "/usr/share/OVMF"], +] +boot.kcmd_args = [ + "SHELL=/bin/sh", + "LOGNAME=root", + "HOME=/", + "USER=root", + "PATH=/bin:/benchmark", + "init=/usr/bin/busybox", +] +boot.init_args = ["sh", "-l"] +boot.initramfs = "regression/build/initramfs.cpio.gz" + +[test] +boot.method = "qemu-direct" + +[grub] +protocol = "multiboot2" +display_grub_menu = true + +[qemu] +args = "$(./tools/qemu_args.sh)" + +[scheme."microvm"] +boot.method = "qemu-direct" +vars = [ + ["MICROVM", "true"], +] +qemu.args = "$(./tools/qemu_args.sh)" + +[scheme."iommu"] +supported_archs = ["x86_64"] +vars = [ + ["IOMMU_DEV_EXTRA", ",iommu_platform=on,ats=on"], + ["IOMMU_EXTRA_ARGS", """\ + -device intel-iommu,intremap=on,device-iotlb=on \ + -device ioh3420,id=pcie.0,chassis=1\ + """], +] +qemu.args = "$(./tools/qemu_args.sh)" + +[scheme."intel_tdx"] +supported_archs = ["x86_64"] +build.features = ["intel_tdx"] +vars = [ + ["MEM", "8G"], + ["OVMF_PATH", "~/tdx-tools/ovmf"], +] +boot.method = "grub-qcow2" +grub.mkrescue_path = "~/tdx-tools/grub" +grub.protocol = "linux" +qemu.args = """\ + -accel kvm \ + -name process=tdxvm,debug-threads=on \ + -m $MEM \ + -smp $SMP \ + -vga none \ +""" +``` + +### Scheme + +Scheme is an advanced feature to create multiple profiles for +the same actions under different scenarios. Scheme allows any +user-defined keys and can be selected by the `--scheme` CLI argument. The key `scheme` can be used to create special settings -(especially special QEMU configurations). If a cfg action is +(especially special QEMU configurations). If a scheme action is matched, unspecified and required arguments will be inherited -from the action that has no cfg (i.e. the default action setting). +from the default scheme.