Espresso 0.0.1c

This commit is contained in:
2025-07-01 20:39:38 -05:00
parent f9f3faca4f
commit 8648637b51
23 changed files with 384 additions and 419 deletions

View File

@ -11,7 +11,8 @@ NASMFLAGS := -f elf32
WNOFLAGS := -Wno-discarded-qualifiers WNOFLAGS := -Wno-discarded-qualifiers
CFLAGS := -std=gnu99 -ffreestanding -O2 -Wall -Wextra -msse $(WNOFLAGS) CFLAGS := -std=gnu99 -ffreestanding -O2 -Wall -Wextra -msse $(WNOFLAGS)
LDFLAGS := -T linker.ld -ffreestanding -O2 -nostdlib LDFLAGS := -T linker.ld -ffreestanding -O2 -nostdlib
QEMUFLAGS := -boot d -cdrom $(ISO) -drive file=espresso.img,format=raw,if=ide,readonly=off,rerror=report,werror=report -cpu qemu32,sse4.1 -singlestep QEMUFLAGS := -boot d -cdrom $(ISO) -drive file=espresso.img,format=raw,if=ide,readonly=off,rerror=report,werror=report -cpu qemu32,sse4.1
QEMUFLGS_EXT := -net none -netdev user,id=n0 -device rtl8139,netdev=n0 #-singlestep
SRC_DIRS := kernel drivers lib SRC_DIRS := kernel drivers lib
INCLUDE_DIRS := include INCLUDE_DIRS := include
INCLUDES := $(addprefix -I, $(INCLUDE_DIRS)) INCLUDES := $(addprefix -I, $(INCLUDE_DIRS))
@ -68,7 +69,8 @@ run: iso
$(QEMU_MKE_IMG) $(QEMU_MKE_IMG)
echo "\n" echo "\n"
$(MKFS_VFAT) $(MKFS_FLAGS) espresso.img $(MKFS_VFAT) $(MKFS_FLAGS) espresso.img
qemu-system-i386 $(QEMUFLAGS) qemu-system-i386 $(QEMUFLAGS) $(QEMUFLGS_EXT)
# === Clean all build artifacts === # === Clean all build artifacts ===
clean: clean:

View File

@ -1 +1,6 @@
#include <drivers/ahci.h> #include <drivers/ahci.h>

View File

