feat: implemented errno, strtol. Started ustar. Reformatted headers and

code. Added some self-tests. Started prepwork for vfs.
This commit is contained in:
2021-03-14 21:14:22 +01:00
parent 586b8191b4
commit 77c8dca72a
39 changed files with 504 additions and 60 deletions

View File

@@ -27,6 +27,7 @@ add_compile_definitions(__kernel__)
# Run IDE in DMA mode if available (NYI)
#add_compile_definitions(IDE_ENABLE_INTERRUPT)
# Run the kernel shell as the main task
add_compile_definitions(ENABLE_SELF_TEST) # Support for pretty printing pci class/subclass/interface
add_compile_definitions(ENABLE_PCIPP) # Support for pretty printing pci class/subclass/interface
add_compile_definitions(K_SHELL)

View File

@@ -68,6 +68,6 @@ struct elf32_symtab_entry {
uint8_t st_info;
uint8_t st_other;
uint16_t st_shndx;
};
} packed;
#endif //NEW_KERNEL_ELF_H

View File

@@ -5,4 +5,41 @@
#ifndef NEW_KERNEL_ERRNO_H
#define NEW_KERNEL_ERRNO_H
extern int errno;
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#endif //NEW_KERNEL_ERRNO_H

View File

@@ -4,6 +4,7 @@
#ifndef NEW_KERNEL_CPU_H
#define NEW_KERNEL_CPU_H
#include <sys/types.h>
typedef struct {

View File

@@ -5,6 +5,7 @@
#ifndef MY_KERNEL_IDT_H
#define MY_KERNEL_IDT_H
#include <myke/attributes.h>
#define KERNEL_CS 0x08

View File

@@ -4,6 +4,7 @@
#ifndef NEW_KERNEL_SYSCALL_HANDLER_H
#define NEW_KERNEL_SYSCALL_HANDLER_H
#include <myke/cpu/cpu.h>
void syscall_handle(isr_registers_t *registers);

View File

@@ -8,9 +8,17 @@
#include <stdbool.h>
#ifdef DEBUG_INIT
#include <multiboot.h>
void debug_store_info(struct multiboot_info *info);
#endif
#ifdef ENABLE_SELF_TEST
void self_test();
#endif
void debug_backtrace(bool do_sync);

View File

@@ -4,6 +4,7 @@
#ifndef NEW_KERNEL_DRIVER_H
#define NEW_KERNEL_DRIVER_H
#include <myke/attributes.h>
#include <myke/preprocessor_format_zero.h>

View File

@@ -5,6 +5,7 @@
#ifndef NEW_KERNEL_BLOCKDEV_H
#define NEW_KERNEL_BLOCKDEV_H
#include <stdbool.h>
#include <sys/types.h>
#include <myke/driver.h>
@@ -24,18 +25,19 @@
#define BLOCK_DEV_REGISTER_FULL 1
typedef struct block_device block_device;
typedef struct block_device block_device_t;
typedef uint8_t (*block_device_driver_check_device)(const block_device *device, uint8_t *first_sector);
typedef uint8_t (*block_device_driver_check_device)(const block_device_t *device, uint8_t *first_sector);
typedef uint8_t (*block_device_driver_free)(const block_device *device);
typedef uint8_t (*block_device_driver_free)(const block_device_t *device);
typedef uint8_t (*block_device_access)(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target);
typedef uint8_t (*block_device_access)(const block_device_t *device, uint8_t direction, uint32_t lba, uint8_t sectors,
void *target);
struct block_dev_driver {
char name[16];
struct {
uint8_t root_only: 1;
uint8_t partitioning: 1;
} flags;
block_device_driver_check_device check_device;
block_device_driver_free free_device;
@@ -43,7 +45,7 @@ struct block_dev_driver {
#define BLOCK_DEV_DRIVER(order) GENERIC_DRIVER(block_dev_driver, order)
typedef struct block_device {
struct block_device {
struct {
uint8_t present: 1;
uint8_t scanned: 1;
@@ -58,14 +60,16 @@ typedef struct block_device {
struct block_dev_driver *driver;
void *device_info; // pointer to driver defined structure
// todo device info
} block_device;
};
uint8_t block_dev_register(block_device *device);
uint8_t block_dev_register(block_device_t *device);
void block_dev_free(block_device *device);
void block_dev_free(block_device_t *device);
void block_dev_start_task();
void block_dev_print_info();
bool block_dev_mount(char *identifier, char *driver);
#endif //NEW_KERNEL_BLOCKDEV_H

View File

@@ -4,6 +4,7 @@
#ifndef NEW_KERNEL_LIBK_H
#define NEW_KERNEL_LIBK_H
#include <myke/attributes.h>
#include <stdbool.h>

View File

@@ -4,6 +4,7 @@
#ifndef NEW_KERNEL_SYSCALL_H
#define NEW_KERNEL_SYSCALL_H
#include <sys/types.h>
#include <myke/attributes.h>

View File

@@ -16,7 +16,9 @@ void *calloc(size_t, size_t);
void free(void *);
#ifndef INCLUDE_STDLIB
void print_malloc_info();
#endif
#endif //NEW_KERNEL_MALLOC_H

View File

@@ -4,13 +4,16 @@
#ifndef NEW_KERNEL_PMM_H
#define NEW_KERNEL_PMM_H
#include <sys/types.h>
// 4k blocks
#define PAGE_SIZE 4096
void pmm_init(void *start_addr, size_t size);
void *pmm_get_pages(uint32_t num_pages);
void pmm_free_pages(void *page, uint32_t num_pages);
#endif //NEW_KERNEL_PMM_H

View File

@@ -4,6 +4,7 @@
#ifndef NEW_KERNEL_POWER_H
#define NEW_KERNEL_POWER_H
#include <myke/attributes.h>
void noreturn power_shutdown();

View File

@@ -33,4 +33,6 @@ long long llabs(long long val);
void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *));
long strtol(const char *nptr, char **endptr, int base);
#endif //NEW_KERNEL_STDLIB_H

View File

@@ -11,7 +11,7 @@ int memcpy(void *dst, const void *src, size_t amount);
int memset(void *dst, int data, size_t amount);
int strcpy(char *dst, char *src);
int strcpy(char *dst, const char *src);
size_t strlen(const char *str);

View File

@@ -4,10 +4,13 @@
#ifndef NEW_KERNEL_UNISTD_H
#define NEW_KERNEL_UNISTD_H
#include <sys/types.h>
int execv(const char *, char *const[]);
int execve(const char *, char *const[], char *const[]);
int execvp(const char *, char *const[]);
pid_t fork(void);

View File

@@ -11,14 +11,20 @@
#include <myke/mem/mem.h>
#include <myke/mem/malloc.h>
#include <myke/cpu/timer.h>
#include <myke/drivers/pci.h>
#include <myke/drivers/ide.h>
#include <myke/drivers/pci/pci.h>
#include <myke/drivers/pci/ide.h>
#include <myke/fs/blockdev.h>
#include <myke/fs/mbr.h>
#include <readline/readline.h>
#include <myke/attributes.h>
#include <myke/util/power.h>
#ifdef ENABLE_SELF_TEST
#include <myke/debug/debug.h>
#endif
#define BOOTLOADER_NAME_MAX_LENGTH 64
#define CMDLINE_MAX_LENGTH 256
@@ -44,16 +50,29 @@ void shutdown(const char *args);
void explode(const char *args);
#ifdef ENABLE_SELF_TEST
void exec_self_test(const char *args);
#endif
cmd_handler cmd_handlers[] = {
{"help\0", help},
{"echo\0", echo},
{"print\0", print},
{"ide\0", ide},
{"help", help},
{"echo", echo},
{"print", print},
{"ide", ide},
{"shutdown", shutdown},
{"explode", explode},
#ifdef ENABLE_SELF_TEST
{"self-test", exec_self_test},
#endif
{NULL, NULL},
};
void exec_self_test(const char *args) {
self_test();
}
void explode(const char *args) {
uint32_t x = 0;

View File

@@ -8,7 +8,7 @@
#define DEBUG_INIT
#include <myke/debug/debug.h>
#include <myke/elf.h>
#include <elf.h>
#include <myke/libk/libk.h>
#include <myke/libk/kprint.h>

152
kernel/debug/self_test.c Normal file
View File

@@ -0,0 +1,152 @@
//
// Created by rick on 13-03-21.
//
#ifdef ENABLE_SELF_TEST
#include <myke/debug/debug.h>
#include <string.h>
#include <stdlib.h>
#include <myke/libk/libk.h>
#include <errno.h>
void assert_int(int expected, int actual) {
if (expected != actual) {
debug_backtrace(true);
k_panics("Assertion failed, integers not equal\n");
}
}
void assert_long(long expected, long actual) {
if (expected != actual) {
debug_backtrace(true);
k_panics("Assertion failed, integers not equal\n");
}
}
void assert_long_long(long long expected, long long actual) {
if (expected != actual) {
debug_backtrace(true);
k_panics("Assertion failed, integers not equal\n");
}
}
void assert_ptr(const void *expected, const void *actual) {
if (expected != actual) {
debug_backtrace(true);
k_panics("Assertion failed, integers not equal\n");
}
}
void assert_array_equal(const uint8_t *a, const uint8_t *b, size_t size) {
for (size_t i = 0; i < size; ++i) {
if (a[i] != b[i]) {
debug_backtrace(true);
k_panics("Assertion failed, arrays differ\n");
}
}
}
void assert_array_all_entries(const uint8_t *a, uint8_t value, size_t size) {
for (size_t i = 0; i < size; ++i) {
if (a[i] != value) {
debug_backtrace(true);
k_panics("Assertion failed, arrays differ\n");
}
}
}
void test_string() {
// test strncmp
assert_int(0, strncmp("abc", "abc", 3));
assert_int(1, strncmp("abcd", "abc", 4));
assert_int(-1, strncmp("abc", "abcd", 4));
// test strcmp
assert_int(0, strcmp("abc", "abc"));
assert_int(1, strcmp("abc", "abd"));
assert_int(-1, strcmp("abc", "abb"));
assert_int(-1, strcmp("abc", "abcd"));
assert_int(1, strcmp("abcd", "abc"));
uint8_t array_a[8] = {0};
uint8_t array_b[16] = {0};
// memset
assert_array_all_entries(array_b, 0, 16);
memset(array_b, 1, 8);
assert_array_all_entries(array_b, 1, 8);
assert_array_all_entries(array_b + 8, 0, 8);
memset(array_b, 1, 16);
assert_array_all_entries(array_b, 1, 16);
// memcpy
memcpy(array_b, array_a, 8);
assert_array_all_entries(array_b, 0, 8);
assert_array_all_entries(array_b + 8, 1, 8);
memcpy(array_b + 8, array_a, 8);
assert_array_all_entries(array_b + 8, 0, 16);
// strlen
assert_int(3, strlen("abc"));
assert_int(4, strlen("abcd"));
assert_int(5, strlen("abcde"));
assert_int(0, strlen(""));
// strchr
const char *strchr_test = "abcdef";
assert_ptr(&strchr_test[3], strchr(strchr_test, 'd'));
assert_ptr(NULL, strchr(strchr_test, '9'));
// strcpy
const char *strcpy_src_test = "abc\0def";
char *strcpy_dst_test = "\0\0\0\0\0\0\0";
const char *strcpy_expected_test = "abc\0\0\0\0";
assert_int(0, strcpy(strcpy_dst_test, strcpy_src_test));
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpointer-sign"
assert_array_equal(strcpy_dst_test, strcpy_expected_test, 8);
#pragma clang diagnostic pop
}
void test_stdlib() {
// abs
assert_int(1, abs(1));
assert_int(1, abs(-1));
assert_int(0, abs(0));
assert_int(0, abs(-0));
// labs
assert_long(1l, labs(1l));
assert_long(1l, labs(-1l));
assert_long(0l, labs(0l));
assert_long(0l, labs(-0l));
// llabs
assert_long_long(1ll, llabs(1ll));
assert_long_long(1ll, llabs(-1ll));
assert_long_long(0ll, llabs(0ll));
assert_long_long(0ll, llabs(-0ll));
assert_long(10, strtol("10", NULL, 10));
assert_long(-10, strtol("-10", NULL, 10));
assert_long(16, strtol("10", NULL, 16));
assert_long(-16, strtol("-10", NULL, 16));
assert_long(8, strtol("10", NULL, 8));
assert_long(-8, strtol("-10", NULL, 8));
assert_long(8, strtol("010", NULL, 8));
assert_long(-8, strtol("-010", NULL, 8));
assert_long(200, strtol("5K", NULL, 36));
assert_long(-200, strtol("-5K", NULL, 36));
assert_long(-200, strtol("-5k", NULL, 36));
errno = 0;
assert_long(-1, strtol("A", NULL, 10));
assert_int(errno, EINVAL);
}
void self_test() {
test_string();
test_stdlib();
}
#endif

View File

@@ -8,11 +8,11 @@
#include <sys/types.h>
#include <stdio.h>
#include <myke/drivers/ide.h>
#include <myke/drivers/pci/ide.h>
#include <myke/debug/debug.h>
#include <myke/drivers/ports.h>
#include <myke/libk/kprint.h>
#include <myke/drivers/pci.h>
#include <myke/drivers/pci/pci.h>
#include <myke/libk/libk.h>
#include <myke/cpu/timer.h>
#include <myke/fs/blockdev.h>
@@ -377,7 +377,7 @@ bool ide_pci_init_channels(pci_device *device) {
}
uint8_t
ide_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) {
ide_block_dev_access(const block_device_t *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) {
@@ -399,7 +399,7 @@ void ide_register_block_devices() {
info->device_number = i;
info->print_error = 1;
block_device device = {
block_device_t device = {
.flags.present = 1,
.flags.root_device = 1,
.device_info = info,

View File

@@ -6,13 +6,13 @@
#include <sys/types.h>
#include <stdio.h>
#include <myke/drivers/pci.h>
#include <myke/drivers/pci/pci.h>
#include <myke/drivers/ports.h>
#include <myke/libk/libk.h>
#ifdef ENABLE_PCIPP
#include <myke/drivers/pci_devices.h>
#include <myke/drivers/pci/pci_devices.h>
#endif

View File

@@ -15,7 +15,7 @@
#define MAX_BLOCK_DEVS 64
int last_block_dev = 0;
block_device block_devices[MAX_BLOCK_DEVS] = {0};
block_device_t block_devices[MAX_BLOCK_DEVS] = {0};
extern struct block_dev_driver __start_block_dev_driver[];
extern struct block_dev_driver __stop_block_dev_driver[];
@@ -25,12 +25,12 @@ extern struct block_dev_driver __stop_block_dev_driver[];
semaphore_t *block_semaphore;
bool blockdev_task_running = false;
uint8_t block_dev_register(block_device *device) {
uint8_t block_dev_register(block_device_t *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));
memcpy((uint8_t *) &block_devices[last_block_dev++], (const uint8_t *) device, sizeof(block_device_t));
if (blockdev_task_running) {
semaphore_signal(block_semaphore);
@@ -38,7 +38,7 @@ uint8_t block_dev_register(block_device *device) {
return BLOCK_DEV_REGISTER_OK;
}
void block_dev_free(block_device *device) {
void block_dev_free(block_device_t *device) {
//todo
k_panics("block dev free not supported");
}
@@ -51,6 +51,43 @@ int block_dev_num_not_scanned() {
return not_scanned;
}
bool block_dev_mount(char *identifier, char *driver_name) {
bool result = true;
block_device_t *device = NULL;
for (int i = 0; i < last_block_dev; ++i) {
if (strncmp(block_devices[i].identifier, identifier, 16) == 0) {
device = &block_devices[i];
}
}
if (identifier == NULL) {
result = false;
goto _end;
}
struct block_dev_driver *driver = NULL;
for (size_t j = 0; j < NUM_DRIVERS; ++j) {
if (strncmp(DRIVER(j)->name, driver_name, 16) == 0) {
driver = DRIVER(j);
}
}
if (driver == NULL) {
result = false;
goto _end;
}
uint8_t *lba0 = malloc(device->block_size);
uint8_t read_result = device->access(device, BLOCK_DEV_DIRECTION_READ, 0, 1, lba0);
if (read_result != BLOCK_DEV_ACCESS_OK) {
result = false;
goto _access_fail;
}
if (driver->check_device(device, lba0) != BLOCK_DEV_DRIVER_CHECK_OK) {
result = false;
}
_access_fail:
free(lba0);
_end:
return result;
}
void block_dev_scan() {
int c_last_block_dev = last_block_dev;
for (int i = 0; i < c_last_block_dev; ++i) {
@@ -62,9 +99,14 @@ void block_dev_scan() {
goto _block_dev_scan_free;
}
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 (DRIVER(j)->flags.root_only && !block_devices[i].flags.root_device) continue;
// only partitioning drivers are automatically assigned
if (!DRIVER(i)->flags.partitioning) {
continue;
}
// only root devices have partitions
if (!block_devices[i].flags.root_device) {
continue;
}
// let the driver test the disk
uint8_t driver_result = DRIVER(j)->check_device(&block_devices[i], lba0);

View File

@@ -107,7 +107,7 @@ void print_chars(char *chars, int amount) {
}
}
uint8_t used fat_check_device(const block_device *device, uint8_t *first_sector) {
uint8_t used fat_check_device(const block_device_t *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) {

View File

@@ -8,7 +8,7 @@
#include <sys/types.h>
#include <myke/fs/mbr.h>
#include <myke/drivers/ide.h>
#include <myke/drivers/pci/ide.h>
#include <myke/fs/blockdev.h>
#include <myke/attributes.h>
@@ -33,12 +33,12 @@ typedef struct {
} packed mbr_table;
typedef struct {
const block_device *device;
const block_device_t *device;
uint32_t start_lba;
} mbr_block_driver_info;
uint8_t
mbr_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba, uint8_t sectors, void *target) {
mbr_block_dev_access(const block_device_t *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;
}
@@ -52,7 +52,7 @@ mbr_block_dev_access(const block_device *device, uint8_t direction, uint32_t lba
return info->device->access(info->device, direction, actual_lba, sectors, target);
}
uint8_t used mbr_check_device(const block_device *device, uint8_t *first_sector) {
uint8_t used mbr_check_device(const block_device_t *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
@@ -69,14 +69,16 @@ uint8_t used mbr_check_device(const block_device *device, uint8_t *first_sector)
}
}
int num_parts = 0;
for (int i = 0; i < 4; ++i) {
if (table.entries[i].system_id == 0) continue;
num_parts += 1;
mbr_block_driver_info *info = malloc(sizeof(mbr_block_driver_info));
info->device = device;
info->start_lba = table.entries[i].start_lba;
block_device logical_device = {
block_device_t logical_device = {
.flags.present = 1,
.num_lba = table.entries[i].num_lbas,
@@ -88,7 +90,10 @@ uint8_t used mbr_check_device(const block_device *device, uint8_t *first_sector)
sprintf(logical_device.identifier, "%sp%d", device->identifier, i);
block_dev_register(&logical_device);
}
if (num_parts == 0) {
return BLOCK_DEV_DRIVER_CHECK_NO_MATCH;
}
return BLOCK_DEV_DRIVER_CHECK_OK;
@@ -104,7 +109,7 @@ void mbr_read_from_ide(uint8_t ide_drive) {
BLOCK_DEV_DRIVER(200) = {
.name = "mbr",
.flags.root_only = 1,
.flags.partitioning = 1,
.check_device = mbr_check_device,
.free_device = NULL, // todo
};

96
kernel/fs/ustar.c Normal file
View File

@@ -0,0 +1,96 @@
//
// Created by rick on 11-03-21.
//
#include <sys/types.h>
#include <myke/fs/blockdev.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct {
char filename[100];
uint64_t mode;
uint64_t uid;
uint64_t gid;
char filesize[12];
char lastmod[12];
uint64_t checksum;
char type;
char linked[100];
char magic[6];
char version[2];
char username[32];
char groupname[32];
uint64_t device_major;
uint64_t device_minor;
char prefix[155];
} packed ustar_sector;
typedef struct {
ustar_sector sector;
uint32_t lba;
} ustar_inode;
typedef struct {
ustar_inode *first_inode;
const block_device_t *device;
} ustar_fs;
const char *ustar_magic = "ustar";
const char *ustar_version = "00";
#define USTAR_TYPE_FILE '0'
#define USTAR_TYPE_LINK '1'
#define USTAR_TYPE_SYMBOL '2'
#define USTAR_TYPE_CHAR '3'
#define USTAR_TYPE_BLOCK '4'
#define USTAR_TYPE_DIR '5'
#define USTAR_TYPE_FIFO '6'
#define SECTOR_SIZE 512
long ustar_oct_to_long(char *oct, uint32_t size) {
char value[size + 1];
memcpy(value, oct, size);
value[size] = 0;
return strtol(value, NULL, 8);
}
bool ustar_sector_valid(ustar_sector *sector) {
return strncmp(ustar_magic, sector->magic, 6) == 0;
}
ustar_sector *ustar_next(ustar_sector *current) {
if (ustar_sector_valid(current)) {
return NULL;
}
long filesize = ustar_oct_to_long(current->filesize, 12);
long offset = (((filesize + SECTOR_SIZE - 1) / SECTOR_SIZE) + 1) * SECTOR_SIZE;
ustar_sector *next = ((void *) current) + offset;
return ustar_sector_valid(next) ? next : NULL;
}
uint8_t ustar_check_device(const block_device_t *device, uint8_t *first_sector) {
ustar_sector *sector = (ustar_sector *) first_sector;
if (!ustar_sector_valid(sector)) {
return BLOCK_DEV_DRIVER_CHECK_NO_MATCH;
}
ustar_fs *fs = malloc(sizeof(ustar_fs));
fs->first_inode = malloc(sizeof(ustar_inode));
memcpy(&fs->first_inode->sector, first_sector, sizeof(ustar_sector));
fs->first_inode->lba = 0;
fs->device = device;
return BLOCK_DEV_DRIVER_CHECK_OK;
}
BLOCK_DEV_DRIVER(300) = {
.name = "ustar",
.check_device = ustar_check_device,
.free_device = NULL,
};

View File

@@ -8,7 +8,7 @@
#include <myke/cpu/timer.h>
#include <myke/debug/debug.h>
#include <myke/drivers/keyboard.h>
#include <myke/drivers/pci.h>
#include <myke/drivers/pci/pci.h>
#include <myke/drivers/serial.h>
#include <myke/drivers/vgascreen.h>
#include <myke/fs/blockdev.h>

View File

@@ -6,6 +6,8 @@
*/
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
/* everything of stdlib is implemented in this file except for:
* - qsort
@@ -76,3 +78,57 @@ char *itoa(int value, char *buffer, int base) {
// reverse the string and return it
return reverse(buffer, 0, i - 1);
}
long strtol(const char *nptr, char **endptr, int base) {
if (base > 36) {
errno = EINVAL;
return -1;
}
char sign = '+';
long n = 0;
long i;
const char *c = nptr;
while (*c == ' ') {
c++;
}
if (*c == '+') {
c++;
} else if (*c == '-') {
sign = '-';
c++;
}
while (*c != '\0') {
n *= base;
if (*c >= '0' && *c <= '9') {
i = *c - '0';
} else if (*c >= 'a' && *c <= 'z') {
i = *c - 'a' + 10;
} else if (*c >= 'A' && *c <= 'Z') {
i = *c - 'A' + 10;
} else {
errno = EINVAL;
n = -1;
goto _set_endptr;
}
if (i >= base) {
errno = EINVAL;
n = -1;
goto _set_endptr;
}
if (i > (LONG_MAX - n)) {
errno = ERANGE;
n = sign == '-' ? LONG_MIN : LONG_MAX;
goto _set_endptr;
}
n += i;
c++;
}
if (sign == '-') {
n *= -1;
}
_set_endptr:
if (endptr != NULL) {
*endptr = c;
}
return n;
}

View File

@@ -20,7 +20,7 @@ int memset(void *dst, int data, size_t amount) {
}
int strcpy(char *dst, char *src) {
int strcpy(char *dst, const char *src) {
return memcpy(dst, src, strlen(src) + 1);
}

View File

@@ -23,6 +23,7 @@
#define TASK_STATE_STOPPED (1 << 6)
#define TASK_STATE_ERROR (1 << 7)
int errno = 0;
typedef struct task {
bool present: 1;
@@ -31,6 +32,8 @@ typedef struct task {
uint32_t tid;
int errno;
struct task *next;
void *stack;
@@ -142,10 +145,14 @@ void task_switch_next_inner(task_t *next_task) {
}
task_t *previous_task = current_task;
current_task = next_task;
if (previous_task != NULL) {
previous_task->errno = errno;
if (previous_task->state == TASK_STATE_RUNNING) {
previous_task->state = TASK_STATE_RUNNABLE;
}
}
current_task->state = TASK_STATE_RUNNING;
errno = current_task->errno;
// switch task
switch_task(previous_task == NULL ? NULL : &previous_task->task_registers, current_task->task_registers);
}

View File

@@ -26,7 +26,7 @@ while [[ "$#" -gt 0 ]]; do
;;
--net)
cp cmake-build-debug/my-kernel.bin netdir/my-kernel.bin
KERNEL="-netdev user,id=n0,tftp=netdir,bootfile=/boot/grub/i386-pc/core.0 -device e1000,netdev=n0"
KERNEL="-netdev user,id=n0,tftp=netdir,bootfile=/boot/grub/i386-pc/core.0 -device e1000,netdev=n0,bootindex=1"
shift
;;
-i | --ide)