1 Commits

Author SHA1 Message Date
23cb50a73f Create ata.h
implement the base ata pio mode driver so that the filesystems like fat16, fat32 work. This is the header for that. It will need a iso9660 driver for cdrom etc optical media
2026-01-18 17:44:18 -08:00
3 changed files with 43 additions and 167 deletions

43
kernel/ata.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef ATA_H
#define ATA_H
#include <stdint.h>
#include <stdbool.h>
/* ATA I/O ports */
#define ATA_PRIMARY_IO 0x1F0
#define ATA_PRIMARY_CTRL 0x3F6
/* ATA registers */
#define ATA_REG_DATA 0x00
#define ATA_REG_ERROR 0x01
#define ATA_REG_FEATURES 0x01
#define ATA_REG_SECCOUNT0 0x02
#define ATA_REG_LBA0 0x03
#define ATA_REG_LBA1 0x04
#define ATA_REG_LBA2 0x05
#define ATA_REG_HDDEVSEL 0x06
#define ATA_REG_COMMAND 0x07
#define ATA_REG_STATUS 0x07
/* ATA commands */
#define ATA_CMD_READ_PIO 0x20
#define ATA_CMD_WRITE_PIO 0x30
#define ATA_CMD_IDENTIFY 0xEC
/* Status flags */
#define ATA_SR_BSY 0x80
#define ATA_SR_DRDY 0x40
#define ATA_SR_DRQ 0x08
#define ATA_SR_ERR 0x01
/* Drive select */
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x10
/* Public API */
bool ata_init(void);
bool ata_read_sector(uint32_t lba, uint8_t* buffer);
bool ata_write_sector(uint32_t lba, const uint8_t* buffer);
#endif

View File

@@ -1,107 +0,0 @@
#include "fat16.h"
#include "ata.h" // Use ata_read_sector and ata_write_sector
#include "print.h" // For debugging
#include <string.h> // For string manipulation
// Global variables
static fat16_boot_sector_t boot_sector;
static uint32_t root_dir_sector = FAT16_ROOT_DIR_SECTOR;
// Read a sector from the disk using ATA
bool read_sector(uint32_t lba, uint8_t* buffer) {
return ata_read_sector(lba, buffer);
}
// Write a sector to the disk using ATA
bool write_sector(uint32_t lba, const uint8_t* buffer) {
return ata_write_sector(lba, buffer);
}
// Parse the boot sector to retrieve basic file system info
bool parse_fat16_boot_sector(void) {
uint8_t sector_buffer[FAT16_SECTOR_SIZE];
// Read the boot sector
if (!read_sector(FAT16_BOOT_SECTOR, sector_buffer)) {
print_string("[FAT16] Failed to read boot sector\n");
return false;
}
// Cast to boot sector structure
memcpy(&boot_sector, sector_buffer, sizeof(fat16_boot_sector_t));
// Check for FAT16 signature
if (boot_sector.oem_name[0] != 'F' || boot_sector.oem_name[1] != 'A' || boot_sector.oem_name[2] != 'T') {
print_string("[FAT16] Invalid FAT16 boot sector signature\n");
return false;
}
print_string("[FAT16] FAT16 boot sector parsed successfully\n");
return true;
}
// Parse the root directory
bool parse_fat16_root_dir(void) {
uint8_t sector_buffer[FAT16_SECTOR_SIZE];
for (int i = 0; i < (boot_sector.max_root_entries / (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t))); i++) {
// Read root directory sector
if (!read_sector(root_dir_sector + i, sector_buffer)) {
print_string("[FAT16] Failed to read root directory sector\n");
return false;
}
// Parse the root directory entries
for (int j = 0; j < (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t)); j++) {
fat16_dir_entry_t* entry = (fat16_dir_entry_t*)&sector_buffer[j * sizeof(fat16_dir_entry_t)];
if (entry->name[0] == 0x00) {
// End of directory entries
return true;
}
if (entry->name[0] != 0xE5) {
// Print file name (8.3 format)
char filename[12];
strncpy(filename, (char*)entry->name, 8);
filename[8] = '.';
strncpy(&filename[9], (char*)entry->ext, 3);
filename[11] = '\0';
print_string(filename);
print_string("\n");
}
}
}
return true;
}
// Read a specific directory entry from the FAT16 root directory
bool read_fat16_entry(uint16_t entry_index, fat16_dir_entry_t* entry) {
uint8_t sector_buffer[FAT16_SECTOR_SIZE];
uint32_t sector_num = FAT16_ROOT_DIR_SECTOR + (entry_index / (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t)));
uint16_t entry_offset = entry_index % (FAT16_SECTOR_SIZE / sizeof(fat16_dir_entry_t));
// Read the sector
if (!read_sector(sector_num, sector_buffer)) {
print_string("[FAT16] Failed to read root directory sector\n");
return false;
}
// Get the entry
memcpy(entry, &sector_buffer[entry_offset * sizeof(fat16_dir_entry_t)], sizeof(fat16_dir_entry_t));
return true;
}
// Mount the FAT16 filesystem
bool mount_fat16(void) {
// Parse the boot sector
if (!parse_fat16_boot_sector()) {
return false;
}
// Parse the root directory
if (!parse_fat16_root_dir()) {
return false;
}
print_string("[FAT16] Filesystem mounted successfully\n");
return true;
}

