From c72dee7352106ae99223b72f54c53868e7e15216 Mon Sep 17 00:00:00 2001 From: koolkdev Date: Sun, 26 Mar 2017 00:05:10 +0300 Subject: [PATCH] Add sd_fat.c - access to the SD FAT32 in FS main thread --- ios_fs/source/sd_fat.c | 94 ++++++++++++++++++++++++++++++++++++++++++ ios_fs/source/sd_fat.h | 8 ++++ 2 files changed, 102 insertions(+) create mode 100644 ios_fs/source/sd_fat.c create mode 100644 ios_fs/source/sd_fat.h diff --git a/ios_fs/source/sd_fat.c b/ios_fs/source/sd_fat.c new file mode 100644 index 0000000..76ae643 --- /dev/null +++ b/ios_fs/source/sd_fat.c @@ -0,0 +1,94 @@ +#include +#include "types.h" +#include "imports.h" +#include "devices.h" +#include "sdio.h" +#include "text.h" +#include "sd_fat.h" + +unsigned char sd_io_buffer[0x40000] __attribute__((aligned(0x40))) __attribute__((section(".io_buffer"))); +unsigned int fat_sector = 0; + +#define PARTITION_TYPE_FAT32 0x0c +#define PARTITION_TYPE_FAT32_CHS 0x0b + +#define MBR_SIGNATURE 0x55AA +#define EBR_SIGNATURE MBR_SIGNATURE + +#define PARTITION_BOOTABLE 0x80 /* Bootable (active) */ +#define PARTITION_NONBOOTABLE 0x00 /* Non-bootable */ +#define PARTITION_TYPE_GPT 0xEE /* Indicates that a GPT header is available */ + +typedef struct _PARTITION_RECORD { + u8 status; /* Partition status; see above */ + u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */ + u8 type; /* Partition type; see above */ + u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */ + u32 lba_start; /* Local block address to first sector of partition */ + u32 block_count; /* Number of blocks in partition */ +} __attribute__((__packed__)) PARTITION_RECORD; + + +typedef struct _MASTER_BOOT_RECORD { + u8 code_area[446]; /* Code area; normally empty */ + PARTITION_RECORD partitions[4]; /* 4 primary partitions */ + u16 signature; /* MBR signature; 0xAA55 */ +} __attribute__((__packed__)) MASTER_BOOT_RECORD; + +int sd_fat_read(unsigned long sector, unsigned char *buffer, unsigned long sector_count) +{ + // It seems that sdcard_readwrite overwrite more bytes than requested with 0xff.... So I use io_buffer to read it. + if (sector_count * SDIO_BYTES_PER_SECTOR > sizeof(sd_io_buffer)) return 0; + int result = sdcard_readwrite(SDIO_READ, sd_io_buffer, sector_count, SDIO_BYTES_PER_SECTOR, fat_sector + sector, NULL, DEVICE_ID_SDCARD_PATCHED); + if (result) return 0; + memcpy(buffer, sd_io_buffer, sector_count * SDIO_BYTES_PER_SECTOR); + return 1; +} + +int sd_fat_write(unsigned long sector, unsigned char *buffer, unsigned long sector_count) +{ + if (sector_count * SDIO_BYTES_PER_SECTOR > sizeof(sd_io_buffer)) return 0; + int result = sdcard_readwrite(SDIO_WRITE, buffer, sector_count, SDIO_BYTES_PER_SECTOR, fat_sector + sector, NULL, DEVICE_ID_SDCARD_PATCHED); + return result ? 0 : 1; +} + +int InitSDCardFAT32() +{ + MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD*)sd_io_buffer; + memset(mbr, 0, SDIO_BYTES_PER_SECTOR); + + int result = sdcard_readwrite(SDIO_READ, mbr, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED); + if(result != 0) + { + _printf(20, 40, "SD card read failed %i", result); + return result; + } + + if (mbr->signature != MBR_SIGNATURE) { + _printf(20, 40, "SD not MBR"); + return -1; + } + + if (mbr->partitions[0].status != PARTITION_BOOTABLE && mbr->partitions[0].status != PARTITION_NONBOOTABLE) { + _printf(20, 40, "Invalid paritition status"); + return -1; + } + + if (mbr->partitions[0].type != PARTITION_TYPE_FAT32 && mbr->partitions[0].type != PARTITION_TYPE_FAT32_CHS) { + _printf(20, 40, "First paritition not FAT32"); + return -1; + } + + fat_sector = le32(mbr->partitions[0].lba_start); + + fl_init(); + + result = fl_attach_media(sd_fat_read, sd_fat_write); + if (result != FAT_INIT_OK) + { + _printf(20, 40, "FAT32 attach failed %i", result); + return result; + } + + return 0; +} diff --git a/ios_fs/source/sd_fat.h b/ios_fs/source/sd_fat.h new file mode 100644 index 0000000..e9a3e07 --- /dev/null +++ b/ios_fs/source/sd_fat.h @@ -0,0 +1,8 @@ +#ifndef _DS_FAT_H_ +#define _DS_FAT_H_ + +#include "fat/fat_filelib.h" + +int InitSDCardFAT32(); + +#endif // _FAT32_FORMAT_H_