Skip to content

Commit 15959e1

Browse files
committed
fat: Add utility functions for loading data from files
This allows much of the existing code to be simplified, by letting us load the remainer of a file into a specific memory region. This also makes it much easier to write the code to load the Linux Kernel header from the bzimage file. Signed-off-by: Joe Richey <joerichey@google.com>
1 parent e421bac commit 15959e1

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/boot.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use core::mem;
22

3-
use crate::common;
3+
use crate::{
4+
common,
5+
fat::{Error, Read},
6+
mem::MemoryRegion,
7+
};
48

59
// Common data needed for all boot paths
610
pub trait Info {
@@ -140,6 +144,26 @@ pub struct Header {
140144
pub handover_offset: u32,
141145
}
142146

147+
impl Header {
148+
// Read a kernel header from the first two sectors of a file
149+
pub fn from_file(f: &mut dyn Read) -> Result<Self, Error> {
150+
let mut data: [u8; 1024] = [0; 1024];
151+
let mut region = MemoryRegion::from_bytes(&mut data);
152+
153+
f.seek(0)?;
154+
f.load_file(&mut region)?;
155+
156+
#[repr(C)]
157+
struct HeaderData {
158+
before: [u8; HEADER_START],
159+
hdr: Header,
160+
after: [u8; 1024 - HEADER_END],
161+
}
162+
// SAFETY: Struct consists entirely of primitive integral types.
163+
Ok(unsafe { mem::transmute::<_, HeaderData>(data) }.hdr)
164+
}
165+
}
166+
143167
// Right now the stucts below are unused, so we only need them to be the correct
144168
// size. Update test_size_and_offset if a struct's real definition is added.
145169
#[derive(Clone, Copy)]

src/fat.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::block::SectorRead;
15+
use crate::{block::SectorRead, mem::MemoryRegion};
1616

1717
#[repr(packed)]
1818
struct Header {
@@ -244,6 +244,27 @@ pub trait Read {
244244
fn read(&mut self, data: &mut [u8]) -> Result<u32, Error>;
245245
fn seek(&mut self, offset: u32) -> Result<(), Error>;
246246
fn get_size(&self) -> u32;
247+
248+
// Loads the remainer of the file into the specified memory region
249+
fn load_file(&mut self, mem: &mut MemoryRegion) -> Result<(), Error> {
250+
let mut chunks = mem.as_bytes().chunks_exact_mut(512);
251+
for chunk in chunks.by_ref() {
252+
self.read(chunk)?;
253+
}
254+
let last = chunks.into_remainder();
255+
if last.is_empty() {
256+
return Ok(());
257+
}
258+
// Use tmp buffer for last, partial sector
259+
let mut dst: [u8; 512] = [0; 512];
260+
if let Some(err) = self.read(&mut dst).err() {
261+
if err != Error::EndOfFile {
262+
return Err(err);
263+
}
264+
}
265+
last.copy_from_slice(&dst[..last.len()]);
266+
Ok(())
267+
}
247268
}
248269

249270
impl<'a> Read for File<'a> {

0 commit comments

Comments
 (0)