xref: /aosp_15_r20/external/crosvm/x86_64/src/fdt.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2018 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #[cfg(any(target_os = "android", target_os = "linux"))]
6 use std::collections::BTreeMap;
7 use std::fs::File;
8 use std::fs::OpenOptions;
9 use std::io::Write;
10 use std::path::PathBuf;
11 
12 use arch::android::create_android_fdt;
13 use arch::apply_device_tree_overlays;
14 use arch::DtbOverlay;
15 use base::open_file_or_duplicate;
16 use cros_fdt::Error;
17 use cros_fdt::Fdt;
18 
19 /// Creates a flattened device tree containing all of the parameters for the
20 /// kernel and returns it as DTB.
21 ///
22 /// # Arguments
23 ///
24 /// * `android_fstab` - the File object for the android fstab
create_fdt( android_fstab: Option<File>, dump_device_tree_blob: Option<PathBuf>, device_tree_overlays: Vec<DtbOverlay>, ) -> Result<Vec<u8>, Error>25 pub fn create_fdt(
26     android_fstab: Option<File>,
27     dump_device_tree_blob: Option<PathBuf>,
28     device_tree_overlays: Vec<DtbOverlay>,
29 ) -> Result<Vec<u8>, Error> {
30     let mut fdt = Fdt::new(&[]);
31     // The whole thing is put into one giant node with some top level properties
32     if let Some(android_fstab) = android_fstab {
33         create_android_fdt(&mut fdt, android_fstab)?;
34     }
35 
36     // Done writing base FDT, now apply DT overlays
37     apply_device_tree_overlays(
38         &mut fdt,
39         device_tree_overlays,
40         #[cfg(any(target_os = "android", target_os = "linux"))]
41         vec![],
42         #[cfg(any(target_os = "android", target_os = "linux"))]
43         &BTreeMap::new(),
44     )?;
45 
46     let fdt_final = fdt.finish()?;
47 
48     if let Some(file_path) = dump_device_tree_blob {
49         let mut fd = open_file_or_duplicate(
50             &file_path,
51             OpenOptions::new()
52                 .read(true)
53                 .create(true)
54                 .truncate(true)
55                 .write(true),
56         )
57         .map_err(|e| Error::FdtIoError(e.into()))?;
58         fd.write_all(&fdt_final)
59             .map_err(|e| Error::FdtDumpIoError(e, file_path.clone()))?;
60     }
61 
62     Ok(fdt_final)
63 }
64