pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug>(
    guest_mem: &GuestMemoryMmap,
    arch_memory_info: &ArchMemoryInfo,
    vcpu_mpidr: Vec<u64>,
    cmdline: &CStr,
    device_info: &HashMap<(DeviceType, String), T>,
    gic_device: &Box<dyn GICDevice>,
    initrd: &Option<InitrdConfig>,
) -> Result<Vec<u8>> {
    // Alocate stuff necessary for the holding the blob.
    let mut fdt = vec![0; FDT_MAX_SIZE];

    allocate_fdt(&mut fdt)?;

    // For an explanation why these nodes were introduced in the blob take a look at
    // https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L845
    // Look for "Required nodes and properties".

    // Header or the root node as per above mentioned documentation.
    append_begin_node(&mut fdt, "")?;
    append_property_string(&mut fdt, "compatible", "linux,dummy-virt")?;
    // For info on #address-cells and size-cells read "Note about cells and address representation"
    // from the above mentioned txt file.
    append_property_u32(&mut fdt, "#address-cells", ADDRESS_CELLS)?;
    append_property_u32(&mut fdt, "#size-cells", SIZE_CELLS)?;
    // This is not mandatory but we use it to point the root node to the node
    // containing description of the interrupt controller for this VM.
    append_property_u32(&mut fdt, "interrupt-parent", GIC_PHANDLE)?;
    create_cpu_nodes(&mut fdt, &vcpu_mpidr)?;
    create_memory_node(&mut fdt, guest_mem, arch_memory_info)?;
    create_chosen_node(&mut fdt, cmdline, initrd)?;
    create_gic_node(&mut fdt, gic_device)?;
    create_timer_node(&mut fdt)?;
    create_clock_node(&mut fdt)?;
    create_psci_node(&mut fdt)?;
    create_devices_node(&mut fdt, device_info)?;

    // End Header node.
    append_end_node(&mut fdt)?;

    // Allocate another buffer so we can format and then write fdt to guest.
    let mut fdt_final = vec![0; FDT_MAX_SIZE];
    finish_fdt(&mut fdt, &mut fdt_final)?;

    // Write FDT to memory.
    let fdt_address = GuestAddress(get_fdt_addr(guest_mem));
    guest_mem
        .write_slice(fdt_final.as_slice(), fdt_address)
        .map_err(Error::WriteFDTToMemory)?;
    Ok(fdt_final)
}
/// Creates the flattened device tree for this aarch64 microVM.
Creates the flattened device tree for this aarch64 microVM.
Creates the flattened device tree for this aarch64 microVM .
pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug>(
    guest_mem: &GuestMemoryMmap,
    arch_memory_info: &ArchMemoryInfo,
    vcpu_mpidr: Vec<u64>,
    cmdline: &CStr,
    device_info: &HashMap<(DeviceType, String), T>,
    gic_device: &Box<dyn GICDevice>,
    initrd: &Option<InitrdConfig>,
) -> Result<Vec<u8>> {
    // Alocate stuff necessary for the holding the blob.
    let mut fdt = vec![0; FDT_MAX_SIZE];
    allocate_fdt(&mut fdt)?;
    // For an explanation why these nodes were introduced in the blob take a look at
    // https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L845
    // Look for "Required nodes and properties".
    // Header or the root node as per above mentioned documentation.
    append_begin_node(&mut fdt, "")?;
    append_property_string(&mut fdt, "compatible", "linux,dummy-virt")?;
    // For info on #address-cells and size-cells read "Note about cells and address representation"
    // from the above mentioned txt file.
    append_property_u32(&mut fdt, "#address-cells", ADDRESS_CELLS)?;
    append_property_u32(&mut fdt, "#size-cells", SIZE_CELLS)?;
    // This is not mandatory but we use it to point the root node to the node
    // containing description of the interrupt controller for this VM.
    append_property_u32(&mut fdt, "interrupt-parent", GIC_PHANDLE)?;
    create_cpu_nodes(&mut fdt, &vcpu_mpidr)?;
    create_memory_node(&mut fdt, guest_mem, arch_memory_info)?;
    create_chosen_node(&mut fdt, cmdline, initrd)?;
    create_gic_node(&mut fdt, gic_device)?;
    create_timer_node(&mut fdt)?;
    create_clock_node(&mut fdt)?;
    create_psci_node(&mut fdt)?;
    create_devices_node(&mut fdt, device_info)?;
    // End Header node.
    append_end_node(&mut fdt)?;
    // Allocate another buffer so we can format and then write fdt to guest.
    let mut fdt_final = vec![0; FDT_MAX_SIZE];
    finish_fdt(&mut fdt, &mut fdt_final)?;
    // Write FDT to memory.
    let fdt_address = GuestAddress(get_fdt_addr(guest_mem));
    guest_mem
        .write_slice(fdt_final.as_slice(), fdt_address)
        .map_err(Error::WriteFDTToMemory)?;
    Ok(fdt_final)
}
pub fn create_fdt < T : DeviceInfoForFDT + Clone + Debug > ( guest_mem : & GuestMemoryMmap , arch_memory_info : & ArchMemoryInfo , vcpu_mpidr : Vec < u64 > , cmdline : & CStr , device_info : & HashMap < ( DeviceType , String ) , T > , gic_device : & Box < dyn GICDevice > , initrd : & Option < InitrdConfig > , ) -> Result < Vec < u8 > > { // Alocate stuff necessary for the holding the blob. let mut fdt = vec ! [ 0 FDT_MAX_SIZE ] ; allocate_fdt ( & mut fdt ) ? ; // For an explanation why these nodes were introduced in the blob take a look at // https://github.com/torvalds/linux/blob/master/Documentation/devicetree/booting-without-of.txt#L845 // Look for "Required nodes and properties". // Header or the root node as per above mentioned documentation. append_begin_node ( & mut fdt , " " ) ? ; append_property_string ( & mut fdt , " " , " " ) ? ; // For info on #address-cells and size-cells read "Note about cells and address representation" // from the above mentioned txt file. append_property_u32 ( & mut fdt , " " , ADDRESS_CELLS ) ? ; append_property_u32 ( & mut fdt , " " , SIZE_CELLS ) ? ; // This is not mandatory but we use it to point the root node to the node // containing description of the interrupt controller for this VM. append_property_u32 ( & mut fdt , " " , GIC_PHANDLE ) ? ; create_cpu_nodes ( & mut fdt , & vcpu_mpidr ) ? ; create_memory_node ( & mut fdt , guest_mem , arch_memory_info ) ? ; create_chosen_node ( & mut fdt , cmdline , initrd ) ? ; create_gic_node ( & mut fdt , gic_device ) ? ; create_timer_node ( & mut fdt ) ? ; create_clock_node ( & mut fdt ) ? ; create_psci_node ( & mut fdt ) ? ; create_devices_node ( & mut fdt , device_info ) ? ; // End Header node. append_end_node ( & mut fdt ) ? ; // Allocate another buffer so we can format and then write fdt to guest. let mut fdt_final = vec ! [ 0 FDT_MAX_SIZE ] ; finish_fdt ( & mut fdt , & mut fdt_final ) ? ; // Write FDT to memory. let fdt_address = GuestAddress ( get_fdt_addr ( guest_mem ) ) ; guest_mem . write_slice ( fdt_final . as_slice ( ) , fdt_address ) . map_err ( Error :: WriteFDTToMemory ) ? ; Ok ( fdt_final ) }
Creates the flattened device tree for this aarch64 microVM.
Creates the flattened device tree for this aarch64 microVM .
guest_mem
&GuestMemoryMmap
arch_memory_info
&ArchMemoryInfo
vcpu_mpidr
Vec<u64>
cmdline
&CStr
device_info
&HashMap<(DeviceType, String), T>
gic_device
&Box<dyn GICDevice>
initrd
&Option<InitrdConfig>