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 187 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,112 +0,0 @@
#include <stddef.h>
#include "vesa.h"
#include "io.h"
#include "print.h"
// VESA mode and controller information
#define VESA_BIOS_INT 0x10
#define VESA_BIOS_FUNC 0x4F
// Function to call BIOS with specific VESA function
static bool vesa_bios_call(uint16_t function, uint16_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
// Set up registers for VESA function call
__asm__ __volatile__(
"movw %1, %%ax\n" // Move function number into AX
"int $0x10\n" // Call BIOS interrupt 0x10 (VESA)
"movw %%ax, %0\n" // Move return value in AX to the return variable
: "=m"(*eax) // Output operand (eax)
: "m"(function) // Input operand (function number)
: "%eax", "%ebx", "%ecx", "%edx", "memory"
);
// Check for success (return values vary depending on the function)
return *eax == 0x004F;
}
// Set the VESA video mode
bool vesa_set_mode(uint16_t mode) {
uint16_t eax = VBE_FUNCTION_SET_MODE;
uint32_t ebx = mode;
uint32_t ecx = 0;
uint32_t edx = 0;
if (vesa_bios_call(VBE_FUNCTION_SET_MODE, &eax, &ebx, &ecx, &edx)) {
return true;
}
return false;
}
// Get the VESA mode information
bool vesa_get_mode_info(uint16_t mode, vbe_mode_info_t* info) {
uint16_t ax_ret;
// Convert the 32-bit pointer to a Segment:Offset pair
// IMPORTANT: 'info' MUST be located in the first 1MB of RAM
uint32_t ptr = (uint32_t)info;
uint16_t segment = (uint16_t)((ptr >> 4) & 0xFFFF);
uint16_t offset = (uint16_t)(ptr & 0x000F);
__asm__ __volatile__(
"push %%es\n\t" // Save Protected Mode ES
"movw %1, %%es\n\t" // Load the segment into ES
"int $0x10\n\t" // BIOS Interrupt
"pop %%es\n\t" // Restore Protected Mode ES
: "=a"(ax_ret) // Result in AX
: "r"(segment), // %1
"D"(offset), // %2 (DI)
"a"((uint16_t)VBE_FUNCTION_GET_MODE_INFO), // AX (0x4F01)
"c"(mode) // CX (The Mode Number)
: "memory", "cc" // Removed %es from clobbers
);
return ax_ret == 0x004F;
}
bool vesa_get_controller_info(vbe_controller_info_t* info) {
uint16_t ax_ret;
// We must use Segment:Offset for BIOS
uint32_t ptr = (uint32_t)info;
uint16_t segment = (uint16_t)((ptr >> 4) & 0xF000); // Base segment
uint16_t offset = (uint16_t)(ptr & 0xFFFF); // Offset
// Copy "VBE2" into signature to tell BIOS we want VBE 2.0+ info
info->Signature[0] = 'V';
info->Signature[1] = 'B';
info->Signature[2] = 'E';
info->Signature[3] = '2';
// To fix the error: Do not use %es in clobber.
// Use a temporary register or a push/pop sequence if we MUST touch ES.
__asm__ __volatile__(
"push %%es\n\t"
"movw %1, %%es\n\t"
"int $0x10\n\t"
"pop %%es\n\t"
: "=a"(ax_ret)
: "r"(segment), "D"(offset), "a"(0x4F00)
: "memory", "cc"
);
return ax_ret == 0x004F;
}
// Return pointer to the VESA framebuffer
void* vesa_get_framebuffer(void) {
vbe_mode_info_t mode_info;
if (vesa_get_mode_info(0x101, &mode_info)) {
return (void*)mode_info.PhysBasePtr;
}
return NULL;
}
// Clear the screen with a color
void vesa_clear_screen(uint32_t color) {
uint32_t* framebuffer = (uint32_t*)vesa_get_framebuffer();
if (framebuffer) {
for (int y = 0; y < 480; y++) { // For 640x480 mode
for (int x = 0; x < 640; x++) {
framebuffer[y * 640 + x] = color;
}
}
}
}