@ -1,248 +0,0 @@
#include <drivers/ide.h>
#include <string.h>
#include <stdio.h>
#include <fs/fat16.h>
static fat16_t fat;
#pragma pack(push, 1)
typedef struct {
uint8_t jmp[3];
char oem[8];
uint16_t bytes_per_sector;
uint8_t sectors_per_cluster;
uint16_t reserved_sectors;
uint8_t fat_count;
uint16_t root_entries;
uint16_t total_sectors_short;
uint8_t media_desc;
uint16_t fat_size_sectors;
uint16_t sectors_per_track;
uint16_t heads;
uint32_t hidden_sectors;
uint32_t total_sectors_long;
// Extended Boot Record...
} fat16_bpb_t;
typedef struct {
char name[8];
char ext[3];
uint8_t attr;
uint8_t reserved;
uint8_t create_time_tenth;
uint16_t create_time;
uint16_t create_date;
uint16_t access_date;
uint16_t first_cluster_hi;
uint16_t write_time;
uint16_t write_date;
uint16_t first_cluster_lo;
uint32_t size;
} fat16_direntry_raw_t;
#pragma pack(pop)
static uint8_t sector_buffer[512];
uint32_t cluster_to_lba(uint16_t cluster)
{
return fat.data_start + ((cluster - 2) * fat.sectors_per_cluster);
}
int32_t fat16_init(uint8_t drive)
{
if (ide_read48(drive, 0, 1, sector_buffer) < 0)
{
return -1;
}
fat16_bpb_t* bpb = (fat16_bpb_t*)sector_buffer;
fat.drive = drive;
fat.bytes_per_sector = bpb->bytes_per_sector;
fat.sectors_per_cluster = bpb->sectors_per_cluster;
fat.root_entry_count = bpb->root_entries;
fat.fat_start = bpb->reserved_sectors;
fat.root_dir_start = fat.fat_start + bpb->fat_count * bpb->fat_size_sectors;
fat.data_start = fat.root_dir_start + ((bpb->root_entries * 32 + fat.bytes_per_sector - 1) / fat.bytes_per_sector);
fat.current_dir_cluster = 0;
return 0;
}
uint16_t fat16_get_fat_entry(uint16_t cluster)
{
uint32_t fat_offset = cluster * 2;
uint32_t fat_sector = fat.fat_start + (fat_offset / fat.bytes_per_sector);
uint32_t ent_offset = fat_offset % fat.bytes_per_sector;
if (ide_read48(fat.drive, fat_sector, 1, sector_buffer) < 0)
{
return 0xFFFF;
}
return *(uint16_t*)&sector_buffer[ent_offset];
}
uint16_t fat16_alloc_cluster(void)
{
for (uint16_t cluster = 2; cluster < 0xFFF0; ++cluster) {
uint16_t entry = fat16_get_fat_entry(cluster);
if (entry == 0x0000) {
// Mark as end of chain
uint32_t fat_offset = cluster * 2;
uint32_t fat_sector = fat.fat_start + (fat_offset / fat.bytes_per_sector);
uint32_t ent_offset = fat_offset % fat.bytes_per_sector;
if (ide_read48(fat.drive, fat_sector, 1, sector_buffer) < 0) return 0;
*(uint16_t*)&sector_buffer[ent_offset] = 0xFFFF;
if (ide_write48(fat.drive, fat_sector, 1, sector_buffer) < 0) return 0;
return cluster;
}
}
return 0;
}
int32_t fat16_list_dir(fat16_dir_entry_t* entries, size_t max_entries)
{
size_t count = 0;
if (fat.current_dir_cluster == 0)
{
uint16_t root_sectors = ((fat.root_entry_count * 32) + (fat.bytes_per_sector - 1)) / fat.bytes_per_sector;
for (uint32_t i = 0; i < root_sectors && count < max_entries; ++i)
{
if (ide_read48(fat.drive, fat.root_dir_start + i, 1, sector_buffer) < 0)
{
return -1;
}
fat16_direntry_raw_t* de = (fat16_direntry_raw_t*)sector_buffer;
for (int32_t j = 0; j < 512 / 32 && count < max_entries; ++j, ++de)
{
if (de->name[0] == 0x00 || de->name[0] == 0xE5)
{
continue;
}
memcpy(entries[count].name, de->name, 8);
entries[count].name[8] = '\0';
entries[count].attr = de->attr;
entries[count].cluster = de->first_cluster_lo;
entries[count].size = de->size;
count++;
}
}
}
/* TODO: Add support for listing subdirectories if current_dir_cluster != 0 */
return count;
}
int32_t fat16_read_file(const char* filename, void* buffer, size_t max_size) {
fat16_dir_entry_t entries[64];
int32_t n = fat16_list_dir(entries, 64);
for (int32_t i = 0; i < n; ++i) {
if (!(entries[i].attr & FAT16_ATTR_DIRECTORY) &&
strncmp(entries[i].name, filename, FAT16_MAX_FILENAME) == 0) {
uint16_t cluster = entries[i].cluster;
uint8_t* out = (uint8_t*)buffer;
size_t remaining = entries[i].size < max_size ? entries[i].size : max_size;
while (cluster >= 0x0002 && cluster < 0xFFF8 && remaining > 0) {
uint32_t lba = cluster_to_lba(cluster);
size_t to_read = fat.bytes_per_sector * fat.sectors_per_cluster;
if (ide_read48(fat.drive, lba, fat.sectors_per_cluster, sector_buffer) < 0)
return -1;
size_t copy_size = (remaining < to_read) ? remaining : to_read;
memcpy(out, sector_buffer, copy_size);
out += copy_size;
remaining -= copy_size;
cluster = fat16_get_fat_entry(cluster);
}
return (int32_t)(out - (uint8_t*)buffer);
}
}
return -1;
}
int32_t fat16_write_file(const char* filename, const void* data, size_t size) {
fat16_dir_entry_t entries[64];
int32_t n = fat16_list_dir(entries, 64);
for (int32_t i = 0; i < n; ++i) {
if (strncmp(entries[i].name, filename, FAT16_MAX_FILENAME) == 0) {
uint16_t cluster = entries[i].cluster;
const uint8_t* src = (const uint8_t*)data;
size_t remaining = size;
while (remaining > 0) {
uint32_t lba = cluster_to_lba(cluster);
size_t cluster_bytes = fat.sectors_per_cluster * fat.bytes_per_sector;
size_t to_write = remaining < cluster_bytes ? remaining : cluster_bytes;
memset(sector_buffer, 0, cluster_bytes); // Clear old data
memcpy(sector_buffer, src, to_write);
if (ide_write48(fat.drive, lba, fat.sectors_per_cluster, sector_buffer) < 0)
return -1;
src += to_write;
remaining -= to_write;
// Last chunk?
if (remaining == 0)
break;
// Check next cluster
uint16_t next = fat16_get_fat_entry(cluster);
if (next >= 0xFFF8 || next == 0x0000) {
// Need to allocate a new cluster
uint16_t new_cluster = fat16_alloc_cluster();
if (new_cluster == 0) return -1;
// Update FAT to point to new cluster
uint32_t fat_offset = cluster * 2;
uint32_t fat_sector = fat.fat_start + (fat_offset / fat.bytes_per_sector);
uint32_t ent_offset = fat_offset % fat.bytes_per_sector;
if (ide_read48(fat.drive, fat_sector, 1, sector_buffer) < 0) return -1;
*(uint16_t*)&sector_buffer[ent_offset] = new_cluster;
if (ide_write48(fat.drive, fat_sector, 1, sector_buffer) < 0) return -1;
next = new_cluster;
}
cluster = next;
}
return (int32_t)size;
}
}
return -1;
}
int32_t fat16_change_dir(const char* dirname)
{
fat16_dir_entry_t entries[64];
int32_t n = fat16_list_dir(entries, 64);
for (int32_t i = 0; i < n; ++i)
{
if ((entries[i].attr & FAT16_ATTR_DIRECTORY) && strncmp(entries[i].name, dirname, FAT16_MAX_FILENAME) == 0)
{
fat.current_dir_cluster = entries[i].cluster;
return 0;
}
}
return -1;
}