View File

@@ -1,60 +0,0 @@
#ifndef FAT16_H
#define FAT16_H
#include <stdint.h>
#include <stdbool.h>
/* FAT16 Constants */
#define FAT16_SECTOR_SIZE 512
#define FAT16_CLUSTER_SIZE 1
#define FAT16_MAX_FILENAME_LEN 11 // 8.3 format
#define FAT16_ROOT_DIR_ENTRIES 224 // Fat16 root directory entries (typically 512 bytes per entry)
#define FAT16_BOOT_SECTOR 0
#define FAT16_FAT1_SECTOR 1
#define FAT16_FAT2_SECTOR 2
#define FAT16_ROOT_DIR_SECTOR 19 // First sector of root directory
/* Boot Sector */
typedef struct {
uint8_t jmp[3]; // Jump instruction to code
uint8_t oem_name[8]; // OEM Name
uint16_t bytes_per_sector; // Bytes per sector (512)
uint8_t sectors_per_cluster; // Sectors per cluster
uint16_t reserved_sectors; // Reserved sectors
uint8_t num_fats; // Number of FAT tables
uint16_t max_root_entries; // Max number of root directory entries
uint16_t total_sectors_16; // Total sectors in FAT16
uint8_t media_type; // Media type (0xF8 = fixed drive)
uint16_t sectors_per_fat; // Sectors per FAT table
uint16_t sectors_per_track; // Sectors per track (for CHS addressing)
uint16_t num_heads; // Number of heads (for CHS addressing)
uint32_t hidden_sectors; // Hidden sectors (before the partition)
uint32_t total_sectors_32; // Total sectors in FAT16 (extended)
} __attribute__((packed)) fat16_boot_sector_t;
/* FAT16 Directory Entry */
typedef struct {
uint8_t name[8]; // File name (8 chars)
uint8_t ext[3]; // File extension (3 chars)
uint8_t attributes; // File attributes (e.g., directory, read-only)
uint8_t reserved; // Reserved
uint8_t creation_time[2]; // Creation time
uint8_t creation_date[2]; // Creation date
uint8_t last_access_date[2]; // Last access date
uint8_t first_cluster_high[2]; // High part of first cluster number
uint8_t last_mod_time[2]; // Last modification time
uint8_t last_mod_date[2]; // Last modification date
uint8_t first_cluster_low[2]; // Low part of first cluster number
uint32_t file_size; // File size in bytes
} __attribute__((packed)) fat16_dir_entry_t;
/* Function Prototypes */
bool mount_fat16(void);
bool read_sector(uint32_t lba, uint8_t* buffer);
bool write_sector(uint32_t lba, const uint8_t* buffer);
bool parse_fat16_boot_sector(void);
bool parse_fat16_root_dir(void);
bool read_fat16_entry(uint16_t entry_index, fat16_dir_entry_t* entry);
#endif // FAT16_H