changes were made

This commit is contained in:
TriMill 2023-04-28 19:17:17 -04:00
parent bca17fe5b9
commit cc00613c5d
26 changed files with 666 additions and 118 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
compile_flags.txt
bin
disk.img

View file

@ -11,7 +11,7 @@ A_OBJ=$(patsubst %.asm,bin/%_asm.o,$(A_SOURCE))
LIBK_SOURCE=$(shell find libk -type f -name "*.c")
LIBK_OBJ=$(patsubst %.c,bin/%.o,$(LIBK_SOURCE))
.PHONY: test all run clean
.PHONY: test all run clean mkdiskimg
all: bin/os.iso
@ -42,8 +42,14 @@ bin/os.iso: bin/kernel.bin grub.cfg
cp bin/kernel.bin bin/iso/boot
grub-mkrescue -o bin/os.iso bin/iso
run: all
qemu-system-i386 -cdrom bin/os.iso
bin/disk.img:
@mkdir -p bin
cp disk.img bin/disk.img
run: bin/os.iso bin/disk.img
qemu-system-i386 -cdrom bin/os.iso \
-drive file=bin/disk.img,format=raw,if=ide \
-boot order=d
clean:
rm -rf bin

BIN
disk.img Normal file

Binary file not shown.

View file

@ -3,7 +3,6 @@
#include <string.h>
#include "panic.h"
#include "term.h"
#include "bootinfo.h"
#define CMDLINE_MAX 128

127
kernel/drivers/ata.c Normal file
View file

@ -0,0 +1,127 @@
#include <sys.h>
#include "ata.h"
#include "pci.h"
#include "../panic.h"
#define REG_DATA 0
#define REG_ERR 1
#define REG_FEATURES 1
#define REG_SECTOR_CNT 2
#define REG_SECTOR_NUM 3
#define REG_LBA_LO 3
#define REG_CYLINDER_LO 4
#define REG_LBA_MID 4
#define REG_CYLINDER_HI 5
#define REG_LBA_HI 5
#define REG_DRIVE_HEAD 6
#define REG_STATUS 7
#define REG_COMMAND 7
#define STAT_ERR 0x01
#define STAT_IDX 0x02
#define STAT_CORR 0x04
#define STAT_DRQ 0x08
#define STAT_SRV 0x10
#define STAT_DF 0x20
#define STAT_RDY 0x40
#define STAT_BSY 0x80
static bool ata_init_impl(uint16_t base, uint16_t ctrl, struct AtaDevice *dev) {
uint8_t status = inb(base + REG_STATUS);
outb(base + REG_DRIVE_HEAD, 0xA0);
outb(base + REG_SECTOR_CNT, 0x00);
outb(base + REG_LBA_LO, 0x00);
outb(base + REG_LBA_MID, 0x00);
outb(base + REG_LBA_HI, 0x00);
outb(base + REG_COMMAND, 0xEC);
status = STAT_BSY;
while(status & STAT_BSY) {
status = inb(base + REG_STATUS);
}
if(inb(base + REG_LBA_MID) != 0 || inb(base + REG_LBA_HI) != 0) {
panic("Device is not an ATA device");
}
while(!(status & (STAT_DRQ | STAT_ERR))) {
status = inb(base + REG_STATUS);
}
if(status & STAT_ERR) {
uint8_t err = inb(base + REG_ERR);
panic("Error initializing ATA device: %X", err);
}
uint16_t data[256];
for(int i = 0; i < 256; i++) {
data[i] = inw(base + REG_DATA);
}
uint32_t sector_count = data[60] | (data[61] << 16);
if(sector_count == 0) {
panic("ATA device does not support LBA28");
}
dev->base = base;
dev->ctrl = ctrl;
dev->sector_count = sector_count;
return true;
}
bool ata_init(struct AtaDevice *atadev, struct PciDevice pcidev) {
uint8_t prog_if = pci_rcfg_b(pcidev, PCI_PROG_IF_B);
if((prog_if & 0x7F) != 0) {
panic("Could not initialize ATA device: unsupported prog_if %X", prog_if);
}
atadev->pcidev = pcidev;
if(!ata_init_impl(0x1F0, 0x3F6, atadev)) {
return false;
}
return true;
}
bool ata_read(struct AtaDevice atadev, uint32_t lba, uint8_t sector_count, uint16_t buf[sector_count*256]) {
outb(atadev.base + REG_DRIVE_HEAD, 0xE0 | ((lba >> 24) & 0x0F));
outb(atadev.base + REG_FEATURES, 0x00);
outb(atadev.base + REG_SECTOR_CNT, sector_count);
outb(atadev.base + REG_LBA_LO, lba & 0xFF);
outb(atadev.base + REG_LBA_MID, (lba >> 8) & 0xFF);
outb(atadev.base + REG_LBA_HI, (lba >> 16) & 0xFF);
outb(atadev.base + REG_COMMAND, 0x20);
for(int i = 0; i < sector_count; i++) {
while(true) {
uint8_t status = inb(atadev.ctrl);
if(status & STAT_DRQ) break;
if(status & STAT_DF) panic("Drive failure");
if(status & STAT_ERR) panic("Read disk error");
}
for(int j = 0; j < 256; j++) {
buf[i*256 + j] = inw(atadev.base + REG_DATA);
}
}
return true;
}
bool ata_write(struct AtaDevice atadev, uint32_t lba, uint8_t sector_count, uint16_t buf[sector_count*256]) {
outb(atadev.base + REG_DRIVE_HEAD, 0xE0 | ((lba >> 24) & 0x0F));
outb(atadev.base + REG_FEATURES, 0x00);
outb(atadev.base + REG_SECTOR_CNT, sector_count);
outb(atadev.base + REG_LBA_LO, lba & 0xFF);
outb(atadev.base + REG_LBA_MID, (lba >> 8) & 0xFF);
outb(atadev.base + REG_LBA_HI, (lba >> 16) & 0xFF);
outb(atadev.base + REG_COMMAND, 0x30);
for(int i = 0; i < sector_count; i++) {
while(true) {
uint8_t status = inb(atadev.ctrl);
if(status & STAT_DRQ) break;
if(status & STAT_DF) panic("Drive failure");
if(status & STAT_ERR) panic("Write disk error");
}
for(int j = 0; j < 256; j++) {
outw(atadev.base + REG_DATA, buf[i*256 + j]);
}
}
io_wait();
outb(atadev.base + REG_COMMAND, 0xE7);
while(inb(atadev.ctrl & STAT_BSY)) {}
return true;
}