94
drivers/fs/sfs.c Normal file
View File

@ -0,0 +1,94 @@
#include <drivers/ide.h>
#include <stdio.h>
#include <stdlib.h>
#include <fs/sfs.h>
#define SFS_BEGINNING_LBA 8
#pragma pack(push, 1)
typedef struct sfs_file_header {
uint16_t magic; /* 0xBEEF */
/*
32 chars for the filename itself,
4 chars for the file's extension,
and 1 char for the null zero.
*/
char filename[37];
uint64_t data_beginning; /* Actually a 48 bit LBA mind you */
uint32_t num_sectors; /* Number of sectors after data_beginning that are this file's data */
uint8_t padding[13]; /* Padding to 64 bytes total */
} sfs_file_header_t;
#pragma pack(pop)
static sfs_file_header_t* base;
int32_t sfs_init(bool format)
{
uint8_t buffer[512] = { 0 };
int32_t kl = read_sector(SFS_BEGINNING_LBA, buffer);
if (kl != 0)
{
return -1;
}
volatile sfs_file_header_t null_file;
memcpy(&null_file, buffer, sizeof(sfs_file_header_t));
if ((&null_file)->magic != 0xBEEF)
{
if (!format)
{
return -2;
}
//sfs_format();
return -2;
}
memcpy(base, &null_file, sizeof(sfs_file_header_t));
return 0;
}
bool sfs_get_formatted_name(const char* raw_name, char output[37])
{
size_t len = strlen(raw_name);
if (len > 36 || strchr(raw_name, '/') || strchr(raw_name, '*') || strchr(raw_name, '\\')) {
return false;
}
memset(output, ' ', 36);
output[36] = '\0';
memcpy(output, raw_name, len);
return true;
}
/*
Note: if a negative value is passed for num, then read the whole file
*/
int32_t sfs_read_file(char* _name, void* buffer, uint32_t num)
{
char name[37] = { '\0' };
if (sfs_get_formatted_name(_name, name))
{
return -128;
}
printf("%s", name);
return 0;
}

View File

