1
0
Fork 0

some WIP exploration

This commit is contained in:
Simon Renblad 2024-07-30 17:35:30 +08:00
parent 482dc07a5a
commit ae6b33a760
3 changed files with 69 additions and 31 deletions

View File

@ -1,5 +1,7 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use core_io::{Error, Read, Seek, SeekFrom}; use fatfs::{Read, Seek, SeekFrom, IoBase};
use core::fmt::Write;
use crate::sd_reader::IoError;
use libboard_zynq::devc; use libboard_zynq::devc;
use log::debug; use log::debug;
@ -8,12 +10,13 @@ pub enum BootgenLoadingError {
InvalidBootImageHeader, InvalidBootImageHeader,
MissingPartition, MissingPartition,
EncryptedBitstream, EncryptedBitstream,
IoError(Error), IoError(IoError),
DevcError(devc::DevcError), DevcError(devc::DevcError),
} }
impl From<Error> for BootgenLoadingError {
fn from(error: Error) -> Self { impl From<T: IoError> for BootgenLoadingError {
fn from(error: IoError) -> Self {
BootgenLoadingError::IoError(error) BootgenLoadingError::IoError(error)
} }
} }
@ -69,7 +72,7 @@ fn read_u32<Reader: Read>(reader: &mut Reader) -> Result<u32, BootgenLoadingErro
} }
/// Load PL partition header. /// Load PL partition header.
fn load_pl_header<File: Read + Seek>( fn load_pl_header<File: Read + Seek + IoBase>(
file: &mut File, file: &mut File,
) -> Result<Option<PartitionHeader>, BootgenLoadingError> { ) -> Result<Option<PartitionHeader>, BootgenLoadingError> {
let mut buffer: [u8; 0x40] = [0; 0x40]; let mut buffer: [u8; 0x40] = [0; 0x40];

View File

@ -13,7 +13,7 @@ pub mod bootgen;
#[derive(Debug)] #[derive(Debug)]
pub enum Error<'a> { pub enum Error<'a> {
SdError(sdio::sd_card::CardInitializationError), SdError(sdio::sd_card::CardInitializationError),
IoError(sd_reader::SdReader::Error), IoError(fatfs::Error<sd_reader::IoError>),
Utf8Error(FromUtf8Error), Utf8Error(FromUtf8Error),
KeyNotFoundError(&'a str), KeyNotFoundError(&'a str),
NoConfig, NoConfig,
@ -39,8 +39,8 @@ impl<'a> From<sdio::sd_card::CardInitializationError> for Error<'a> {
} }
} }
impl<'a> From<sd_reader::SdReader::Error> for Error<'a> { impl<'a> From<fatfs::Error<sd_reader::IoError>> for Error<'a> {
fn from(error: sd_reader::SdReader::Error) -> Self { fn from(error: fatfs::Error<sd_reader::IoError>) -> Self {
Error::IoError(error) Error::IoError(error)
} }
} }
@ -51,10 +51,12 @@ impl<'a> From<FromUtf8Error> for Error<'a> {
} }
} }
pub type FFile = fatfs::File<sd_reader::SdReader, fatfs::DefaultTimeProvider, fatfs::LossyOemCpConverter>;
fn parse_config<'a>( fn parse_config<'a>(
key: &'a str, key: &'a str,
buffer: &mut Vec<u8>, buffer: &mut Vec<u8>,
file: fatfs::File<sd_reader::SdReader, fatfs::DefaultTimeProvider, fatfs::LossyOemCpConverter>, file: FFile,
) -> Result<'a, ()> { ) -> Result<'a, ()> {
let prefix = [key, "="].concat().to_ascii_lowercase(); let prefix = [key, "="].concat().to_ascii_lowercase();
let file_buf = &mut []; let file_buf = &mut [];

View File

@ -1,4 +1,4 @@
use fatfs::{self as fatfs, Read, Seek, SeekFrom, Write, IoBase}; use fatfs::{self as fatfs, Read, Seek, SeekFrom, Write, IoBase, IoError as BaseIoError};
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError}; use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
use log::debug; use log::debug;
use alloc::vec::Vec; use alloc::vec::Vec;
@ -15,6 +15,46 @@ const PARTID_FAT16_LBA: u8 = 0x0E;
const BLOCK_SIZE: usize = 512; const BLOCK_SIZE: usize = 512;
#[derive(Debug)]
pub enum ErrorKind {
InvalidData,
InvalidInput,
Other
}
#[derive(Debug)]
pub struct IoError {
error: ErrorKind,
message: String
}
impl IoError {
pub fn new(error: ErrorKind, message: &str) -> Self {
IoError {
error,
message: String::from(message)
}
}
}
impl BaseIoError for IoError {
fn is_interrupted() -> IoError {
false
}
fn new_unexpected_eof_error() -> IoError{
}
fn new_write_zero_error() -> IoError {
}
}
pub type IoResult<T> = core::Result<T, IoError>;
fn cmd_error_to_io_error(_: CmdTransferError) -> IoError {
IoError::new(ErrorKind::Other, "Command transfer error")
}
/// SdReader struct implementing `Read + BufRead + Write + Seek` traits for `core_io`. /// SdReader struct implementing `Read + BufRead + Write + Seek` traits for `core_io`.
/// Used as an adaptor for fatfs crate, but could be used directly for raw data access. /// Used as an adaptor for fatfs crate, but could be used directly for raw data access.
/// ///
@ -51,7 +91,7 @@ pub enum PartitionEntry {
} }
impl IoBase for SdReader { impl IoBase for SdReader {
type Error = fatfs::error::Error<String>; type Error = IoError;
} }
impl SdReader { impl SdReader {
@ -73,7 +113,7 @@ impl SdReader {
/// Internal read function for unaligned read. /// Internal read function for unaligned read.
/// The read must not cross block boundary. /// The read must not cross block boundary.
fn read_unaligned(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { fn read_unaligned(&mut self, buf: &mut [u8]) -> IoResult<usize> {
if buf.len() == 0 { if buf.len() == 0 {
return Ok(0); return Ok(0);
} }
@ -87,7 +127,7 @@ impl SdReader {
/// Internal write function for unaligned write. /// Internal write function for unaligned write.
/// The write must not cross block boundary. /// The write must not cross block boundary.
fn write_unaligned(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { fn write_unaligned(&mut self, buf: &[u8]) -> IoResult<usize> {
if buf.len() == 0 { if buf.len() == 0 {
return Ok(0); return Ok(0);
} }
@ -138,7 +178,7 @@ impl SdReader {
} }
/// Set the base offset of the SD card, to transform from physical address to logical address. /// Set the base offset of the SD card, to transform from physical address to logical address.
fn set_base_offset(&mut self, offset: u32) -> Result<u64, Self::Error> { fn set_base_offset(&mut self, offset: u32) -> IoResult<u64> {
self.offset = offset; self.offset = offset;
self.seek(SeekFrom::Start(0)) self.seek(SeekFrom::Start(0))
} }
@ -146,16 +186,13 @@ impl SdReader {
/// Mount fatfs from partition entry, and return the fatfs object if success. /// Mount fatfs from partition entry, and return the fatfs object if success.
/// This takes the ownership of self, so currently there is no way to recover from an error, /// This takes the ownership of self, so currently there is no way to recover from an error,
/// except creating a new SD card instance. /// except creating a new SD card instance.
pub fn mount_fatfs(mut self, entry: PartitionEntry) -> Result<fatfs::FileSystem<Self>, Self::Error> { pub fn mount_fatfs(mut self, entry: PartitionEntry) -> IoResult<fatfs::FileSystem<Self>> {
let mut buffer: [u8; 4] = [0; 4]; let mut buffer: [u8; 4] = [0; 4];
self.seek(SeekFrom::Start(0x1FE))?; self.seek(SeekFrom::Start(0x1FE))?;
self.read_exact(&mut buffer[..2])?; self.read_exact(&mut buffer[..2])?;
// check MBR signature // check MBR signature
if buffer[..2] != MBR_SIGNATURE { if buffer[..2] != MBR_SIGNATURE {
return Err(Self::Error::new( return Err(IoError::new(ErrorKind::InvalidData, "Incorrect signature for MBR sector."));
ErrorKind::InvalidData,
"Incorrect signature for MBR sector.",
));
} }
// Read partition ID. // Read partition ID.
self.seek(SeekFrom::Start(entry as u64 + 0x4))?; self.seek(SeekFrom::Start(entry as u64 + 0x4))?;
@ -165,9 +202,8 @@ impl SdReader {
PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 | PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 |
PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {} PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {}
_ => { _ => {
return Err(Self::Error::new( return Err(IoError::new(ErrorKind::InvalidData,
ErrorKind::InvalidData, "No FAT partition found for the specified entry."
"No FAT partition found for the specified entry.",
)); ));
} }
} }
@ -185,10 +221,7 @@ impl SdReader {
fatfs::FileSystem::new(self, fatfs::FsOptions::new()) fatfs::FileSystem::new(self, fatfs::FsOptions::new())
} }
fn cmd_error_to_io_error(_: CmdTransferError) -> Self::Error { fn fill_buf(&mut self) -> IoResult<&[u8]> {
Self::Error::Other("Command transfer error")
}
fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
if self.index == BLOCK_SIZE { if self.index == BLOCK_SIZE {
// flush the buffer if it is dirty before overwriting it with new data // flush the buffer if it is dirty before overwriting it with new data
if self.dirty { if self.dirty {
@ -211,7 +244,7 @@ impl SdReader {
impl Read for SdReader { impl Read for SdReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
let total_length = buf.len(); let total_length = buf.len();
let (a, b, c) = self.block_align_mut(buf); let (a, b, c) = self.block_align_mut(buf);
self.read_unaligned(a)?; self.read_unaligned(a)?;
@ -237,7 +270,7 @@ impl Read for SdReader {
} }
impl Write for SdReader { impl Write for SdReader {
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
let (a, b, c) = self.block_align(buf); let (a, b, c) = self.block_align(buf);
self.write_unaligned(a)?; self.write_unaligned(a)?;
if b.len() > 0 { if b.len() > 0 {
@ -258,7 +291,7 @@ impl Write for SdReader {
Ok(buf.len()) Ok(buf.len())
} }
fn flush(&mut self) -> Result<(), Self::Error> { fn flush(&mut self) -> IoResult<()> {
if self.dirty { if self.dirty {
let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32); let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32);
self.sd self.sd
@ -271,14 +304,14 @@ impl Write for SdReader {
} }
impl Seek for SdReader { impl Seek for SdReader {
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Self::Error> { fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> {
let raw_target = match pos { let raw_target = match pos {
SeekFrom::Start(x) => self.offset as i64 + x as i64, SeekFrom::Start(x) => self.offset as i64 + x as i64,
SeekFrom::Current(x) => self.byte_addr as i64 + x, SeekFrom::Current(x) => self.byte_addr as i64 + x,
SeekFrom::End(_) => panic!("SD card does not support seek from end"), SeekFrom::End(_) => panic!("SD card does not support seek from end"),
}; };
if raw_target < self.offset as i64 || raw_target > core::u32::MAX as i64 { if raw_target < self.offset as i64 || raw_target > core::u32::MAX as i64 {
return Err(Error::new(ErrorKind::InvalidInput, "Invalid address")); return Err(IoError::new(ErrorKind::InvalidInput, "Invalid address"));
} }
let target_byte_addr = raw_target as u32; let target_byte_addr = raw_target as u32;
let address_same_block = let address_same_block =