diff --git a/kernel/attributes.h b/kernel/attributes.h index 02b18ca..9c01876 100644 --- a/kernel/attributes.h +++ b/kernel/attributes.h @@ -5,6 +5,9 @@ #ifndef NEW_KERNEL_ATTRIBUTES_H #define NEW_KERNEL_ATTRIBUTES_H +// generic +#define used __attribute((used)) + // function #define noreturn __attribute((noreturn)) #define cdecl __attribute((cdecl)) diff --git a/kernel/driver.h b/kernel/driver.h new file mode 100644 index 0000000..e324cca --- /dev/null +++ b/kernel/driver.h @@ -0,0 +1,20 @@ +// +// Created by rick on 06-03-21. +// + +#ifndef NEW_KERNEL_DRIVER_H +#define NEW_KERNEL_DRIVER_H +#include + +#ifndef STRUCT_ALIGNMENT +#define STRUCT_ALIGNMENT 16 +#endif +#define DRIVER_CAT(a, b) DRIVER_DUMMY() a ## _ ## b +#define DRIVER_DUMMY() + +#define GENERIC_DRIVER(drivername, data...) \ + static struct drivername DRIVER_CAT(drivername, __COUNTER__) \ + __attribute((__used__, __section__(#drivername))) \ + = { data } + +#endif //NEW_KERNEL_DRIVER_H diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index 1bd22d8..b24ae6a 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -322,34 +322,6 @@ unsigned char ide_print_error(unsigned int drive, unsigned char err) { return err; } -uint8_t ide_pci_validate(const pci_device *device); - -uint8_t ide_pci_initialize(pci_device *device); - -PCI_DRIVER( - .name = "pci-ide", - .description = "Default PCI IDE Driver", - .order = 0xFF, // let other block_dev_drivers precede if they can - .pci_use_subclass = true, - .validatable = true, - .initialisable = true, - .pci_class = PCI_CLASS_MASS_STORAGE, - .pci_subclass = PCI_SUB_CLASS_IDE, - - .validate = ide_pci_validate, - .initialize = ide_pci_initialize, -); - -uint8_t ide_pci_validate(const pci_device *device) { - if (device->class != PCI_CLASS_MASS_STORAGE - || device->subclass != PCI_SUB_CLASS_IDE - || (device->programInterface != 0x8A && device->programInterface != 0x80)) { - return PCI_VALIDATE_FAIL; - } - // todo other validations - return PCI_VALIDATE_OK; -} - void ide_fix_bar(bar_info *bar, uint32_t default_address, uint32_t size) { if (bar->address == 0x0) { // no need to actually write ti back @@ -365,6 +337,7 @@ bool ide_pci_init_channels(pci_device *device) { pci_config_write_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE, 0xFE); if (pci_config_read_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE) == 0xFE) { #ifdef IDE_ENABLE_INTERRUPT +#error "Interrupt not supported" k_panics("NOT SUPPORTED"); #else pci_config_write_byte(device->bus, device->slot, device->func, PCI_CONFIG_INTERRUPT_LINE, @@ -399,7 +372,8 @@ bool ide_pci_init_channels(pci_device *device) { return true; } -uint8_t ide_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) { +uint8_t +ide_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) { ide_block_device_info *info = device->device_info; uint8_t result = ide_access(direction, info->device_number, lba, sectors, target); if (result != 0) { @@ -436,7 +410,17 @@ void ide_register_block_devices() { } } -uint8_t ide_pci_initialize(pci_device *device) { +uint8_t used ide_pci_validate(const pci_device *device) { + if (device->class != PCI_CLASS_MASS_STORAGE + || device->subclass != PCI_SUB_CLASS_IDE + || (device->programInterface != 0x8A && device->programInterface != 0x80)) { + return PCI_VALIDATE_FAIL; + } + // todo other validations + return PCI_VALIDATE_OK; +} + +uint8_t used ide_pci_initialize(pci_device *device) { if (!ide_pci_init_channels(device)) { return PCI_INIT_FAIL; @@ -686,3 +670,18 @@ uint8_t ide_access(uint8_t direction, uint8_t drive, uint32_t lba, uint8_t numse mutex_release(ide_lock); return result; } + +PCI_DRIVER( + .name = "pci-ide", + .description = "Default PCI IDE Driver", + .order = 0xFF, // let other block_dev_drivers precede if they can + .pci_use_subclass = true, + .validatable = true, + .initialisable = true, + .pci_class = PCI_CLASS_MASS_STORAGE, + .pci_subclass = PCI_SUB_CLASS_IDE, + + .validate = ide_pci_validate, + .initialize = ide_pci_initialize, +); + diff --git a/kernel/drivers/pci.c b/kernel/drivers/pci.c index 6120474..a0c6eac 100644 --- a/kernel/drivers/pci.c +++ b/kernel/drivers/pci.c @@ -46,10 +46,10 @@ const struct pci_driver pci_internal_secondary_bus = { }; //const pci_driver *pci_drivers[MAX_PCI_DRIVERS]; -extern struct pci_driver __start_pci_drivers[]; -extern struct pci_driver __stop_pci_drivers[]; -#define NUM_DRIVERS ((size_t)(__stop_pci_drivers - __start_pci_drivers)) -#define DRIVER(i) ((__start_pci_drivers) + (i)) +extern struct pci_driver __start_pci_driver[]; +extern struct pci_driver __stop_pci_driver[]; +#define NUM_DRIVERS ((size_t)(__stop_pci_driver - __start_pci_driver)) +#define DRIVER(i) ((__start_pci_driver) + (i)) int last_pci_device_index = 0; pci_device pci_devices[MAX_PCI_DEVICES]; @@ -126,18 +126,20 @@ uint8_t pci_get_header_type(uint8_t bus, uint8_t slot, uint8_t func) { void pci_pick_driver(pci_device *device) { // check special drivers // PCI Secondary bus - if (device->class == pci_internal_secondary_bus.pci_class && device->subclass == pci_internal_secondary_bus.pci_subclass) { - uint8_t secondary_bus = pci_config_read_byte(device->bus, device->slot, device->func, PCI_CONFIG_SECONDARY_BUS_NUMBER); + if (device->class == pci_internal_secondary_bus.pci_class && + device->subclass == pci_internal_secondary_bus.pci_subclass) { + uint8_t secondary_bus = pci_config_read_byte(device->bus, device->slot, device->func, + PCI_CONFIG_SECONDARY_BUS_NUMBER); device->pci_driver = &pci_internal_secondary_bus; pci_check_bus(secondary_bus); return; } // use normal drivers - for (int i = 0; i < NUM_DRIVERS; ++i) { -// if (DRIVER(i) == NULL) { -// continue; -// } + for (size_t i = 0; i < NUM_DRIVERS; ++i) { + if (DRIVER(i) == NULL) { + continue; + } if (device->class != DRIVER(i)->pci_class) { continue; } diff --git a/kernel/drivers/pci.h b/kernel/drivers/pci.h index a428e00..ab6052e 100644 --- a/kernel/drivers/pci.h +++ b/kernel/drivers/pci.h @@ -6,6 +6,7 @@ #define NEW_KERNEL_PCI_H #include +#include #include #include @@ -76,14 +77,6 @@ #define PCI_INTERRUPT_LINE_DISABLED 0xff -#ifndef PCI_DRIVER_ALIGNMENT -#if defined(__LP64__) -#define PCI_DRIVER_ALIGNMENT 16 -#else -#define PCI_DRIVER_ALIGNMENT 8 -#endif -#endif - typedef struct pci_device pci_device; typedef uint8_t (*pci_driver_validate)(const pci_device *); @@ -103,16 +96,9 @@ struct pci_driver { }; pci_driver_validate validate; pci_driver_initialize initialize; -} __attribute__((__aligned__(PCI_DRIVER_ALIGNMENT))); +} __attribute__((__aligned__(STRUCT_ALIGNMENT))); -#define PCI_DRIVER_NAME(counter) DRIVER_CAT(pci_driver_, counter) -#define DRIVER_CAT(a, b) DRIVER_DUMMY() a ## b -#define DRIVER_DUMMY() - -#define PCI_DRIVER(data...) \ - static struct pci_driver PCI_DRIVER_NAME(__COUNTER__) \ - __attribute((__used__, __section__("pci_drivers"))) \ - = { data } +#define PCI_DRIVER(data...) GENERIC_DRIVER(pci_driver, data) typedef struct { uint32_t address; diff --git a/kernel/fs/blockdev.c b/kernel/fs/blockdev.c index 964995c..5712746 100644 --- a/kernel/fs/blockdev.c +++ b/kernel/fs/blockdev.c @@ -12,34 +12,28 @@ #include "blockdev.h" #define MAX_BLOCK_DEVS 64 -#define MAX_BLOCK_DRIVERS 64 int last_block_dev = 0; -block_device block_devices[MAX_BLOCK_DEVS]; -int last_block_driver = 0; -block_dev_driver block_dev_drivers[MAX_BLOCK_DRIVERS]; +block_device block_devices[MAX_BLOCK_DEVS] = {0}; + +extern struct block_dev_driver __start_block_dev_driver[]; +extern struct block_dev_driver __stop_block_dev_driver[]; +#define NUM_DRIVERS ((size_t)(__stop_block_dev_driver - __start_block_dev_driver)) +#define DRIVER(i) ((__start_block_dev_driver) + (i)) + semaphore_t *block_semaphore; bool blockdev_task_running = false; -uint8_t block_dev_register_driver(block_dev_driver *driver) { - if (last_block_dev >= MAX_BLOCK_DEVS - 1) { - return BLOCK_DEV_REGISTER_DRIVER_FULL; - } - - memcpy((uint8_t *) &block_dev_drivers[last_block_driver++], (const uint8_t *) driver, sizeof(block_dev_driver)); - return BLOCK_DEV_REGISTER_DRIVER_OK; -} - uint8_t block_dev_register(block_device *device) { if (last_block_dev >= MAX_BLOCK_DEVS - 1) { return BLOCK_DEV_REGISTER_FULL; } + memcpy((uint8_t *) &block_devices[last_block_dev++], (const uint8_t *) device, sizeof(block_device)); + if (blockdev_task_running) { semaphore_signal(block_semaphore); } - - memcpy((uint8_t *) &block_devices[last_block_dev++], (const uint8_t *) device, sizeof(block_device)); return BLOCK_DEV_REGISTER_OK; } @@ -66,15 +60,15 @@ void block_dev_scan() { block_devices[i].flags.unreadable = 1; goto _block_dev_scan_free; } - for (int j = 0; j < last_block_driver; ++j) { + for (size_t j = 0; j < NUM_DRIVERS; ++j) { // validate if driver is appropriate at all // don't use a root device driver (i.e. mbr) for a non-root device - if (block_dev_drivers[j].flags.root_only && !block_devices[i].flags.root_device) continue; + if (DRIVER(j)->flags.root_only && !block_devices[i].flags.root_device) continue; // let the driver test the disk - uint8_t driver_result = block_dev_drivers[j].check_device(&block_devices[i], lba0); + uint8_t driver_result = DRIVER(j)->check_device(&block_devices[i], lba0); if (driver_result == BLOCK_DEV_DRIVER_CHECK_OK) { - block_devices[i].driver = &block_dev_drivers[j]; + block_devices[i].driver = DRIVER(j); block_devices[i].flags.driver_installed = 1; break; } diff --git a/kernel/fs/blockdev.h b/kernel/fs/blockdev.h index 8cc68d6..1e18af6 100644 --- a/kernel/fs/blockdev.h +++ b/kernel/fs/blockdev.h @@ -6,6 +6,7 @@ #define NEW_KERNEL_BLOCKDEV_H #include +#include #define BLOCK_DEV_ACCESS_OK 0 #define BLOCK_DEV_ACCESS_ERR 1 @@ -31,15 +32,16 @@ typedef uint8_t (*block_device_driver_free)(const block_device *device); typedef uint8_t (*block_device_access)(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target); - -typedef struct { +struct block_dev_driver { char name[16]; struct { uint8_t root_only: 1; } flags; block_device_driver_check_device check_device; block_device_driver_free free_device; -} block_dev_driver; +} __attribute__((__aligned__(STRUCT_ALIGNMENT))); + +#define BLOCK_DEV_DRIVER(data...) GENERIC_DRIVER(block_dev_driver, data) typedef struct block_device { struct { @@ -53,13 +55,11 @@ typedef struct block_device { uint32_t num_lba; uint16_t block_size; block_device_access access; - block_dev_driver *driver; + struct block_dev_driver *driver; void *device_info; // pointer to driver defined structure // todo device info } block_device; -uint8_t block_dev_register_driver(block_dev_driver *driver); - uint8_t block_dev_register(block_device *device); void block_dev_free(block_device *device); diff --git a/kernel/fs/fat.c b/kernel/fs/fat.c index 74bcd19..a594e68 100644 --- a/kernel/fs/fat.c +++ b/kernel/fs/fat.c @@ -101,18 +101,6 @@ typedef struct { }; } packed fat_directory_entry; -uint8_t fat_check_device(const block_device *device, uint8_t *first_sector); - -block_dev_driver fat_driver = { - .name = "fat", - .check_device = fat_check_device, - .free_device = NULL, // todo -}; - -void fat_register_block_driver() { - block_dev_register_driver(&fat_driver); -} - void print_chars(char *chars, int amount) { for (int i = 0; i < amount; ++i) { if (chars[i] == 0) break; @@ -120,7 +108,7 @@ void print_chars(char *chars, int amount) { } } -uint8_t fat_check_device(const block_device *device, uint8_t *first_sector) { +uint8_t used fat_check_device(const block_device *device, uint8_t *first_sector) { fat_bpb bpb; memcpy((uint8_t *) &bpb, first_sector, sizeof(fat_bpb)); if (bpb.bpb.sectors_per_fat == 0 || bpb.bpb.sectors_per_cluster == 0) { @@ -205,5 +193,10 @@ get_fat_table_value(uint8_t fat_type, const uint8_t *fat_table, uint32_t active_ return result; } +BLOCK_DEV_DRIVER( + .name = "fat", + .check_device = fat_check_device, + .free_device = NULL, // todo +); // steal validation code from here https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/fs/fat/inode.c#L1456 \ No newline at end of file diff --git a/kernel/fs/fat.h b/kernel/fs/fat.h index 73d5eaf..c01a75b 100644 --- a/kernel/fs/fat.h +++ b/kernel/fs/fat.h @@ -5,6 +5,4 @@ #ifndef NEW_KERNEL_FAT_H #define NEW_KERNEL_FAT_H -void fat_register_block_driver(); - #endif //NEW_KERNEL_FAT_H diff --git a/kernel/fs/mbr.c b/kernel/fs/mbr.c index 28a784d..82e43e9 100644 --- a/kernel/fs/mbr.c +++ b/kernel/fs/mbr.c @@ -36,19 +36,6 @@ typedef struct { uint32_t start_lba; } mbr_block_driver_info; -uint8_t mbr_check_device(const block_device *device, uint8_t *first_sector); - -block_dev_driver mbr_driver = { - .name = "mbr", - .flags.root_only = 1, - .check_device = mbr_check_device, - .free_device = NULL, // todo -}; - -void mbr_register_block_driver() { - block_dev_register_driver(&mbr_driver); -} - uint8_t mbr_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) { if (!device->flags.present || lba > device->num_lba) { return BLOCK_DEV_ACCESS_ERR; @@ -63,7 +50,7 @@ uint8_t mbr_block_dev_access(const block_device *device, uint8_t direction, uint return info->device->access(info->device, direction, actual_lba, sectors, target); } -uint8_t mbr_check_device(const block_device *device, uint8_t *first_sector) { +uint8_t used mbr_check_device(const block_device *device, uint8_t *first_sector) { mbr_table table; memcpy((uint8_t *) &table, first_sector + (device->block_size - sizeof(mbr_table)), sizeof(mbr_table)); if (table.signature[0] != 0x55 && table.signature[1] != 0xAA) { // AA 55 but in little endian @@ -111,4 +98,11 @@ void mbr_read_from_ide(uint8_t ide_drive) { mbr_partition_table_entry *entry = (mbr_partition_table_entry *) (mbr_data + 0x1BE); printf("Start at %d, count: %d\n", entry->start_lba, entry->num_lbas); free(mbr_data); -} \ No newline at end of file +} + +BLOCK_DEV_DRIVER( + .name = "mbr", + .flags.root_only = 1, + .check_device = mbr_check_device, + .free_device = NULL, // todo +); diff --git a/kernel/fs/mbr.h b/kernel/fs/mbr.h index aeeca4c..1fbc29b 100644 --- a/kernel/fs/mbr.h +++ b/kernel/fs/mbr.h @@ -7,8 +7,6 @@ #include -void mbr_register_block_driver(); - void mbr_read_from_ide(uint8_t ide_drive); #endif //NEW_KERNEL_MBR_H diff --git a/kernel/kernel.c b/kernel/kernel.c index a517381..17a3ebf 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -8,11 +8,8 @@ #include #include #include -#include #include -#include #include -#include #include #include #include @@ -38,13 +35,7 @@ void init_pci_system() { pci_init_drivers(); } -void init_block_devices() { - // register drivers - mbr_register_block_driver(); - fat_register_block_driver(); -} - -void noreturn kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) { +void noreturn used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) { // early init isr_install(); vga_clear_screen(); @@ -77,9 +68,6 @@ void noreturn kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) { init_keyboard(); init_pci_system(); - // register block device drivers - init_block_devices(); - printf("Booted successfully v%d.%d.%d\n", version_major, version_minor, version_patch); // initialize tasking diff --git a/linker.ld b/linker.ld index 37d9276..60634c4 100644 --- a/linker.ld +++ b/linker.ld @@ -29,10 +29,15 @@ SECTIONS /* Read-write data (initialized) */ .data BLOCK(4K) : ALIGN(4K) { - __start_pci_drivers = .; - *(pci_drivers) - __stop_pci_drivers = .; *(.data) + . = ALIGN(16); + __start_pci_driver = .; + *(pci_driver) + __stop_pci_driver = .; + . = ALIGN(16); + __start_block_dev_driver = .; + *(block_dev_driver) + __stop_block_dev_driver = .; } /* Read-write data (uninitialized) and stack */