View File

@@ -1,75 +0,0 @@
#ifndef VESA_H
#define VESA_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
// VESA BIOS Extension 2.0 Function Calls
#define VBE_FUNCTION_SET_MODE 0x4F02
#define VBE_FUNCTION_GET_MODE_INFO 0x4F01
#define VBE_FUNCTION_GET_CONTROLLER_INFO 0x4F00
#define VBE_FUNCTION_SET_DISPLAY_START 0x4F05
// VESA Mode Information Structure (VBE 2.0)
typedef struct {
uint16_t ModeAttributes; // Mode attributes
uint8_t WinAAttributes; // Window A attributes
uint8_t WinBAttributes; // Window B attributes
uint16_t WinGranularity; // Window granularity
uint16_t WinSize; // Window size
uint16_t WinASegment; // Window A segment address
uint16_t WinBSegment; // Window B segment address
uint32_t WinFuncPtr; // Function pointer for window
uint16_t BytesPerScanLine; // Bytes per scanline
uint16_t XResolution; // Horizontal resolution in pixels
uint16_t YResolution; // Vertical resolution in pixels
uint8_t XCharSize; // Character cell width
uint8_t YCharSize; // Character cell height
uint8_t NumberOfPlanes; // Number of memory planes
uint8_t BitsPerPixel; // Bits per pixel
uint8_t NumberOfBanks; // Number of banks
uint8_t MemoryModel; // Memory model type
uint8_t BankSize; // Bank size in kB
uint8_t NumberOfImagePages; // Number of image pages
uint8_t Reserved0; // Reserved
uint8_t RedMaskSize; // Red mask size
uint8_t RedFieldPosition; // Red field position
uint8_t GreenMaskSize; // Green mask size
uint8_t GreenFieldPosition; // Green field position
uint8_t BlueMaskSize; // Blue mask size
uint8_t BlueFieldPosition; // Blue field position
uint8_t RsvdMaskSize; // Reserved mask size
uint8_t RsvdFieldPosition; // Reserved field position
uint8_t DirectColorModeInfo; // Direct color mode info
uint32_t PhysBasePtr; // Physical base address of the linear framebuffer
uint32_t OffScreenMemOff; // Offset to off-screen memory
uint16_t OffScreenMemSize; // Size of off-screen memory
uint8_t Reserved1[206]; // Reserved
} __attribute__((packed)) vbe_mode_info_t;
// VESA Controller Information
typedef struct {
char Signature[4]; // Should be "VESA" (or "VBE2" for request)
uint16_t Version; // VBE version; high byte is major, low is minor
uint32_t OEMStringPtr; // Segment:Offset pointer to OEM string
uint32_t Capabilities; // Capabilities of graphics controller
uint32_t VideoModePtr; // Segment:Offset pointer to supported modes list
uint16_t TotalMemory; // Number of 64KB memory blocks
uint16_t OEMSoftwareRev; // VBE implementation Software revision
uint32_t OEMVendorNamePtr; // Segment:Offset pointer to Vendor Name string
uint32_t OEMProductNamePtr; // Segment:Offset pointer to Product Name string
uint32_t OEMProductRevPtr; // Segment:Offset pointer to Product Revision string
uint8_t Reserved[222]; // Reserved for VBE implementation scratch area
uint8_t OEMData[256]; // Data area for OEM strings
} __attribute__((packed)) vbe_controller_info_t;
// Function Prototypes
bool vesa_set_mode(uint16_t mode);
bool vesa_get_mode_info(uint16_t mode, vbe_mode_info_t* info);
bool vesa_get_controller_info(vbe_controller_info_t* info);
void* vesa_get_framebuffer(void);
void vesa_clear_screen(uint32_t color);
#endif // VESA_H