@ -1,30 +1,32 @@
/*#include <fs/fat16.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <fs/vfs.h>*/ #include <fs/vfs.h>
typedef struct vfs_file_header {
char* filename; /* The filename, not the path. */
int32_t fd;
uint8_t type_info; /* Bits 0 - 3 -> File type, Bits 4 - 7 FS type */
uint16_t* fs_header;
struct vfs_file_header* next; /* Linked list */
} vfs_file_header_t;
vfs_file_header_t* root;
/* /*
Note: the special FILE value -128 means the current directory. This is being written as a test.
-32 means stdin This has no affect on aaand my CPU is at 87 degrees Celsius and /usr/bin/gnome-shell is at 115% CPU utilization.
-33 means stdout (which can be read) Just by writing that.
*/ wow.
and now my CPU fan is going nuts.
/*bool vfs_initialized = false;
ramfs_file_header_t* vfs_current_dir = NULL; --update: now it works. I had to go back to nouveau instead of the proprietary nVidia drivers..
void vfs_init(void)
{
if (!vfs_initialized)
{
ramfs_init();
ramfs_make_root();
vfs_initialized = true;
vfs_current_dir = ramfs_get_root();
}
}
*/ */

View File

@ -16,11 +16,21 @@ extern void gdt_flush(uint32_t);
void gdt_install(bool prnt_gdt) void gdt_install(bool prnt_gdt)
{ {
create_descriptor(0, 0, 0, 0, prnt_gdt); // Null if (prnt_gdt)
create_descriptor(1, 0, 0x000FFFFF, GDT_CODE_PL0, prnt_gdt); // Kernel code {
create_descriptor(2, 0, 0x000FFFFF, GDT_DATA_PL0, prnt_gdt); // Kernel data printf("<===== GDT =====>\n");
create_descriptor(3, 0, 0x000FFFFF, GDT_CODE_PL3, prnt_gdt); // User code }
create_descriptor(4, 0, 0x000FFFFF, GDT_DATA_PL3, prnt_gdt); // User data
create_descriptor(0, 0, 0, 0, prnt_gdt); /* Null */
create_descriptor(1, 0, 0x000FFFFF, GDT_CODE_PL0, prnt_gdt); /* Kernel code */
create_descriptor(2, 0, 0x000FFFFF, GDT_DATA_PL0, prnt_gdt); /* Kernel data */
create_descriptor(3, 0, 0x000FFFFF, GDT_CODE_PL3, prnt_gdt); /* User code */
create_descriptor(4, 0, 0x000FFFFF, GDT_DATA_PL3, prnt_gdt); /* User data */
if (prnt_gdt)
{
printf("<===== GDT =====>\n");
}
gp.limit = sizeof(gdt) - 1; gp.limit = sizeof(gdt) - 1;
gp.base = (uint32_t)&gdt; gp.base = (uint32_t)&gdt;
@ -32,15 +42,15 @@ void create_descriptor(int index, uint32_t base, uint32_t limit, uint16_t flag,
{ {
uint64_t descriptor; uint64_t descriptor;
descriptor = limit & 0x000F0000; // limit bits 19:16 descriptor = limit & 0x000F0000; /* limit bits 19:16 */
descriptor |= (flag << 8) & 0x00F0FF00; // flags and access descriptor |= (flag << 8) & 0x00F0FF00; /* flags and access */
descriptor |= (base >> 16) & 0x000000FF; // base bits 23:16 descriptor |= (base >> 16) & 0x000000FF; /* base bits 23:16 */
descriptor |= base & 0xFF000000; // base bits 31:24 descriptor |= base & 0xFF000000; /* base bits 31:24 */
descriptor <<= 32; descriptor <<= 32;
descriptor |= ((uint64_t)base << 16); // base bits 15:0 descriptor |= ((uint64_t)base << 16); /* base bits 15:0 */
descriptor |= (limit & 0x0000FFFF); // limit bits 15:0 descriptor |= (limit & 0x0000FFFF); /* limit bits 15:0 */
gdt[index] = descriptor; gdt[index] = descriptor;

View File

@ -199,3 +199,13 @@ int32_t ide_write48(uint8_t drive, uint64_t lba, uint8_t sector_count, const voi
return 0; return 0;
} }
int32_t read_sector(uint64_t lba, void* buffer)
{
return ide_read48(0, lba, 1, buffer);
}
int32_t write_sector(uint64_t lba, const void* buffer)
{
return ide_write48(0, lba, 1, buffer);
}

View File

@ -81,7 +81,8 @@ void exception_dispatcher(uint32_t int_no, uint32_t err_code)
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags)
{
idt_entry_t* descriptor = &idt[vector]; idt_entry_t* descriptor = &idt[vector];
descriptor->isr_low = (uint32_t)isr & 0xFFFF; descriptor->isr_low = (uint32_t)isr & 0xFFFF;

View File

@ -4,19 +4,26 @@
#include <drivers/irq.h> #include <drivers/irq.h>
irq_func_t func_list[64];
void irq_init(void)
{
set_irq_handler(0, (irq_func_t*)pit_handler);
set_irq_handler(1, (irq_func_t*)keyboard_handler);
}
void irq_handler(uint8_t irq_number) void irq_handler(uint8_t irq_number)
{ {
switch (irq_number) if (irq_number < 64 && func_list[irq_number])
{ {
case 0: func_list[irq_number]();
pit_handler(); }
break; }
case 1:
keyboard_handler(); void set_irq_handler(uint32_t num, irq_func_t* handler)
break; {
default: if (num < 64)
printf("Unhandled IRQ %u\n", irq_number); {
break; func_list[num] = (irq_func_t)handler;
} }
} }

View File

@ -1,58 +1,96 @@
#include <stdint.h> #include <drivers/ahci.h>
#include <stddef.h>
#include <drivers/pci.h>
#include <port_io.h> #include <port_io.h>
#include <stdio.h> #include <stdio.h>
#include <drivers/pci.h>
#define PCI_CONFIG_ADDRESS 0xCF8 #define PCI_CONFIG_ADDRESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC #define PCI_CONFIG_DATA 0xCFC
/*
Register Offset Bits 31-24 Bits 23-16 Bits 15-8 Bits 7-0
0x0 0x0 Device ID Vendor ID
0x1 0x4 Status Command
0x2 0x8 Class code Subclass Prog IF Revision ID
0x3 0xC BIST Header type Latency Timer Cache Line Size
*/
uint32_t pci_config_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset) uint32_t pci_config_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
{ {
uint32_t address = 0; uint32_t address = 0;
address |= (bus << 16); // Bus number (bits 23-16) address |= (bus << 16); /* Bus number (bits 23-16) */
address |= (device << 11); // Device number (bits 15-11) address |= (device << 11); /* Device number (bits 15-11) */
address |= (function << 8); // Function number (bits 10-8) address |= (function << 8); /* Function number (bits 10-8) */
address |= (offset & 0xFC); // Register offset (bits 7-0) address |= (offset & 0xFC); /* Register offset (bits 7-0) */
address |= (1 << 31); // Enable configuration access address |= (1 << 31); /* Enable configuration access */
outl(PCI_CONFIG_ADDRESS, address); // Write address to PCI config space outl(PCI_CONFIG_ADDRESS, address); /* Write address to PCI config space */
return inl(PCI_CONFIG_DATA); // Read data from PCI config space return inl(PCI_CONFIG_DATA); /* Read data from PCI config space */
} }
void pci_config_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value) void pci_config_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value)
{ {
uint32_t address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC); uint32_t address = 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & 0xFC);
outl(PCI_CONFIG_ADDRESS, address); // Send the address to PCI config space outl(PCI_CONFIG_ADDRESS, address); /* Send the address to PCI config space */
outl(PCI_CONFIG_DATA, value); // Write data to PCI config space outl(PCI_CONFIG_DATA, value); /* Write data to PCI config space */
} }
void pci_enumerate() void pci_config_read_block(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, void* buffer, size_t size)
{ {
for (uint16_t bus = 0; bus < 256; bus++) // Maximum 256 buses uint8_t* buf = (uint8_t*)buffer;
for (size_t i = 0; i < size; i += 4)
{ {
for (uint8_t device = 0; device < 32; device++) // Maximum 32 devices per bus uint32_t value = pci_config_read(bus, device, function, offset + i);
size_t remaining = size - i;
if (remaining >= 4)
{ {
for (uint8_t function = 0; function < 8; function++) // Maximum 8 functions per device *(uint32_t*)(buf + i) = value;
{ }
uint32_t vendor_id = pci_config_read(bus, device, function, 0x00); else
if (vendor_id == 0xFFFFFFFF) continue; // No device present {
for (size_t j = 0; j < remaining; ++j)
uint32_t device_id = pci_config_read(bus, device, function, 0x02); {
uint32_t class_code = pci_config_read(bus, device, function, 0x08); buf[i + j] = (value >> (8 * j)) & 0xFF;
printf("Found PCI device: Vendor ID: 0x%X Device ID: 0x%X Class: 0x%X\n", vendor_id, device_id, class_code); }
}
printf("0x%X", class_code); }
printf(" --- "); }
printf("0x%X\n", (class_code >> 8));
void pci_enumerate(void)
if ((class_code >> 8) == 0x0C) { {
printf("Found USB controller (Class: 0x%02X)\n", class_code); for (uint16_t bus = 0; bus < 256; bus++) /* Maximum 256 buses */
// Now, you can initialize and configure the USB controller. {
for (uint8_t device = 0; device < 32; device++) /* Maximum 32 devices per bus */
{
for (uint8_t function = 0; function < 8; function++) /* Maximum 8 functions per device */
{
struct pci_header pre_header;
pci_config_read_block(bus, device, function, 0x00, &pre_header, sizeof(pre_header));
if (pre_header.vendor_id == 0xFFFF)
{
continue; /* No device present */
}
if (pre_header.class_code == 0xB)
{
printf("Processor found on PCI bus, what?!?!\n");
continue;
}
if (pre_header.header_type == 0x00)
{
struct pci_header_type_0 hdr;
pci_config_read_block(bus, device, function, 0x00, &hdr, sizeof(hdr));
if (hdr.class_code == 0x1 && hdr.subclass == 0x6 && hdr.prog_if == 0x1)
{
/*configure_ahci_controller(hdr);*/
}
} }
} }
} }
} }