14
kernel/drivers/ata.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "pci.h"
struct AtaDevice {
struct PciDevice pcidev;
uint16_t base;
uint16_t ctrl;
uint32_t sector_count;
};
bool ata_init(struct AtaDevice *atadev, struct PciDevice pcidev);
bool ata_read(struct AtaDevice atadev, uint32_t lba, uint8_t sector_count, uint16_t buf[sector_count*256]);
bool ata_write(struct AtaDevice atadev, uint32_t lba, uint8_t sector_count, uint16_t buf[sector_count*256]);

View file

@ -9,7 +9,7 @@ struct Keycode {
#define KC_FLAG_KEY_DOWN 0x01
#define KC_FLAG_KEY_UP 0x02
#define KC_FLAG_ERROR 0x04
#define KC_FLAG_ERROR 0x04
#define KEY_NONE 0x00
#define KEY_UNKNOWN 0x01

157
kernel/drivers/pci.c Normal file
View file

@ -0,0 +1,157 @@
#include <stdint.h>
#include <sys.h>
#include "../panic.h"
#include "pci.h"
#define CONF_ADDR 0xCF8
#define CONF_DATA 0xCFC
#define TABLE_LEN 16
struct PciTableEntry {
struct PciDevice device;
uint16_t device_id;
uint16_t vendor_id;
uint8_t class;
uint8_t subclass;
uint8_t prog_if;
uint8_t revision;
};
static struct PciTableEntry pci_table[TABLE_LEN];
static size_t pci_table_next = 0;
uint32_t pci_rcfg_d(struct PciDevice dev, uint8_t offset) {
uint32_t addr = 0x80000000;
addr |= ((uint32_t)dev.bus) << 16;
addr |= ((uint32_t)dev.device) << 11;
addr |= ((uint32_t)dev.function) << 8;
addr |= offset & 0xFC;
outl(CONF_ADDR, addr);
uint32_t in = inl(CONF_DATA);
return in;
}
uint16_t pci_rcfg_w(struct PciDevice dev, uint8_t offset) {
uint32_t dword = pci_rcfg_d(dev, offset);
return (uint16_t)((dword >> ((offset & 2) * 8)) & 0xFFFF);
}
uint8_t pci_rcfg_b(struct PciDevice dev, uint8_t offset) {
uint32_t dword = pci_rcfg_d(dev, offset);
return (uint8_t)((dword >> ((offset & 3) * 8)) & 0xFF);
}
void pci_wcfg_d(struct PciDevice dev, uint8_t offset, uint32_t dword) {
uint32_t addr = 0x80000000;
addr |= ((uint32_t)dev.bus) << 16;
addr |= ((uint32_t)dev.device) << 11;
addr |= ((uint32_t)dev.function) << 8;
addr |= offset & 0xFC;
outl(CONF_ADDR, addr);
outl(CONF_DATA, dword);
}
void pci_wcfg_w(struct PciDevice dev, uint8_t offset, uint16_t word) {
size_t shift = (offset & 2) * 8;
uint32_t dword = pci_rcfg_d(dev, offset);
dword &= ~(0xFFFF << shift);
dword |= word << shift;
pci_wcfg_d(dev, offset, dword);
}
void pci_wcfg_b(struct PciDevice dev, uint8_t offset, uint8_t byte) {
size_t shift = (offset & 3) * 8;
uint32_t dword = pci_rcfg_d(dev, offset);
dword &= ~(0xFF << shift);
dword |= byte << shift;
pci_wcfg_d(dev, offset, dword);
}
//static void print_device(struct PciTableEntry *entry) {
// printf("pci bus @0e%X@0f dev @0e%X@0f func @0e%X@0f",
// entry->device.bus, entry->device.device, entry->device.function);
//
// printf("\tid @0c%X:%X@0f", entry->vendor_id, entry->device_id);
//
// printf("\tclass @0c%X:%X:%X@0f", entry->class, entry->subclass, entry->prog_if);
// printf("\trev @0c%X@0f\n", entry->revision);
//}
static struct PciTableEntry *load_device(struct PciDevice dev) {
if(pci_table_next >= TABLE_LEN) panic("Too many PCI devices: limit is %d", TABLE_LEN);
struct PciTableEntry *entry = &pci_table[pci_table_next++];
entry->device = dev;
uint32_t dword0 = pci_rcfg_d(dev, 0);
uint32_t dword2 = pci_rcfg_d(dev, 8);
entry->device_id = (dword0 >> 16) & 0xFFFF;
entry->vendor_id = dword0 & 0xFFFF;
entry->class = (dword2 >> 24) & 0xFF;
entry->subclass = (dword2 >> 16) & 0xFF;
entry->prog_if = (dword2 >> 8) & 0xFF;
entry->revision = dword2 & 0xFF;
//print_device(entry);
return entry;
}
void pci_init(void) {
pci_table_next = 0;
struct PciDevice pcidev;
for(int bus = 0; bus < 256; bus++) {
pcidev.bus = bus;
for(int dev = 0; dev < 32; dev++) {
pcidev.device = dev;
pcidev.function = 0;
uint16_t vendor = pci_rcfg_w(pcidev, 0);
if(vendor == 0xFFFF) continue;
load_device(pcidev);
uint8_t header_type = pci_rcfg_b(pcidev, 14);
if(!(header_type & 0x80)) continue;
for(int func = 1; func < 8; func++) {
pcidev.function = func;
uint16_t vendor = pci_rcfg_w(pcidev, 0);
if(vendor == 0xFFFF) continue;
load_device(pcidev);
}
}
}
}
bool pci_findby_class(struct PciDevice *dest, uint8_t class, uint8_t subclass, size_t *offset) {
size_t o = 0;
if(offset == NULL) offset = &o;
for(; *offset < pci_table_next; (*offset)++) {
struct PciTableEntry *entry = &pci_table[*offset];
if(entry->class == class && entry->subclass == subclass) {
*dest = entry->device;
return true;
}
}
return false;
}
bool pci_findby_id(struct PciDevice *dest, uint16_t device, uint16_t vendor, size_t *offset) {
size_t o = 0;
if(offset == NULL) offset = &o;
for(; *offset < pci_table_next; (*offset)++) {
struct PciTableEntry *entry = &pci_table[*offset];
if(entry->device_id == device && entry->vendor_id == vendor) {
*dest = entry->device;
return true;
}
}
return false;
}

55
kernel/drivers/pci.h Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
// common
#define PCI_VENDOR_W 0x00
#define PCI_DEVICE_W 0x02
#define PCI_COMMAND_W 0x04
#define PCI_STATUS_W 0x06
#define PCI_REVISION_B 0x08
#define PCI_PROG_IF_B 0x09
#define PCI_SUBCLASS_B 0x0A
#define PCI_CLASS_B 0x0B
#define PCI_CACHE_SIZE_B 0x0C
#define PCI_LATENCY_TIMER_B 0x0D
#define PCI_HEADER_TYPE_B 0x0E
#define PCI_BIST_B 0x0F
// header type 0
#define PCI_BAR0_D 0x10
#define PCI_BAR1_D 0x14
#define PCI_BAR2_D 0x18
#define PCI_BAR3_D 0x1C
#define PCI_BAR4_D 0x20
#define PCI_BAR5_D 0x24
#define PCI_CARDBUS_CIS_D 0x28
#define PCI_SUBSYSTEM_VENDOR_W 0x2C
#define PCI_SUBSYSTEM_W 0x2E
#define PCI_EXPANSION_ROM_D 0x30
#define PCI_CAP_PTR_B 0x34
#define PCI_INT_LINE_B 0x3C
#define PCI_INT_PIN_B 0x3D
#define PCI_MIN_GRANT_B 0x3E
#define PCI_MAX_LATENCY_B 0x3F
struct PciDevice {
uint8_t bus: 8;
uint8_t device: 5;
uint8_t function: 3;
};
void pci_init(void);
bool pci_findby_class(struct PciDevice *dest, uint8_t class, uint8_t subclass, size_t *offset);
bool pci_findby_id(struct PciDevice *dest, uint16_t device, uint16_t vendor, size_t *offset);
uint32_t pci_rcfg_d(struct PciDevice dev, uint8_t offset);
uint16_t pci_rcfg_w(struct PciDevice dev, uint8_t offset);
uint8_t pci_rcfg_b(struct PciDevice dev, uint8_t offset);
void pci_wcfg_d(struct PciDevice dev, uint8_t offset, uint32_t dword);
void pci_wcfg_w(struct PciDevice dev, uint8_t offset, uint16_t word);
void pci_wcfg_b(struct PciDevice dev, uint8_t offset, uint8_t byte);

View file

@ -1,7 +1,6 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "../term.h"
#include "../panic.h"
#include "../interrupt/pic.h"
#include <string.h>

View file

@ -1,39 +0,0 @@
#include <stdbool.h>
#include <sys.h>
#include "serial.h"
#include "../panic.h"
#define PORT 0x3f8 // COM1
void serial_init(void) {
outb(PORT + 1, 0x00); // Disable all interrupts
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT + 0, 0x01); // Set divisor to 1 (lo byte) 38400 baud
outb(PORT + 1, 0x00); // (hi byte)
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent)
uint8_t response = inb(PORT + 0);
if(response != 0xAE) {
panic("Serial is faulty: %X\n", response);
}
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
outb(PORT + 4, 0x0F);
}
void serial_write(uint8_t a) {
while((inb(PORT + 5) & 0x20) != 0);
outb(PORT, a);
}
void serial_write_s(const char* str) {
while(*str != '\0') {
serial_write(*str++);
}
}

