Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Options:
Work around missing HELLO packet
-s, --storage-type <emmc/ufs/nvme/nand>

-S, --storage-slot <STORAGE_SLOT>
Index of the physical device (e.g. 1 for secondary UFS) [default: 0]
--sector-size <SECTOR_SIZE>

--skip-storage-init
Expand Down
39 changes: 33 additions & 6 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ struct Args {
#[arg(short, long, value_name = "emmc/ufs/nvme/nand")]
storage_type: String,

#[arg(
short = 'S',
long,
default_value = "0",
help = "Index of the physical device (e.g. 1 for secondary UFS)"
)]
storage_slot: u8,

#[arg(long)]
sector_size: Option<usize>,

Expand Down Expand Up @@ -223,6 +231,7 @@ fn main() -> Result<()> {
}
}
},
storage_slot: args.storage_slot,
bypass_storage: args.bypass_storage,
backend,
skip_firehose_log: !args.print_firehose_log,
Expand Down Expand Up @@ -291,7 +300,9 @@ fn main() -> Result<()> {
fs::create_dir_all(&outdir)?;
let outpath = Path::new(&outdir);

for (_, p) in read_gpt_from_storage(&mut qdl_dev, args.phys_part_idx)?.iter() {
for (_, p) in
read_gpt_from_storage(&mut qdl_dev, args.storage_slot, args.phys_part_idx)?.iter()
{
// *sigh*
if p.partition_name.as_str().is_empty() || p.size()? == 0 {
continue;
Expand All @@ -302,6 +313,7 @@ fn main() -> Result<()> {
&mut qdl_dev,
&mut out,
&p.partition_name.to_string(),
args.storage_slot,
args.phys_part_idx,
)?
}
Expand All @@ -312,16 +324,23 @@ fn main() -> Result<()> {
let outpath = Path::new(&outdir);
let mut out = File::create(outpath.join(&name))?;

read_storage_logical_partition(&mut qdl_dev, &mut out, &name, args.phys_part_idx)?
read_storage_logical_partition(
&mut qdl_dev,
&mut out,
&name,
args.storage_slot,
args.phys_part_idx,
)?
}
Command::Erase { name } => {
let part = find_part(&mut qdl_dev, &name, args.phys_part_idx)?;
let part = find_part(&mut qdl_dev, &name, args.storage_slot, args.phys_part_idx)?;

firehose_program_storage(
&mut qdl_dev,
&mut &[0u8][..],
&name,
(part.ending_lba - part.starting_lba + 1) as usize,
args.storage_slot,
args.phys_part_idx,
&part.starting_lba.to_string(),
)?;
Expand Down Expand Up @@ -357,12 +376,15 @@ fn main() -> Result<()> {
&mut file,
"",
file_len_sectors as usize,
args.storage_slot,
args.phys_part_idx,
"0",
)?;
}
Command::Peek { base, len } => firehose_peek(&mut qdl_dev, base, len)?,
Command::PrintGpt => print_partition_table(&mut qdl_dev, args.phys_part_idx)?,
Command::PrintGpt => {
print_partition_table(&mut qdl_dev, args.storage_slot, args.phys_part_idx)?
}
Command::Reset { reset_mode } => {
firehose_reset(&mut qdl_dev, &FirehoseResetMode::from_str(&reset_mode)?, 0)?
}
Expand All @@ -371,8 +393,12 @@ fn main() -> Result<()> {
part_name,
file_path,
} => {
let part: gptman::GPTPartitionEntry =
find_part(&mut qdl_dev, &part_name, args.phys_part_idx)?;
let part: gptman::GPTPartitionEntry = find_part(
&mut qdl_dev,
&part_name,
args.storage_slot,
args.phys_part_idx,
)?;
let mut file = File::open(file_path)?;
let file_len_sectors = file
.metadata()?
Expand All @@ -394,6 +420,7 @@ fn main() -> Result<()> {
&mut file,
&part_name,
file_len_sectors as usize,
args.storage_slot,
args.phys_part_idx,
&part.starting_lba.to_string(),
)?;
Expand Down
15 changes: 14 additions & 1 deletion cli/src/programfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn parse_read_cmd<T: Read + Write + QdlChan>(
.unwrap()
.parse::<usize>()
.unwrap();
let slot = attrs.get("slot").map_or(0, |a| a.parse::<u8>().unwrap());
let phys_part_idx = attrs
.get("physical_partition_number")
.unwrap()
Expand All @@ -45,6 +46,7 @@ fn parse_read_cmd<T: Read + Write + QdlChan>(
channel,
&mut outfile,
num_sectors,
slot,
phys_part_idx,
start_sector,
)
Expand All @@ -65,6 +67,7 @@ fn parse_patch_cmd<T: Read + Write + QdlChan>(
}

let byte_off = attrs.get("byte_offset").unwrap().parse::<u64>().unwrap();
let slot = attrs.get("slot").map_or(0, |a| a.parse::<u8>().unwrap());
let phys_part_idx = attrs
.get("physical_partition_number")
.unwrap()
Expand All @@ -74,7 +77,15 @@ fn parse_patch_cmd<T: Read + Write + QdlChan>(
let start_sector = attrs.get("start_sector").unwrap();
let val = attrs.get("value").unwrap();

firehose_patch(channel, byte_off, phys_part_idx, size, start_sector, val)
firehose_patch(
channel,
byte_off,
slot,
phys_part_idx,
size,
start_sector,
val,
)
}

const BOOTABLE_PART_NAMES: [&str; 3] = ["xbl", "xbl_a", "sbl1"];
Expand Down Expand Up @@ -104,6 +115,7 @@ fn parse_program_cmd<T: Read + Write + QdlChan>(
.unwrap()
.parse::<usize>()
.unwrap();
let slot = attrs.get("slot").map_or(0, |a| a.parse::<u8>().unwrap());
let phys_part_idx = attrs
.get("physical_partition_number")
.unwrap()
Expand Down Expand Up @@ -151,6 +163,7 @@ fn parse_program_cmd<T: Read + Write + QdlChan>(
&mut buf,
label,
num_sectors,
slot,
phys_part_idx,
start_sector,
)
Expand Down
15 changes: 10 additions & 5 deletions cli/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ use qdl::{self, firehose_read_storage, types::QdlChan};

pub fn read_gpt_from_storage<T: Read + Write + QdlChan>(
channel: &mut T,
slot: u8,
phys_part_idx: u8,
) -> Result<GPT> {
let mut buf = Cursor::new(Vec::<u8>::new());

// First, probe sector 1 to retrieve the GPT size
// Note, sector 0 contains a fake MBR as per the GPT spec ("Protective MBR")
firehose_read_storage(channel, &mut buf, 1, phys_part_idx, 1)?;
firehose_read_storage(channel, &mut buf, 1, slot, phys_part_idx, 1)?;

buf.rewind()?;
let header = match GPTHeader::read_from(&mut buf) {
Expand All @@ -28,7 +29,7 @@ pub fn read_gpt_from_storage<T: Read + Write + QdlChan>(

// Then, read the entire GPT and parse it
buf.rewind()?;
firehose_read_storage(channel, &mut buf, gpt_len, phys_part_idx, 0)?;
firehose_read_storage(channel, &mut buf, gpt_len, slot, phys_part_idx, 0)?;

// Ignore the aforementioned MBR sector
buf.set_position(channel.fh_config().storage_sector_size as u64);
Expand All @@ -38,9 +39,10 @@ pub fn read_gpt_from_storage<T: Read + Write + QdlChan>(
pub fn find_part<T: Read + Write + QdlChan>(
channel: &mut T,
name: &str,
slot: u8,
phys_part_idx: u8,
) -> Result<GPTPartitionEntry> {
match read_gpt_from_storage(channel, phys_part_idx)?
match read_gpt_from_storage(channel, slot, phys_part_idx)?
.iter()
.find(|(_, p)| p.partition_name.to_string() == name)
{
Expand All @@ -51,9 +53,10 @@ pub fn find_part<T: Read + Write + QdlChan>(

pub fn print_partition_table<T: Read + Write + QdlChan>(
channel: &mut T,
slot: u8,
phys_part_idx: u8,
) -> Result<()> {
let gpt = read_gpt_from_storage(channel, phys_part_idx)?;
let gpt = read_gpt_from_storage(channel, slot, phys_part_idx)?;

println!(
"GPT on physical partition {} of {}:",
Expand Down Expand Up @@ -87,9 +90,10 @@ pub fn read_storage_logical_partition<T: Read + Write + QdlChan>(
channel: &mut T,
out: &mut impl Write,
name: &str,
slot: u8,
phys_part_idx: u8,
) -> Result<()> {
let gpt = read_gpt_from_storage(channel, phys_part_idx)?;
let gpt = read_gpt_from_storage(channel, slot, phys_part_idx)?;

let part = gpt
.iter()
Expand All @@ -101,6 +105,7 @@ pub fn read_storage_logical_partition<T: Read + Write + QdlChan>(
channel,
out,
(part.ending_lba - part.starting_lba + 1) as usize,
slot,
phys_part_idx,
part.starting_lba as u32,
)
Expand Down
6 changes: 6 additions & 0 deletions qdl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ pub fn firehose_get_storage_info<T: Read + Write + QdlChan>(
pub fn firehose_patch<T: Read + Write + QdlChan>(
channel: &mut T,
byte_off: u64,
slot: u8,
phys_part_idx: u8,
size: u64,
start_sector: &str,
Expand All @@ -295,6 +296,7 @@ pub fn firehose_patch<T: Read + Write + QdlChan>(
),
("byte_offset", &byte_off.to_string()),
("filename", "DISK"), // DISK means "patch device's storage"
("slot", &slot.to_string()),
("physical_partition_number", &phys_part_idx.to_string()),
("size_in_bytes", &size.to_string()),
("start_sector", start_sector),
Expand Down Expand Up @@ -359,6 +361,7 @@ pub fn firehose_program_storage<T: Read + Write + QdlChan>(
data: &mut impl Read,
label: &str,
num_sectors: usize,
slot: u8,
phys_part_idx: u8,
start_sector: &str,
) -> anyhow::Result<()> {
Expand All @@ -371,6 +374,7 @@ pub fn firehose_program_storage<T: Read + Write + QdlChan>(
&channel.fh_config().storage_sector_size.to_string(),
),
("num_partition_sectors", &num_sectors.to_string()),
("slot", &slot.to_string()),
("physical_partition_number", &phys_part_idx.to_string()),
("start_sector", start_sector),
(
Expand Down Expand Up @@ -461,6 +465,7 @@ pub fn firehose_read_storage<T: Read + Write + QdlChan>(
channel: &mut T,
out: &mut impl Write,
num_sectors: usize,
slot: u8,
phys_part_idx: u8,
start_sector: u32,
) -> anyhow::Result<()> {
Expand All @@ -473,6 +478,7 @@ pub fn firehose_read_storage<T: Read + Write + QdlChan>(
&channel.fh_config().storage_sector_size.to_string(),
),
("num_partition_sectors", &num_sectors.to_string()),
("slot", &slot.to_string()),
("physical_partition_number", &phys_part_idx.to_string()),
("start_sector", &start_sector.to_string()),
],
Expand Down
2 changes: 2 additions & 0 deletions qdl/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub struct FirehoseConfiguration {
pub xml_buf_size: usize,

pub storage_sector_size: usize,
pub storage_slot: u8,
pub storage_type: FirehoseStorageType,

pub bypass_storage: bool,
Expand All @@ -73,6 +74,7 @@ impl Default for FirehoseConfiguration {
recv_buffer_size: 4096,
xml_buf_size: 4096,
storage_sector_size: 512,
storage_slot: 0,
storage_type: FirehoseStorageType::Emmc,
bypass_storage: true,
hash_packets: false,
Expand Down
Loading