View File

@ -1,6 +1,6 @@
#ifndef _AHCI_H #ifndef _AHCI_H
#define _AHCI_H #define _AHCI_H
#include <types.h>
#endif #endif

View File

@ -0,0 +1,6 @@
#ifndef _AHCI_TYPES_H
#define _AHCI_TYPES_H
#endif

View File

@ -33,8 +33,12 @@
#define ATA_SR_ERR 0x01 #define ATA_SR_ERR 0x01
void ide_initialize(void); void ide_initialize(void);
int32_t ide_identify(uint8_t drive, uint16_t* buffer); int32_t ide_identify(uint8_t drive, uint16_t* buffer);
int32_t ide_read48(uint8_t drive, uint64_t lba, uint8_t sector_count, void* buffer); int32_t ide_read48(uint8_t drive, uint64_t lba, uint8_t sector_count, void* buffer);
int32_t ide_write48(uint8_t drive, uint64_t lba, uint8_t sector_count, const void* buffer); int32_t ide_write48(uint8_t drive, uint64_t lba, uint8_t sector_count, const void* buffer);
int32_t read_sector(uint64_t lba, void* buffer);
int32_t write_sector(uint64_t lba, const void* buffer);
#endif #endif

View File

@ -3,6 +3,10 @@
#include <types.h> #include <types.h>
typedef void (*irq_func_t)(void);
void irq_init(void);
void irq_handler(uint8_t irq_number); void irq_handler(uint8_t irq_number);
void set_irq_handler(uint32_t num, irq_func_t* handler);
#endif #endif

