feat: reformatted driver code and linkage. Some optimizations
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define NEW_KERNEL_BLOCKDEV_H
|
||||
|
||||
#include <types.h>
|
||||
#include <driver.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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
|
||||
@@ -5,6 +5,4 @@
|
||||
#ifndef NEW_KERNEL_FAT_H
|
||||
#define NEW_KERNEL_FAT_H
|
||||
|
||||
void fat_register_block_driver();
|
||||
|
||||
#endif //NEW_KERNEL_FAT_H
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
BLOCK_DEV_DRIVER(
|
||||
.name = "mbr",
|
||||
.flags.root_only = 1,
|
||||
.check_device = mbr_check_device,
|
||||
.free_device = NULL, // todo
|
||||
);
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
|
||||
#include <types.h>
|
||||
|
||||
void mbr_register_block_driver();
|
||||
|
||||
void mbr_read_from_ide(uint8_t ide_drive);
|
||||
|
||||
#endif //NEW_KERNEL_MBR_H
|
||||
|
||||
Reference in New Issue
Block a user