forked from M-Labs/zynq-rs
some WIP exploration
This commit is contained in:
parent
482dc07a5a
commit
ae6b33a760
|
@ -1,5 +1,7 @@
|
|||
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 log::debug;
|
||||
|
||||
|
@ -8,12 +10,13 @@ pub enum BootgenLoadingError {
|
|||
InvalidBootImageHeader,
|
||||
MissingPartition,
|
||||
EncryptedBitstream,
|
||||
IoError(Error),
|
||||
IoError(IoError),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +72,7 @@ fn read_u32<Reader: Read>(reader: &mut Reader) -> Result<u32, BootgenLoadingErro
|
|||
}
|
||||
|
||||
/// Load PL partition header.
|
||||
fn load_pl_header<File: Read + Seek>(
|
||||
fn load_pl_header<File: Read + Seek + IoBase>(
|
||||
file: &mut File,
|
||||
) -> Result<Option<PartitionHeader>, BootgenLoadingError> {
|
||||
let mut buffer: [u8; 0x40] = [0; 0x40];
|
||||
|
|
|
@ -13,7 +13,7 @@ pub mod bootgen;
|
|||
#[derive(Debug)]
|
||||
pub enum Error<'a> {
|
||||
SdError(sdio::sd_card::CardInitializationError),
|
||||
IoError(sd_reader::SdReader::Error),
|
||||
IoError(fatfs::Error<sd_reader::IoError>),
|
||||
Utf8Error(FromUtf8Error),
|
||||
KeyNotFoundError(&'a str),
|
||||
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> {
|
||||
fn from(error: sd_reader::SdReader::Error) -> Self {
|
||||
impl<'a> From<fatfs::Error<sd_reader::IoError>> for Error<'a> {
|
||||
fn from(error: fatfs::Error<sd_reader::IoError>) -> Self {
|
||||
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>(
|
||||
key: &'a str,
|
||||
buffer: &mut Vec<u8>,
|
||||
file: fatfs::File<sd_reader::SdReader, fatfs::DefaultTimeProvider, fatfs::LossyOemCpConverter>,
|
||||
file: FFile,
|
||||
) -> Result<'a, ()> {
|
||||
let prefix = [key, "="].concat().to_ascii_lowercase();
|
||||
let file_buf = &mut [];
|
||||
|
|
|
@ -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 log::debug;
|
||||
use alloc::vec::Vec;
|
||||
|
@ -15,6 +15,46 @@ const PARTID_FAT16_LBA: u8 = 0x0E;
|
|||
|
||||
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`.
|
||||
/// 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 {
|
||||
type Error = fatfs::error::Error<String>;
|
||||
type Error = IoError;
|
||||
}
|
||||
|
||||
impl SdReader {
|
||||
|
@ -73,7 +113,7 @@ impl SdReader {
|
|||
|
||||
/// Internal read function for unaligned read.
|
||||
/// 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 {
|
||||
return Ok(0);
|
||||
}
|
||||
|
@ -87,7 +127,7 @@ impl SdReader {
|
|||
|
||||
/// Internal write function for unaligned write.
|
||||
/// 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 {
|
||||
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.
|
||||
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.seek(SeekFrom::Start(0))
|
||||
}
|
||||
|
@ -146,16 +186,13 @@ impl SdReader {
|
|||
/// 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,
|
||||
/// 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];
|
||||
self.seek(SeekFrom::Start(0x1FE))?;
|
||||
self.read_exact(&mut buffer[..2])?;
|
||||
// check MBR signature
|
||||
if buffer[..2] != MBR_SIGNATURE {
|
||||
return Err(Self::Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"Incorrect signature for MBR sector.",
|
||||
));
|
||||
return Err(IoError::new(ErrorKind::InvalidData, "Incorrect signature for MBR sector."));
|
||||
}
|
||||
// Read partition ID.
|
||||
self.seek(SeekFrom::Start(entry as u64 + 0x4))?;
|
||||
|
@ -165,9 +202,8 @@ impl SdReader {
|
|||
PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 |
|
||||
PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {}
|
||||
_ => {
|
||||
return Err(Self::Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"No FAT partition found for the specified entry.",
|
||||
return Err(IoError::new(ErrorKind::InvalidData,
|
||||
"No FAT partition found for the specified entry."
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -185,10 +221,7 @@ impl SdReader {
|
|||
fatfs::FileSystem::new(self, fatfs::FsOptions::new())
|
||||
}
|
||||
|
||||
fn cmd_error_to_io_error(_: CmdTransferError) -> Self::Error {
|
||||
Self::Error::Other("Command transfer error")
|
||||
}
|
||||
fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
|
||||
fn fill_buf(&mut self) -> IoResult<&[u8]> {
|
||||
if self.index == BLOCK_SIZE {
|
||||
// flush the buffer if it is dirty before overwriting it with new data
|
||||
if self.dirty {
|
||||
|
@ -211,7 +244,7 @@ impl 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 (a, b, c) = self.block_align_mut(buf);
|
||||
self.read_unaligned(a)?;
|
||||
|
@ -237,7 +270,7 @@ impl Read 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);
|
||||
self.write_unaligned(a)?;
|
||||
if b.len() > 0 {
|
||||
|
@ -258,7 +291,7 @@ impl Write for SdReader {
|
|||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
if self.dirty {
|
||||
let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32);
|
||||
self.sd
|
||||
|
@ -271,14 +304,14 @@ impl Write 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 {
|
||||
SeekFrom::Start(x) => self.offset as i64 + x as i64,
|
||||
SeekFrom::Current(x) => self.byte_addr as i64 + x,
|
||||
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 {
|
||||
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 address_same_block =
|
||||
|
|
Loading…
Reference in New Issue