pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug>(
    guest_mem: &GuestMemory,
    num_cpus: u32,
    cmdline: &CStr,
    device_info: Option<&HashMap<(DeviceType, String), T>>,
) -> 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, num_cpus)?;
    create_memory_node(&mut fdt, guest_mem)?;
    create_chosen_node(&mut fdt, cmdline)?;
    create_gic_node(&mut fdt, u64::from(num_cpus))?;
    create_timer_node(&mut fdt)?;
    create_clock_node(&mut fdt)?;
    create_psci_node(&mut fdt)?;
    device_info.map_or(Ok(()), |v| create_devices_node(&mut fdt, v))?;

    // 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));
    let written = guest_mem
        .write_slice_at_addr(fdt_final.as_slice(), fdt_address)
        .map_err(Error::WriteFDTToMemory)?;
    if written < FDT_MAX_SIZE {
        return Err(Error::IncompleteFDTMemoryWrite);
    }
    Ok(fdt_final)
}
// Creates the flattened device tree for this VM.
Creates the flattened device tree for this VM.
Creates the flattened device tree for this VM .
pub fn create_fdt<T: DeviceInfoForFDT + Clone + Debug>(
    guest_mem: &GuestMemory,
    num_cpus: u32,
    cmdline: &CStr,
    device_info: Option<&HashMap<(DeviceType, String), T>>,
) -> 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, num_cpus)?;
    create_memory_node(&mut fdt, guest_mem)?;
    create_chosen_node(&mut fdt, cmdline)?;
    create_gic_node(&mut fdt, u64::from(num_cpus))?;
    create_timer_node(&mut fdt)?;
    create_clock_node(&mut fdt)?;
    create_psci_node(&mut fdt)?;
    device_info.map_or(Ok(()), |v| create_devices_node(&mut fdt, v))?;
    // 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));
    let written = guest_mem
        .write_slice_at_addr(fdt_final.as_slice(), fdt_address)
        .map_err(Error::WriteFDTToMemory)?;
    if written < FDT_MAX_SIZE {
        return Err(Error::IncompleteFDTMemoryWrite);
    }
    Ok(fdt_final)
}
pub fn create_fdt < T : DeviceInfoForFDT + Clone + Debug > ( guest_mem : & GuestMemory , num_cpus : u32 , cmdline : & CStr , device_info : Option < & HashMap < ( DeviceType , String ) , T > > , ) -> 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 , num_cpus ) ? ; create_memory_node ( & mut fdt , guest_mem ) ? ; create_chosen_node ( & mut fdt , cmdline ) ? ; create_gic_node ( & mut fdt , u64 :: from ( num_cpus ) ) ? ; create_timer_node ( & mut fdt ) ? ; create_clock_node ( & mut fdt ) ? ; create_psci_node ( & mut fdt ) ? ; device_info . map_or ( Ok ( ( ) ) , | v | create_devices_node ( & mut fdt , v ) ) ? ; // 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 ) ) ; let written = guest_mem . write_slice_at_addr ( fdt_final . as_slice ( ) , fdt_address ) . map_err ( Error :: WriteFDTToMemory ) ? ; if written < FDT_MAX_SIZE { return Err ( Error :: IncompleteFDTMemoryWrite ) ; } Ok ( fdt_final ) }
Creates the flattened device tree for this VM.
Creates the flattened device tree for this VM .
guest_mem
&GuestMemory
num_cpus
u32
cmdline
&CStr
device_info
Option<&HashMap<(DeviceType, String), T>>
guest_mem
&GuestMemory
num_cpus
u32
cmdline
&CStr
device_info
Option<&HashMap<(DeviceType, String), T>>