View file

@ -1,7 +0,0 @@
#pragma once
#include <stdint.h>
void serial_init(void);
void serial_write(uint8_t a);
void serial_write_s(const char* str);

59
kernel/fs/fat.c Normal file
View file

@ -0,0 +1,59 @@
#include <string.h>
#include "../term.h"
#include "../panic.h"
#include "fat.h"
bool fat_init(struct FatInfo *fatinfo, struct AtaDevice dev, struct MbrPartition partition) {
uint8_t boot_sector[512] __attribute__((aligned(2)));
if(!ata_read(dev, partition.start_sector, 1, (void*)boot_sector)) return false;
memcpy(&fatinfo->bpb, boot_sector, sizeof(struct FatBpb));
memcpy(&fatinfo->ebpb.f16, boot_sector + sizeof(struct FatBpb), sizeof(struct Fat16Ebpb));
fatinfo->type = FAT16;
fatinfo->dev = dev;
fatinfo->partition = partition;
return true;
}
static int read_dir_entry_sector(struct FatFile *file, struct FatInfo *fatinfo, size_t sector, char* name) {
uint8_t buf[512] __attribute__((aligned(2)));
if(!ata_read(fatinfo->dev, fatinfo->partition.start_sector + sector, 1, (uint16_t*)buf)) panic("read fail");
for(int i = 0; i < 512; i += 32) {
if(buf[i] == 0) return 1; // reached end
if(buf[i] == 0xE5) continue;
if(buf[i+11] == 0x0F) continue;
int j;
for(j = 0; j < 11; j++) {
if(buf[i + j] != name[j]) break;
}
if(j != 11) continue;
memcpy(file->name, &buf[i], 11);
file->start_cluster = buf[i+26] | (buf[i+27] << 8) | (buf[i+20] << 16) | (buf[i+21] << 24);
file->size = buf[i+28] | (buf[i+29] << 8) | (buf[i+30] << 16) | (buf[i+31] << 24);
file->attributes = buf[i+11];
return 0; // found file
}
return 2; // next sector
}
static bool read_dir_entry(struct FatFile *file, struct FatInfo *fatinfo, size_t start_sector, size_t sector_count, char* name) {
for(size_t i = 0; i < sector_count; i++) {
int result = read_dir_entry_sector(file, fatinfo, start_sector + i, name);
if(result == 0) return true;
if(result == 1) break;
// continue if result == 2
}
return false;
}
bool fat_test(struct FatInfo *fatinfo) {
size_t root_start = fatinfo->bpb.reserved_sectors + fatinfo->bpb.fat_count * fatinfo->bpb.sectors_per_fat;
size_t root_sectors = (fatinfo->bpb.root_entries * 32 + 511) / 512;
printf("root start %d sectors %d\n", root_start, root_sectors);
printf("%X\n", root_start * 512);
struct FatFile file;
read_dir_entry(&file, fatinfo, root_start, root_sectors, "FILE3 ");
printf("start: 0x%X\n", file.start_cluster);
printf("size: 0x%X\n", file.size);
printf("attr: 0x%X\n", file.attributes);
return true;
}

