This commit is contained in:
notsomeidiot123 2025-09-24 12:15:52 -04:00
parent 25d67aaa9e
commit c7aaedbd2a
8 changed files with 233 additions and 90 deletions

View File

@ -36,7 +36,7 @@ mount: bootloader tools kernel
bootloader:
$(AS) src/bootloader/main.s $(BL_ASFLAGS) -o bin/bootloader.bin
run:
qemu-system-i386 -hda image.bin --no-reboot --no-shutdown -m 32m -smp 2 -serial mon:stdio -D intlog.txt -d int
qemu-system-i386 -hda image.bin -hdb test.bin --no-reboot --no-shutdown -m 32m -smp 2 -serial mon:stdio -D intlog.txt -d int
# kernel: $(OBJS)
kernel:
@ -48,9 +48,9 @@ kernel:
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
ld -T linker.ld bin/kernel/*.o -melf_i386 -o kernel.elf -static
ld -T linker.ld -o kernel_interface.elf -r -R kernel.elf -melf_i386
ld -pie bin/modules/disk_driver.o -o idm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
ld -pie bin/modules/disk_driver.o bin/kernel/string.o -o idm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
# ld bin/modules/fs_driver.o -o ifsm.elf -melf_i386
ld -pie bin/modules/fs_driver.o -o ifsm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
ld -pie bin/modules/fs_driver.o bin/kernel/string.o -o ifsm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
# %.o: $(SRCS)
# mkdir -p bin/kernel/$(shell dirname $@)
# $(CC) $(CFLAGS) $< -o $@

View File

@ -118,6 +118,10 @@ void kernel_panic(char *message, cpu_registers_t *regs){
void install_irq_handler(void (*handler)(), uint8_t irqno){
interrupt_handlers[irqno] = handler;
// printf("called\n");
}
void *get_irq_handler(uint8_t irqno){
return interrupt_handlers[irqno];
}
void pit_reload(uint8_t mode, uint16_t reload){
const uint16_t PIT_CMD = 0x43;

View File

@ -20,7 +20,19 @@ void sysinit(){
mlog("KERNEL", "PID 1 Started\n", MLOG_PRINT);
pci_init();
modules_init(boot_info);
vfile_t *file;
vfile_t *file = fopen("/dev/disk");
vfile_t **dir_data = file->access.data.ptr;
printf("/dev/disk/: %x\n", file);
// fcreate("/dev/disk/test", VFILE_DEVICE, 0, 0);
int i = 0;
while(dir_data[i]){
printf("%d: %s\n", i, dir_data[i]->name);
i++;
}
vfile_t *drive_test = fopen("/dev/disk/ide0");
uint32_t *buffer = kmalloc(1);
int status = fread(drive_test, buffer, 0, 512);
printf("Done: %x, %x\n", status, buffer[0]);
//fopen shell file & execute it.
for(;;);
}
@ -31,10 +43,12 @@ extern void kmain(kernel_info_t *kernel_info){
idt_load();
pic_init(0x20);
pic_disable();
pic_setmask(0xfe, PIC1_DATA);
pic_setmask(0x0, PIC1_DATA);
pic_setmask(0x0, PIC2_DATA);
vfs_init();
fcreate("/dev", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("/dev/disk", VFILE_DIRECTORY, kmalloc(1), 1);
fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1);
mlog("KERNEL", "Initializing Scheduler & starting PID 1\n", MLOG_PRINT);
boot_info = kernel_info;

View File

@ -30,4 +30,5 @@ inline void disable_interrupts(){
asm volatile("cli");
}
void kernel_panic(char *msg, cpu_registers_t *regs);
void install_irq_handler(void (*handler)(), uint8_t irqno);
void install_irq_handler(void (*handler)(), uint8_t irqno);
void *get_irq_handler(uint8_t irqno);

View File

@ -19,28 +19,44 @@ uint32_t module_api(uint32_t func, ...){
//do something
module_t *structure = va_arg(vars, void *);
if(structure == 0){
return -1;
return_value = -1;
}
vector_push(modules, structure);
uint32_t tmp = pm_alloc();
(structure->key) = (modules->size ^ 190507) + tmp << 12 ^ 4405648937 ^ 8592807313 >> 5;
structure->key & 0xffffff00 | modules->size;
pm_free(tmp);
return 0;
break;
case MODULE_API_ADDFUNC:
//do something
return_value = -1;
break;
case MODULE_API_DELFUNC:
//do something
return_value = -1;
return_value = 0;
break;
case MODULE_API_ADDINT:
uint32_t int_index = va_arg(vars, uint32_t);
//do something
uint32_t key = va_arg(vars, uint32_t);
void *interrupt_handler = va_arg(vars, void *);
if(int_index >= 16 || int_index < 0 /* || get_irq_handler(int_index)*/){
return_value = -1;
break;
}
// printf("installed %d", int_index);
install_irq_handler(interrupt_handler, int_index);
module_t *tmpmodule = vector_get(key & 0xff, modules);
tmpmodule->interrupts |= 1 << int_index;
return_value = 0;
// printf("Added key\n");
break;
case MODULE_API_DELINT:
int_index = va_arg(vars, uint32_t);
key = va_arg(vars, uint32_t);
tmpmodule = vector_get(key & 0xff, modules);
if(key == tmpmodule->key){
install_irq_handler(0, int_index);
tmpmodule->interrupts &= ~(1 << int_index);
}
else{
return_value = -1;
break;
}
return_value = 0;
break;
case MODULE_API_PRINT:
// vmlog(MODULE_NAME, "Testing modules calling kernel functions\n", MLOG_PRINT, vars);
@ -91,8 +107,8 @@ uint32_t module_api(uint32_t func, ...){
return_value = get_paddr(addr);
break;
case MODULE_API_MALLOC:
uint32_t size_pgs = va_arg(vars, uint32_t);
return_value = (uint32_t)kmalloc(size_pgs);
uint32_t sz_pgs = va_arg(vars, uint32_t);
return_value = (uint32_t)kmalloc(sz_pgs);
break;
case MODULE_API_FREE:
void *ptr = va_arg(vars, void *);

View File

@ -9,24 +9,27 @@
//no patch number
#define MODULE_API_VERSION 0x0100
#define MODULE_API_REGISTER 0 //registers the module as active using information provided from the module
#define MODULE_API_ADDFUNC 1 //adds function to kernel API handler
#define MODULE_API_DELFUNC 2 //delete function from kernel API handler
#define MODULE_API_ADDINT 3 //set interrupt handler
#define MODULE_API_DELINT 4 //delete interrupt handler
#define MODULE_API_PRINT 5 //print to terminal
#define MODULE_API_READ 6 //read from virtual file
#define MODULE_API_WRITE 7 //write to virtual file
#define MODULE_API_CREAT 8 //create a virtual file and assigns it to the the proper module (requires having a read and write function passed)
#define MODULE_API_DELET 9 //delete a virtual file
#define MODULE_API_OPEN 10
#define MODULE_API_MAP 11 //map physical address to virtual address
#define MODULE_API_UNMAP 12 //unmap physical address to virtual address
#define MODULE_API_PADDR 13 //get physical address of memory
#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks
#define MODULE_API_FREE 15 //free memory allocated by malloc
#define MODULE_API_PMALLOC64K 16
#define MODULE_API_KMALLOC_PADDR 17
enum MODULE_API_FUNCS{
MODULE_API_ADDFUNC,//adds function to kernel API handler
MODULE_API_REGISTER, //registers the module as active using information provided from the module
MODULE_API_DELFUNC, //delete function from kernel API handler
MODULE_API_ADDINT, //set interrupt handler
MODULE_API_DELINT, //delete interrupt handler
MODULE_API_PRINT, //print to terminal
MODULE_API_READ, //read from virtual file
MODULE_API_WRITE, //write to virtual file
MODULE_API_CREAT, //create a virtual file and assigns it to the the proper module (requires having a read and write function passed)
MODULE_API_DELET, //delete a virtual file
MODULE_API_OPEN,
MODULE_API_MAP, //map physical address to virtual address
MODULE_API_UNMAP, //unmap physical address to virtual address
MODULE_API_PADDR, //get physical address of memory
MODULE_API_MALLOC, //allocate memory in 4kb blocks
MODULE_API_FREE, //free memory allocated by malloc
MODULE_API_PMALLOC64K,
MODULE_API_KMALLOC_PADDR,
};
typedef struct module{
void *init_entry;

View File

@ -127,13 +127,14 @@ void fini();
enum DRIVE_TYPE{
TYPE_NULL,
TYPE_TMP,
TYPE_IDE,
TYPE_AHCI,
TYPE_NVME,
TYPE_USB,
TYPE_FLOPPY, //Here, Navya, just for you
};
uint32_t volatile transferring_disk_index = -1;
typedef struct drive_desc{
uint32_t BARs[8];
enum DRIVE_TYPE type;
@ -150,10 +151,6 @@ typedef struct drive_desc{
drive_t drives[32] = {0};
uint16_t get_bus_from_drive(uint32_t drive){
return drive & 2 ? ATA_SECONDARY_BUS : ATA_PRIMARY_BUS;
}
//return 1 if ready, 0 if not
int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){
static uint16_t last_disk = 0;
@ -169,6 +166,7 @@ int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){
uint8_t status = inb(BAR2 ATA_ALT_STATUS);
return (status >> 7) == 0;
}
void ata_reset(uint16_t bar1){
outw(bar1 ATA_DEVICE_CONTROL, 0x4);
for(uint32_t i = 0; i < 4096; i++){
@ -185,6 +183,89 @@ uint32_t find_free_drive(){
}
}
int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count){
if(count == 0){
return -1;//prevent from accidentally reading 65536 * 512 bytes
}
drive_t drive = drives[file->mount_id];
uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3);
uint32_t status = inb(dmabar + 2);
api(MODULE_API_PRINT, MODULE_NAME, "status: %x\n", status);
PRD_T *prdt = drive.PRDT;
if(count == 0) return 0;
uint32_t count_pgs = ((count + 4096) / 4096);
for(int i = 0; i < count_pgs; i++){
prdt[i].address = api(MODULE_API_PADDR, ptr + (i * (1 << 12)));
prdt[i].byte_count = (i == (count_pgs - 1)) ? count % (1 << 12) : 1 << 12;
prdt[i].reserved = (1 << 31) * (i == (count_pgs - 1));
}
outb(dmabar + 2, 0x6);
outl(dmabar + 4, api(MODULE_API_PADDR, prdt));
outb(dmabar, 0x8);
while(!ata_ready(drive.BARs[0] >> 2, drive.BARs[1] >> 2, drive.flags.slave));
outb(drive.BARs[1], 0x00);
uint64_t lba = (offset >> 9);
uint8_t *lba_arr = &lba;
outb(drive.BARs[0] + ATA_DRIVE_HEAD, 0x40 | (drive.flags.slave << 4) | ((lba >> 24) * !drive.flags.huge));
if(count >> 9 == 0){
return 0;
}
if(drive.flags.huge){
outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9) >> 8);
}else{
outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9));
}
for(uint32_t i = 0; i < 3; i++){
outb(drive.BARs[0] + ATA_LBA_LOW + i, lba_arr[i + 3 * drive.flags.huge]);
}
if(drive.flags.huge){
outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9) & 0xff);
for(uint32_t i = 0; i < 3; i++){
outb(drive.BARs[0] + ATA_LBA_LOW + i, lba_arr[i]);
}
puts(api, MODULE_NAME, "bleh\n");
outb(drive.BARs[0] + ATA_COMMAND, ATA_CMD_READ_DMA_EXT);
}else{
outb(drive.BARs[0] + ATA_COMMAND, ATA_CMD_READ_DMA);
}
//issue read command to drive
transferring_disk_index = file->mount_id;
outb(dmabar, 0x9);
// while(!ata_ready(drive.BARs[0] >> 2, drive.BARs[1] >> 2, drive.flags.slave));
while(transferring_disk_index != -1);
// while (!(inb(dmabar + 2) & 0x01));
outb(dmabar, 0x0);
return 0;
}
cpu_registers_t *int_handler(cpu_registers_t * regs){
puts(api, MODULE_NAME, "Interrupt called");
drive_t drive = drives[transferring_disk_index];
uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3);
uint32_t status = inb(dmabar + 2);
transferring_disk_index = -1;
if(status & 0x4) return regs;
return regs;
}
int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
}
//return 255 if err/ does not exist
//return 0 if is ATA drive
//return 1 if is ATAPI
@ -228,24 +309,42 @@ uint8_t ata_identify(uint32_t index, uint16_t disk){
}
// drives[index].size_sectors
uint32_t lba48 = (identify[83] & (1 << 10));
drives[index].flags.huge = lba48 ? 1 : 0;
// drives[index].flags.huge = lba48 ? 1 : 0;
drives[index].size_sectors = !lba48 ? (identify[60] | (identify[61] << 16)) : ((uint64_t)(identify[100]) | (uint64_t)(identify[101] << 16) | ((uint64_t)identify[102] << 32));
api(MODULE_API_PRINT, MODULE_NAME, "Sector Count: %x\n", drives[index].size_sectors);
char fname[32];
strcpy("/dev/disk/ide", fname);
uint8_t ata_drives = 0;
for(uint32_t i = 0; i < 32; i++){
if(drives[i].type == TYPE_IDE) ata_drives++;
}
drives[index].type = TYPE_IDE;
itoa(ata_drives, fname + strlen(fname), 10);
vfile_t *new_file = fcreate(api, fname, VFILE_DEVICE, ata_write, ata_read);
new_file->mount_id = index;
free(api, fname);
return 1;
}
void ide_init(uint32_t BARS[5]){
uint32_t primary_index = find_free_drive();
drives[primary_index].type = TYPE_IDE;
drives[primary_index].type = TYPE_TMP;
uint32_t primary_slave_index = find_free_drive();
drives[primary_slave_index].type = TYPE_TMP;
uint32_t secondary_index = find_free_drive();
drives[secondary_index].type = TYPE_IDE;
drives[secondary_index].type = TYPE_TMP;
uint32_t secondary_slave_index = find_free_drive();
drives[secondary_slave_index].type = TYPE_TMP;
for(int i = 0; i < 2; i++){
drives[primary_index].BARs[i] = BARS[i];
drives[primary_slave_index].BARs[i] = BARS[i];
drives[secondary_index].BARs[i] = BARS[i+2];
drives[secondary_slave_index].BARs[i] = BARS[i+2];
}
drives[primary_index].BARs[4] = BARS[4];
drives[primary_slave_index].BARs[4] = BARS[4];
drives[secondary_index].BARs[4] = BARS[4];
drives[secondary_slave_index].BARs[4] = BARS[4];
uint32_t prdt_primary_paddr = api(MODULE_API_PMALLOC64K);
uint32_t prdt_secondary_paddr = api(MODULE_API_PMALLOC64K);
@ -253,45 +352,41 @@ void ide_init(uint32_t BARS[5]){
drives[secondary_index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_secondary_paddr, 16);
//now call ATA IDENTIFY
uint8_t master_status = ata_identify(primary_index, ATA_MASTER);
drive_t master_copy = drives[primary_index];
if(ata_identify(primary_index, ATA_SLAVE) == 0){
if(master_status == -1){
drives[primary_index].flags.slave = 1;
}
else{
uint32_t slave_index = find_free_drive();
drives[slave_index] = drives[primary_index];
drives[slave_index].flags.slave = 1;
drives[primary_index] = master_copy;
drives[slave_index].type = TYPE_IDE;
}
uint8_t slave_status = ata_identify(primary_slave_index, ATA_SLAVE);
if(master_status){
drives[primary_index].type = TYPE_NULL;
}
if(slave_status){
drives[primary_slave_index].type = TYPE_NULL;
}
master_status = ata_identify(secondary_index, ATA_MASTER);
master_copy = drives[secondary_index];
if(ata_identify(secondary_index, ATA_SLAVE) == 0){
if(master_status == -1){
drives[secondary_index].flags.slave = 1;
}
else{
uint32_t slave_index = find_free_drive();
drives[slave_index] = drives[secondary_index];
drives[slave_index].flags.slave = 1;
drives[secondary_index] = master_copy;
drives[slave_index].type = TYPE_IDE;
}
slave_status = ata_identify(secondary_slave_index, ATA_SLAVE);
if(master_status){
drives[secondary_index].type = TYPE_NULL;
}
if(slave_status){
drives[secondary_slave_index].type = TYPE_NULL;
}
// outb(BARS[4] >> 1, 0x0);
// int volatile tt = 0;
// while(tt < 50000){
// tt++;
// }
}
void init(KOS_MAPI_FP module_api, uint32_t api_version){
api = module_api;
api(MODULE_API_PRINT, MODULE_NAME, "KIDM Storage Driver Module v0.1.0\nSupported interfaces: \n");
api(MODULE_API_PRINT, MODULE_NAME, "KIDM Storage Driver Module v0.1.0\nSupported interfaces: \n- PATA\n");
int status = api(MODULE_API_REGISTER, &module_data);
if(status){
api(MODULE_API_PRINT, MODULE_NAME, "Failed to register module, exiting\n");
return;
}
api(MODULE_API_PRINT, MODULE_NAME, "Key Test: %x", module_data.key);
api(MODULE_API_ADDINT, 15, module_data.key, int_handler);
api(MODULE_API_ADDINT, 14, module_data.key, int_handler);
// api(MODULE_API_ADDINT, 0, module_data.key, int_handler);
vfile_t *pci_drive_dir = fopen(api, "/dev/pci/disk/");
vfile_t **dir_data = (pci_drive_dir->access.data.ptr);
for(uint32_t i = 0; dir_data[i]; i++){

View File

@ -1,24 +1,27 @@
#pragma once
#include <stdint.h>
#define MODULE_API_REGISTER 0 //registers the module as active using information provided from the module
#define MODULE_API_ADDFUNC 1 //adds function to kernel API handler
#define MODULE_API_DELFUNC 2 //delete function from kernel API handler
#define MODULE_API_ADDINT 3 //set interrupt handler
#define MODULE_API_DELINT 4 //delete interrupt handler
#define MODULE_API_PRINT 5 //print to terminal
#define MODULE_API_READ 6 //read from virtual file
#define MODULE_API_WRITE 7 //write to virtual file
#define MODULE_API_CREAT 8 //create a virtual file and assigns it to the the proper module (requires having a read and write function passed)
#define MODULE_API_DELET 9 //delete a virtual file
#define MODULE_API_OPEN 10 //open a virtual file
#define MODULE_API_MAP 11 //map physical address to virtual address
#define MODULE_API_UNMAP 12 //unmap physical address to virtual address
#define MODULE_API_PADDR 13 //get physical address of memory
#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks
#define MODULE_API_FREE 15 //free memory allocated by malloc
#define MODULE_API_PMALLOC64K 16 //get 64k-aligned pages
#define MODULE_API_KMALLOC_PADDR 17
enum MODULE_API_FUNCS{
MODULE_API_ADDFUNC,//adds function to kernel API handler
MODULE_API_REGISTER, //registers the module as active using information provided from the module
MODULE_API_DELFUNC, //delete function from kernel API handler
MODULE_API_ADDINT, //set interrupt handler
MODULE_API_DELINT, //delete interrupt handler
MODULE_API_PRINT, //print to terminal
MODULE_API_READ, //read from virtual file
MODULE_API_WRITE, //write to virtual file
MODULE_API_CREAT, //create a virtual file and assigns it to the the proper module (requires having a read and write function passed)
MODULE_API_DELET, //delete a virtual file
MODULE_API_OPEN,
MODULE_API_MAP, //map physical address to virtual address
MODULE_API_UNMAP, //unmap physical address to virtual address
MODULE_API_PADDR, //get physical address of memory
MODULE_API_MALLOC, //allocate memory in 4kb blocks
MODULE_API_FREE, //free memory allocated by malloc
MODULE_API_PMALLOC64K,
MODULE_API_KMALLOC_PADDR,
};
typedef uint32_t (*KOS_MAPI_FP)(unsigned int function, ...);
typedef struct module{
@ -31,6 +34,13 @@ typedef struct module{
void (*fini)(void);
}module_t;
typedef struct cpu_registers{
uint32_t gs, fs, es, ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no, pfa;
uint32_t eip, cs, eflags, useresp, ss;
}__attribute__((packed))cpu_registers_t;
typedef enum vfile_type{
VFILE_POINTER,
VFILE_DEVICE,