Skip to content

Commit 74da030

Browse files
committed
me: add method to relocate partitions
Signed-off-by: Daniel Maslowski <info@orangecms.org>
1 parent 621f49b commit 74da030

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/me.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::dir::{
1212
gen2::Directory as Gen2Directory,
1313
gen3::{CPD_MAGIC_BYTES, CodePartitionDirectory},
1414
};
15+
use crate::part::gen2::Gen2Partition;
1516
use crate::part::{
1617
fpt::{FPT, MIN_FPT_SIZE},
1718
partitions::Partitions,
@@ -63,6 +64,67 @@ impl FPTArea {
6364
}
6465
}
6566

67+
pub fn relocate_partitions(&mut self) -> Result<(), String> {
68+
let sorted_parts = &self.partitions.get_sorted();
69+
let first = sorted_parts
70+
.into_iter()
71+
.filter(|p| p.entry().size() > 0)
72+
.nth(0);
73+
if let Some(p) = first {
74+
let e = p.entry();
75+
let n = e.name();
76+
let min_offset = MIN_FPT_SIZE;
77+
let new_offset = match &self.partitions {
78+
Partitions::Gen2(parts) => {
79+
// Find a Directory partition to calculate the offset.
80+
let dir_part = parts.iter().find(|p| matches!(p, Gen2Partition::Dir(_)));
81+
match dir_part {
82+
Some(Gen2Partition::Dir(d)) => d.dir.calc_new_offset(min_offset as u32)?,
83+
_ => return Err("no directory partition found".into()),
84+
}
85+
}
86+
Partitions::Gen3(_) => e.offset().min(min_offset) as u32,
87+
_ => todo!(),
88+
};
89+
90+
let old_offset = e.offset();
91+
println!("old offset: {old_offset:08x}");
92+
println!("new offset: {new_offset:08x}");
93+
94+
if let Err(e) = self.partitions.relocate(&n, new_offset) {
95+
return Err(format!("Cannot relocate partitions: {e}"));
96+
}
97+
98+
let offset = new_offset as usize;
99+
// It may happen that some part of the FPT area had not been covered
100+
// by an FPT entry, but it contained data that can now be overwritten
101+
// when relocating partitions.
102+
let mut non_covered = vec![];
103+
let r = offset..offset + e.size();
104+
for nc in &self.non_covered {
105+
let o = nc.offset;
106+
let e = o + nc.data.len();
107+
if r.contains(&o) || r.contains(&e) {
108+
println!("Drop data not covered by FPT and now overlapping: {o:08x}..{e:08x}");
109+
} else {
110+
non_covered.push(nc.clone());
111+
}
112+
}
113+
self.non_covered = non_covered;
114+
115+
// Update partition table entry
116+
for e in &mut self.fpt.entries {
117+
if e.name() == n {
118+
e.set_offset(offset as u32);
119+
}
120+
}
121+
122+
Ok(())
123+
} else {
124+
Err("no FPT partitions found".into())
125+
}
126+
}
127+
66128
/// Clear out fully removable partitions and adjust FPT
67129
pub fn to_vec(&self) -> Vec<u8> {
68130
let debug = true;

0 commit comments

Comments
 (0)