Tue, 05 Dec 2023 23:34:04 +0100
6 files changed,
27 insertions(+),
204 deletions(-)
D
boot/fat.c
@@ -1,183 +0,0 @@
-#include "fat.h" -#include "string.h" -#include <stdint.h> - -typedef struct { - char jmp[3]; - char oemname[8]; - - uint16_t bytes_per_sect; - uint8_t sect_per_cluster; - uint16_t num_reserved_sectors; - uint8_t num_FAT; - uint16_t max_root_dir_entries; - uint16_t total_log_sectors; - uint8_t media_desc; - uint16_t log_sect_per_fat; -} __attribute__((packed)) BOOT_SECT; - -typedef struct { - char name[8]; - char ext[3]; - uint8_t file_attr; - uint8_t user_attr; - uint8_t del_char; - uint16_t create_time; - uint16_t create_date; - uint16_t last_access_date; - uint16_t access_rights; - uint16_t last_modified_time; - uint16_t last_modified_date; - uint16_t start_of_clusters; - uint32_t file_size; -} __attribute__((packed)) DIR_ENTRY; - -typedef struct { - uint8_t seq_num; - uint16_t part_1[5]; - uint8_t file_attr; - uint8_t user_attr; - uint8_t del_char; - uint16_t part_2[6]; - uint16_t start_of_clusters; - uint16_t part_3[2]; -} __attribute__((packed)) VFAT_LFN_ENTRY; - - -void *FAT_addr; -BOOT_SECT *boot_sect; - -uint32_t FAT1_lba; -uint32_t FAT2_lba; -uint32_t root_lba; -uint32_t data_lba; - -void FAT_init() { - // open image file - FAT_addr = (void*)(0x10000); - - boot_sect = (BOOT_SECT*)(FAT_addr); - - FAT1_lba = boot_sect->num_reserved_sectors; - FAT2_lba = FAT1_lba + boot_sect->log_sect_per_fat; - root_lba = FAT1_lba + (boot_sect->log_sect_per_fat * boot_sect->num_FAT); - - long root_dir_size = boot_sect->max_root_dir_entries * sizeof(DIR_ENTRY); - data_lba = root_lba + (root_dir_size / boot_sect->bytes_per_sect); -} - -void *FAT_read_sector_offset(uint32_t lba, uint32_t *offset) { - if (offset != NULL) { - lba += (*offset) / boot_sect->bytes_per_sect; - *offset = (*offset) % boot_sect->bytes_per_sect; - } - - return (void*)((long)(FAT_addr) + (long)(lba * boot_sect->bytes_per_sect)); -} - -void *FAT_read_cluster(uint16_t cluster, void *buffer) { - // TODO: perform memcpy - void *addr = FAT_read_sector_offset(data_lba + ((cluster - 2) * boot_sect->sect_per_cluster), NULL); - - uint32_t cluster_size = boot_sect->bytes_per_sect * boot_sect->sect_per_cluster; - - memcpy(buffer, addr, cluster_size); - - return (void*)((uint8_t*)(buffer) + cluster_size); -} - -int FAT_root_dir_next(int index, char *fname_buffer, uint16_t *first_cluster, uint32_t *file_size) { - memset(fname_buffer, 0, sizeof(fname_buffer)); - - while (1) { - // index overflow - if (index >= boot_sect->max_root_dir_entries) { - return -1; - } - - uint32_t offset = index * sizeof(DIR_ENTRY); - void *sect = FAT_read_sector_offset(root_lba, &offset); - DIR_ENTRY *dir_entry = (DIR_ENTRY *)((uint32_t)(sect) + offset); - - // if first character of name is 0, then no subsequent entry is in use - if (dir_entry->name[0] == 0x00) { - return -1; - } - - // deleted file - if (dir_entry->name[0] == (char)(0xE5)) { - index++; - continue; - } - - // VFAT LFN entry - if (dir_entry->file_attr == 0x0F && dir_entry->start_of_clusters == 0 && dir_entry->file_size != 0) { - VFAT_LFN_ENTRY *lfn_entry = (VFAT_LFN_ENTRY*)(dir_entry); - - int offset = 13 * ((lfn_entry->seq_num & 0x3F) - 1); - - // read long file name - for (int i = 0; i < 5; i++) { - fname_buffer[offset++] = lfn_entry->part_1[i]; - } - - for (int i = 0; i < 6; i++) { - fname_buffer[offset++] = lfn_entry->part_2[i]; - } - - for (int i = 0; i < 2; i++) { - fname_buffer[offset++] = lfn_entry->part_3[i]; - } - - index++; - continue; - } - - if (index == 0 && (dir_entry->file_attr & 0x08) && dir_entry->file_size == 0) { - // volume label - index++; - continue; - - } else if ((dir_entry->file_attr & 0x10) && dir_entry->file_size == 0) { - // subdirectory - - } else { - // regular file - - } - - *file_size = dir_entry->file_size; - *first_cluster = dir_entry->start_of_clusters; - - // if no VFAT LFN exists, use DOS name - if (fname_buffer[0] == 0) { - for (int i = 0; i < 8; i++) { - fname_buffer[i] = dir_entry->name[i]; - } - fname_buffer[8] = '.'; - for (int i = 0; i < 3; i++) { - fname_buffer[i + 9] = dir_entry->ext[i]; - } - fname_buffer[12] = 0; - } - - return index + 1; - } -} - -uint16_t FAT_next_cluster(uint16_t cluster) { - // assuming FAT12 - uint32_t offset = (cluster >> 1) * 3; - uint8_t *sect = FAT_read_sector_offset(FAT1_lba, &offset); - sect += offset; - - if (cluster & 0x01) { - uint16_t high = (uint16_t)(sect[2]); - uint16_t low = (uint16_t)(sect[1] & 0xF0) >> 4; - return (high << 4) | low; - } else { - uint16_t low = (uint16_t)(sect[0]); - uint16_t high = (uint16_t)(sect[1] & 0x0F) << 8; - return low | high; - } -}
D
boot/fat.h
@@ -1,13 +0,0 @@
-#ifndef FAT_H -#define FAT_H - -#include <stdint.h> - -void FAT_init(); -void *FAT_read_sector_offset(uint32_t lba, uint32_t *offset); -void *FAT_read_cluster(uint16_t cluster, void *buffer); -uint16_t FAT_next_cluster(uint16_t cluster); -int FAT_root_dir_next(int index, char *fname_buffer, uint16_t *first_cluster, uint32_t *file_size); -void *FAT_find_file(const char *fname); - -#endif
M
boot/main.c
→
boot/main.c
@@ -1,7 +1,8 @@
#include <stdint.h> +#include <stddef.h> #include "string.h" -#include "fat.h" +#include "fat12.h" void printc(char c) { static uint8_t *display = (uint8_t*)(0xB8000);@@ -21,6 +22,23 @@
while (1) {} } +FAT12_descriptor_t fat_desc; + +void *FAT12_read(uint32_t lba, uint32_t *offset, size_t size, void *buffer) { + void *FAT_addr = (void*)(0x10000); + + if (offset != NULL) { + lba += (*offset) / fat_desc.bytes_per_sect; + *offset = (*offset) % fat_desc.bytes_per_sect; + + void *ptr = (void*)((long)(FAT_addr) + (long)(lba * fat_desc.bytes_per_sect)); + return memcpy(buffer, ptr + *offset, size); + } else { + void *ptr = (void*)((long)(FAT_addr) + (long)(lba * fat_desc.bytes_per_sect)); + return memcpy(buffer, ptr, size); + } +} + int load_kernel() { // debug output uint8_t *dbuf = (uint8_t *)(0x10000);@@ -37,8 +55,7 @@ printc(' ');
} //while (1); - - FAT_init(); + FAT12_init(&fat_desc); int i = 0;@@ -49,7 +66,7 @@ while (1) {
char buffer[832]; uint32_t file_size; - i = FAT_root_dir_next(i, buffer, &first_cluster, &file_size); + i = FAT12_root_dir_next(&fat_desc, i, buffer, &first_cluster, &file_size); print_string(buffer); print_string(" ");@@ -62,8 +79,8 @@ // copy all clusters
uint16_t cluster = first_cluster; uint8_t *buffer = (uint8_t *)(0x100000); while (1) { - buffer = FAT_read_cluster(cluster, buffer); - cluster = FAT_next_cluster(cluster); + buffer = FAT12_read_cluster(&fat_desc, cluster, buffer); + cluster = FAT12_next_cluster(&fat_desc, cluster); if (cluster == 0xFFF || cluster == 0x000) { break; } }
M
boot/paging.c
→
boot/paging.c
@@ -1,7 +1,6 @@
#include "paging.h" #include "linker.h" #include "string.h" -#include "fat.h" void *create_kernel_environment() {
M
kernel/fat12.c
→
common/fat12.c
@@ -77,7 +77,9 @@ fat->cluster_size = fat->bytes_per_sect * fat->sect_per_cluster;
} void *FAT12_read_cluster(FAT12_descriptor_t *fat, uint16_t cluster, void *buffer) { - return FAT12_read(fat->data_lba + ((cluster - 2) * fat->sect_per_cluster), NULL, fat->cluster_size, buffer); + FAT12_read(fat->data_lba + ((cluster - 2) * fat->sect_per_cluster), NULL, fat->cluster_size, buffer); + + return buffer += fat->cluster_size; } int FAT12_root_dir_next(FAT12_descriptor_t *fat, int index, char *fname_buffer, uint16_t *first_cluster, uint32_t *file_size) {
M
kernel/fat12.h
→
common/fat12.h
@@ -2,6 +2,7 @@ #ifndef FAT12_H
#define FAT12_H #include <stdint.h> +#include <stddef.h> typedef struct { // logical block addresses of FAT regions