View File

@ -1,7 +1,66 @@
#ifndef _PCI_H #ifndef _PCI_H
#define _PCI_H #define _PCI_H
#include <stdint.h> #include <types.h>
struct pci_header {
uint16_t vendor_id;
uint16_t device_id;
uint16_t command;
uint16_t status;
uint8_t revision_id;
uint8_t prog_if;
uint8_t subclass;
uint8_t class_code;
uint8_t cache_line_size;
uint8_t latency_timer;
uint8_t header_type;
uint8_t bist;
} __attribute__((packed));
struct pci_header_type_0 {
uint16_t vendor_id;
uint16_t device_id;
uint16_t command;
uint16_t status;
uint8_t revision_id;
uint8_t prog_if;
uint8_t subclass;
uint8_t class_code;
uint8_t cache_line_size;
uint8_t latency_timer;
uint8_t header_type;
uint8_t bist;
uint32_t bar0;
uint32_t bar1;
uint32_t bar2;
uint32_t bar3;
uint32_t bar4;
uint32_t bar5;
uint32_t cardbus_cis_ptr;
uint16_t subsystem_vendor_id;
uint16_t subsystem_id;
uint32_t expansion_rom_base;
uint8_t capabilities_ptr;
uint8_t reserved1[3];
uint32_t reserved2;
uint8_t interrupt_line;
uint8_t interrupt_pin;
uint8_t min_grant;
uint8_t max_latency;
} __attribute__((packed));
uint32_t pci_config_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset); uint32_t pci_config_read(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset);
void pci_config_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value); void pci_config_write(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value);