72
kernel/fs/fat.h Normal file
View file

@ -0,0 +1,72 @@
#pragma once
#include "mbr.h"
enum FatType {
FAT12,
FAT16,
FAT32,
};
struct FatBpb {
uint8_t _instrs[3];
uint8_t oem_ident[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_16;
uint8_t media_descriptor;
uint16_t sectors_per_fat;
uint16_t sectors_per_track;
uint16_t heads;
uint32_t hidden_sectors;
uint32_t total_sectors_32;
} __attribute__((packed));
struct Fat16Ebpb {
uint8_t drive_number;
uint8_t _reserved;
uint8_t signature;
uint32_t volume_id;
uint8_t volume_label[11];
uint8_t sys_ident[8];
} __attribute__((packed));
struct Fat32Ebpb {
uint32_t sectors_per_fat;
uint16_t flags;
uint16_t version;
uint32_t root_cluster;
uint16_t fsinfo_sector;
uint16_t backup_boot_sector;
uint8_t _reserved0[12];
uint8_t drive_number;
uint8_t _reserved1;
uint8_t signature;
uint32_t serial_number;
uint8_t volume_label[11];
uint8_t system_ident[8];
} __attribute__((packed));
struct FatInfo {
struct MbrPartition partition;
struct AtaDevice dev;
enum FatType type;
struct FatBpb bpb;
union {
struct Fat16Ebpb f16;
struct Fat32Ebpb f32;
} ebpb;
};
struct FatFile {
uint8_t name[11];
uint8_t attributes;
uint32_t start_cluster;
uint32_t size;
};
bool fat_init(struct FatInfo *fatinfo, struct AtaDevice dev, struct MbrPartition partition);
bool fat_test(struct FatInfo *fatinfo);

19
kernel/fs/mbr.c Normal file
View file

@ -0,0 +1,19 @@
#include "mbr.h"
bool mbr_get_partition(struct MbrPartition *dest, struct AtaDevice dev, int n) {
if(n < 0 || n > 3) return false;
uint8_t data[512] __attribute__(( aligned(2) ));
if(!ata_read(dev, 0, 1, (void*)data)) return false;
size_t offset = 0x1BE + n * 0x10;
uint8_t status = data[offset];
if((status & 0x7F) != 0) return false;
dest->n = n;
dest->bootable = status & 0x80 ? true : false;
dest->type = data[offset + 4];
dest->start_sector = data[offset+8] | (data[offset+9] << 8) | (data[offset+10] << 16) | (data[offset+11] << 24);
dest->sector_count = data[offset+12] | (data[offset+13] << 8) | (data[offset+14] << 16) | (data[offset+15] << 24);
return true;
}

17
kernel/fs/mbr.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "../drivers/ata.h"
struct MbrPartition {
uint8_t n;
uint8_t type;
bool bootable;
size_t start_sector;
size_t sector_count;
};
bool mbr_get_partition(struct MbrPartition *dest, struct AtaDevice device, int n);

View file

@ -1,7 +1,7 @@
extern idt_exception_handler
extern idt_pic_timer
extern idt_pic_keyboard
extern idt_pic_generic
extern idt_pic_eoi
global isr_stub_table
%macro ISRErrorStub 1
@ -15,25 +15,25 @@ isr_stub_%+%1:
%macro PICGeneric 1
isr_stub_%+%1:
push dword %1
call idt_pic_generic
call idt_pic_eoi
pop eax
iret
%endmacro
%macro PICTimer 1
isr_stub_%+%1:
push dword %1
call idt_pic_generic
call idt_pic_timer
push dword %1
call idt_pic_eoi
pop eax
iret
%endmacro
%macro PICKeyboard 1
isr_stub_%+%1:
push dword %1
call idt_pic_generic
call idt_pic_keyboard
push dword %1
call idt_pic_eoi
pop eax
iret
%endmacro

View file

@ -13,7 +13,7 @@
static int timer = 0;
void idt_pic_generic(uint8_t exception) {
void idt_pic_eoi(uint8_t exception) {
pic_eoi(exception - PIC_REMAP_OFFSET);
}

View file

@ -1,5 +1,4 @@
#include "pic.h"
#include "../term.h"
#include <sys.h>
#define PIC1_COMMAND_PORT 0x20

View file

@ -1,10 +1,13 @@
#include <sys.h>
#include <stdlib.h>
#include "bootinfo.h"
#include "drivers/ata.h"
#include "drivers/keycodes.h"
#include "drivers/ps2ctrl.h"
#include "drivers/ps2kb.h"
#include "drivers/serial.h"
#include "drivers/pci.h"
#include "fs/fat.h"
#include "fs/mbr.h"
#include "panic.h"
#include "term.h"
#include "interrupt/pic.h"
@ -13,20 +16,27 @@
extern void kmain(void* boot_info) {
term_clear();
term_setcol(0x0f);
puts("loading kernel\n");
bootinfo_load(boot_info);
puts("loaded boot info\n");
printf("cmdline: %s\n", bootinfo_get_cmdline());
idt_init();
puts("initialized idt\n");
pic_remap(PIC_REMAP_OFFSET);
puts("remapped pic\n");
serial_init();
puts("initialized serial\n");
ps2ctrl_init();
puts("enabled ps/2 controller\n");
ps2kb_init();
puts("enabled keyboard\n");
pci_init();
struct PciDevice pcidev;
if(!pci_findby_class(&pcidev, 0x01, 0x01, NULL)) {
panic("Could not find IDE device");
}
struct AtaDevice atadev;
ata_init(&atadev, pcidev);
struct MbrPartition part0;
mbr_get_partition(&part0, atadev, 0);
struct FatInfo fat;
fat_init(&fat, atadev, part0);
fat_test(&fat);
while(1) {
int_wait();

View file

@ -24,8 +24,7 @@ void putc(char c) {
term_x = TERM_W;
break;
case '\t':
if(term_x % 8 == 0) term_x += 8;
term_x += 7 - (term_x % 8);
term_x += 8 - (term_x % 8);
break;
default:
screen_buf[term_x + term_y * TERM_W] = screen_entry(c, color);
@ -115,14 +114,19 @@ void vprintf(const char *fstr, va_list args) {
char buf[80];
for(; *fstr != '\0'; fstr++) {
if(*fstr == '%') {
fstr++;
switch(*fstr) {
switch(*++fstr) {
case '%':
putc('%');
break;
case '@':
putc('@');
break;
case 's':
puts(va_arg(args, char*));
break;
case 'c':
putc(va_arg(args, int));
break;
case 'd':
itoa(va_arg(args, int), buf, 10, false);
puts(buf);
@ -139,15 +143,13 @@ void vprintf(const char *fstr, va_list args) {
utoa(va_arg(args, unsigned int), buf, 16, true);
puts(buf);
break;
case '@': {
uint8_t hi = hex2i(*++fstr);
uint8_t lo = hex2i(*++fstr);
term_setcol((hi << 4) | lo);
break;
}
default:
break;
}
} else if(*fstr == '@') {
uint8_t hi = hex2i(*++fstr);
uint8_t lo = hex2i(*++fstr);
term_setcol((hi << 4) | lo);
} else {
putc(*fstr);
}

7
libk/include/errno.h Normal file
View file

@ -0,0 +1,7 @@
#pragma once
enum {
ESUCCESS,
ENOENTRY,
EDISKFAIL,
};

View file

@ -1,12 +1,51 @@
#include <stdint.h>
#include <stdint.h>
uint8_t inb(uint16_t port);
void outb(uint16_t port, uint8_t val);
void io_wait(void);
static inline uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
void int_enable(void);
void int_disable(void);
void int_wait(void);
static inline void outb(uint16_t port, uint8_t val) {
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}
void halt(void);
static inline uint16_t inw(uint16_t port) {
uint16_t ret;
__asm__ volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void outw(uint16_t port, uint16_t val) {
__asm__ volatile ("outw %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint32_t inl(uint16_t port) {
uint32_t ret;
__asm__ volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void outl(uint16_t port, uint32_t val) {
__asm__ volatile ("outl %0, %1" : : "a"(val), "Nd"(port));
}
static inline void io_wait(void) {
outb(0x80, 0);
}
static inline void int_enable(void) {
__asm__ volatile ("sti");
}
static inline void int_disable(void) {
__asm__ volatile ("cli");
}
static inline void int_wait(void) {
__asm__ volatile ("sti; hlt");
}
static inline void halt(void) {
__asm__ volatile ("cli; hlt");
}

View file

@ -1,31 +0,0 @@
#include <stdint.h>
uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
void outb(uint16_t port, uint8_t val) {
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}
void io_wait(void) {
outb(0x80, 0);
}
void int_enable(void) {
__asm__ volatile ("sti");
}
void int_disable(void) {
__asm__ volatile ("cli");
}
void int_wait(void) {
__asm__ volatile ("sti; hlt");
}
void halt(void) {
__asm__ volatile ("cli; hlt");
}

22
scripts/mkdisk.sh Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh
DISKSIZE_MB=16
DISK=disk.img
OFFSET=1048576
dd if=/dev/zero of="$DISK" bs=1M count="$DISKSIZE_MB"
sfdisk "$DISK" <<EOF
label: dos
label-id: 0x7c295044
device: disk.img
unit: sectors
sector-size: 512
disk.img1 : start= 2048, size= 30720, type=4
EOF
LOOPDEV="$(losetup -f)"
losetup "$LOOPDEV" "$DISK" -o "$OFFSET"
mkfs.fat -F16 "$LOOPDEV"
losetup -D "$DISK"

21
scripts/mount.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh
DISK=disk.img
MOUNTPOINT=mnt
OFFSET=1048576
if [ "$(id -u)" -ne 0 ]; then
echo "must be root"
exit 1
fi
if mountpoint "$MOUNTPOINT" >/dev/null; then
echo "unmounting"
umount "$MOUNTPOINT"
losetup -D "$DISK"
else
echo "mounting"
LOOPDEV="$(losetup -f)"
losetup "$LOOPDEV" "$DISK" -o "$OFFSET"
mount "$LOOPDEV" "$MOUNTPOINT"
fi