summary refs log tree commit diff
path: root/arch/src/android.rs
blob: 5311d3fea8ed8f1676486ebf08c9ac79f540d280 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;

use crate::fdt::{begin_node, end_node, property_string, Error, Result};

fn parse_fstab_line(line: &str) -> Result<Vec<String>> {
    let vec: Vec<&str> = line.split_whitespace().collect();
    if vec.len() != 5 {
        return Err(Error::FdtFileParseError);
    }
    Ok(vec.iter().map(|s| s.to_string()).collect())
}

/// Creates a flattened device tree containing all of the parameters used
/// by Android.
///
/// # Arguments
///
/// * `fdt` - The DTB to modify. The top-most node should be open.
/// * `android-fstab` - A text file of Android fstab entries to add to the DTB
pub fn create_android_fdt(fdt: &mut Vec<u8>, fstab: File) -> Result<()> {
    let vecs = BufReader::new(fstab)
        .lines()
        .map(|l| parse_fstab_line(&l.map_err(Error::FdtIoError)?))
        .collect::<Result<Vec<Vec<String>>>>()?;
    begin_node(fdt, "firmware")?;
    begin_node(fdt, "android")?;
    property_string(fdt, "compatible", "android,firmware")?;

    let (dtprop, fstab): (_, Vec<_>) = vecs.into_iter().partition(|x| x[0] == "#dt-vendor");
    begin_node(fdt, "vendor")?;
    for vec in dtprop {
        let content = std::fs::read_to_string(&vec[2]).map_err(Error::FdtIoError)?;
        property_string(fdt, &vec[1], &content);
    }
    end_node(fdt)?; // vendor
    begin_node(fdt, "fstab")?;
    property_string(fdt, "compatible", "android,fstab")?;
    for vec in fstab {
        let partition = &vec[1][1..];
        begin_node(fdt, partition)?;
        property_string(fdt, "compatible", &("android,".to_owned() + partition))?;
        property_string(fdt, "dev", &vec[0])?;
        property_string(fdt, "type", &vec[2])?;
        property_string(fdt, "mnt_flags", &vec[3])?;
        property_string(fdt, "fsmgr_flags", &vec[4])?;
        end_node(fdt)?;
    }
    end_node(fdt)?; // fstab
    end_node(fdt)?; // android
    end_node(fdt)?; // firmware
    Ok(())
}