View File

@ -1,38 +0,0 @@
#ifndef _FAT16_H
#define _FAT16_H
#include <types.h>
#define FAT16_MAX_FILENAME 256
#define FAT16_ATTR_DIRECTORY 0x10
typedef struct {
uint8_t drive;
uint32_t fat_start;
uint32_t root_dir_start;
uint32_t data_start;
uint16_t bytes_per_sector;
uint8_t sectors_per_cluster;
uint16_t root_entry_count;
uint32_t current_dir_cluster;
} fat16_t;
typedef struct {
char name[FAT16_MAX_FILENAME];
uint8_t attr;
uint32_t cluster;
uint32_t size;
} fat16_dir_entry_t;
int32_t fat16_init(uint8_t drive);
uint32_t cluster_to_lba(uint16_t cluster);
uint16_t fat16_get_fat_entry(uint16_t cluster);
uint16_t fat16_alloc_cluster(void);
int32_t fat16_list_dir(fat16_dir_entry_t* entries, size_t max_entries);
int32_t fat16_change_dir(const char* dirname);
int32_t fat16_read_file(const char* filename, void* buffer, size_t max_size);
int32_t fat16_write_file(const char* filename, const void* data, size_t size);
#endif

12
include/fs/sfs.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _SFS_H
#define _SFS_H
#include <types.h>
int32_t sfs_init(bool format);
bool sfs_get_formatted_name(const char* raw_name, char output[37]);
int32_t sfs_read_file(char* name, void* buffer, uint32_t num);
#endif

View File

@ -3,7 +3,7 @@
#include <types.h> #include <types.h>
typedef int32_t FILE;

View File

@ -4,7 +4,7 @@
#define SSE_XMM_SIZE 128 #define SSE_XMM_SIZE 128
void enable_sse(void); /*void enable_sse(void);*/ /* We use _enable_sse_asm (in boot.s) instead */
int32_t test_sse(void); int32_t test_sse(void);

View File

@ -8,9 +8,7 @@
#error "This kernel needs to be compiled with a ix86-elf compiler" #error "This kernel needs to be compiled with a ix86-elf compiler"
#endif #endif
#include <stdbool.h> #include <types.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h> #include <string.h>
@ -19,6 +17,7 @@
#include <gdt.h> #include <gdt.h>
#include <drivers/idt.h> #include <drivers/idt.h>
#include <drivers/irq.h>
#include <multiboot.h> #include <multiboot.h>
@ -32,15 +31,14 @@
#include <fs/fat32.h> #include <fs/fat32.h>
#include <fs/duckfs.h> #include <fs/duckfs.h>
#include <fs/vfs.h> #include <fs/vfs.h>
#include <fs/sfs.h>
#include <vector_extentions/sse.h> #include <vector_extensions/sse.h>
#include <kernel/intro.h> #include <kernel/intro.h>
#define DEBUG #define DEBUG
/*extern HBA_MEM *abar;
extern HBA_PORT *ahci_port;*/
extern void _hang_asm(void); extern void _hang_asm(void);
extern void _sti_asm(void); extern void _sti_asm(void);
@ -80,6 +78,8 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
idt_init(); idt_init();
_sti_asm(); _sti_asm();
irq_init(); /* MUST be done after pci_remap() and idt_init() */
terminal_setcolor(VGA_COLOR_GREEN); terminal_setcolor(VGA_COLOR_GREEN);
printd("Initializing physical memory manager...\n"); printd("Initializing physical memory manager...\n");
@ -102,7 +102,7 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
} }
else else
{ {
printd("SSE test succeeded\n"); printd("SSE test passed\n");
} }
printd("Initializing the PIT...\n"); printd("Initializing the PIT...\n");
@ -123,17 +123,13 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
ide_initialize(); ide_initialize();
printd("IDE initialized\n"); printd("IDE initialized\n");
/*printd("Initializing fat16...\n");
fat16_init(0);
printd("fat16 initialized.\n");*/
/*printd("Initializing DuckFS...\n"); /*printd("Initializing DuckFS...\n");
duckfs_init(); duckfs_init();
printd("DuckFS initialized\n");*/ printd("DuckFS initialized\n");*/
/*printd("Initializing FAT32...\n"); printd("Initializing PCI...\n");
fat32_init(0); pci_enumerate();
printd("FAT32 initialized\n");*/ printd("PCI initialized\n");
@ -147,6 +143,11 @@ void kernel_main(multiboot_info_t* mbd, unsigned int magic)
printf("Guten tag and welcome to Espresso\n"); printf("Guten tag and welcome to Espresso\n");
/*printf("here\n");
printf("%i\n", sfs_init(false));
printf("here\n");*/
while (true) while (true)
{ {

View File

@ -25,7 +25,7 @@ char* getstring(void)
return "HELLO\0"; return "HELLO\0";
} }
char* fgets(char* buf, int n, FILE file) /*char* fgets(char* buf, int n, FILE file)
{ {
if (!buf || n <= 1 || file < 1) if (!buf || n <= 1 || file < 1)
{ {
@ -37,26 +37,26 @@ char* fgets(char* buf, int n, FILE file)
while (total_read < n - 1) while (total_read < n - 1)
{ {
int bytes = 0/*read_file(file, &c, 1)*/; int bytes = 0*//*read_file(file, &c, 1)*/;
if (bytes <= 0) /*if (bytes <= 0)
{ {
break; /* EOF or error */ break; *//* EOF or error */
} /*}
buf[total_read++] = c; buf[total_read++] = c;
if (c == '\n') if (c == '\n')
{ {
break; /* Stop at newline */ break; *//* Stop at newline */
} /*}
} }
if (total_read == 0) if (total_read == 0)
{ {
return NULL; /* Nothing read (e.g. EOF) */ return NULL; *//* Nothing read (e.g. EOF) */
} /*}
buf[total_read] = '\0'; buf[total_read] = '\0';
return buf; return buf;
} }*/

View File

@ -1,6 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <vector_extentions/sse.h> #include <vector_extensions/sse.h>
#include <string.h> #include <string.h>
@ -184,7 +184,6 @@ char* strchr(const char* s, int c)
} }
void* memset(void *dst, char c, uint32_t n) void* memset(void *dst, char c, uint32_t n)
{ {
char *temp = dst; char *temp = dst;

View File

@ -1,10 +1,7 @@
#include <stdint.h> #include <types.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <vector_extentions/sse.h> #include <vector_extensions/sse.h>
void enable_sse(void) void enable_sse(void)
@ -12,17 +9,17 @@ void enable_sse(void)
uint32_t cr0, cr4; uint32_t cr0, cr4;
__asm__ volatile ("mov %%cr0, %0" : "=r"(cr0)); __asm__ volatile ("mov %%cr0, %0" : "=r"(cr0));
cr0 &= ~(1 << 2); // EM = 0 cr0 &= ~(1 << 2);
cr0 |= (1 << 1); // MP = 1 cr0 |= (1 << 1);
__asm__ volatile ("mov %0, %%cr0" :: "r"(cr0)); __asm__ volatile ("mov %0, %%cr0" :: "r"(cr0));
__asm__ volatile ("mov %%cr4, %0" : "=r"(cr4)); __asm__ volatile ("mov %%cr4, %0" : "=r"(cr4));
cr4 |= (1 << 9); // OSFXSR = 1 cr4 |= (1 << 9);
cr4 |= (1 << 10); // OSXMMEXCPT = 1 cr4 |= (1 << 10);
__asm__ volatile ("mov %0, %%cr4" :: "r"(cr4)); __asm__ volatile ("mov %0, %%cr4" :: "r"(cr4));
} }
// Basic SSE test: add two arrays of 4 floats using xmm registers /* Basic SSE test: add two arrays of 4 floats using xmm registers */
__attribute__((force_align_arg_pointer)) __attribute__((force_align_arg_pointer))
int32_t test_sse(void) int32_t test_sse(void)
{ {