From 391ed256d21a6ae2e2456d1809f357e6e96e15d1 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Mon, 20 Jan 2020 23:12:54 +0100 Subject: Added pure awesomeness Actually quite some days of work but ok --- src/kernel/fs/ata_pio.c | 46 +++++++++++++++++------------------ src/kernel/fs/atapi_pio.c | 1 - src/kernel/fs/install.c | 18 ++++++++------ src/kernel/fs/iso9660/iso9660.c | 2 +- src/kernel/fs/marfs/directory.c | 11 +++++---- src/kernel/fs/marfs/new_file.c | 8 +++--- src/kernel/fs/marfs/read_whole_file.c | 8 +++--- src/kernel/fs/marfs/sectorlevel.c | 4 +-- 8 files changed, 50 insertions(+), 48 deletions(-) (limited to 'src/kernel/fs') diff --git a/src/kernel/fs/ata_pio.c b/src/kernel/fs/ata_pio.c index 0134ee4..fef3a32 100644 --- a/src/kernel/fs/ata_pio.c +++ b/src/kernel/fs/ata_pio.c @@ -1,35 +1,35 @@ #include -#include #include +#include struct ata_interface *new_ata(uint8_t master, uint16_t port_base) { - struct ata_interface *ret = kmalloc(sizeof(struct ata_interface)); + struct ata_interface *ret = (struct ata_interface *) kmalloc(sizeof(struct ata_interface)); ret->master = master; ret->data_port = port_base; - ret->error_port = port_base + 0x1; - ret->sector_count_port = port_base + 0x2; - ret->lba_low_port = port_base + 0x3; - ret->lba_mid_port = port_base + 0x4; - ret->lba_high_port = port_base + 0x5; - ret->device_port = port_base + 0x6; - ret->command_port = port_base + 0x7; - ret->control_port = port_base + 0x206; + ret->error_port = (uint16_t) (port_base + 0x1); + ret->sector_count_port = (uint16_t) (port_base + 0x2); + ret->lba_low_port = (uint16_t) (port_base + 0x3); + ret->lba_mid_port = (uint16_t) (port_base + 0x4); + ret->lba_high_port = (uint16_t) (port_base + 0x5); + ret->device_port = (uint16_t) (port_base + 0x6); + ret->command_port = (uint16_t) (port_base + 0x7); + ret->control_port = (uint16_t) (port_base + 0x206); return ret; } uint8_t ata_identify(struct ata_interface *interface, uint16_t *ret_data) { - outb(interface->device_port, interface->master ? 0xA0 : 0xB0); + outb(interface->device_port, (uint8_t) (interface->master ? 0xA0 : 0xB0)); outb(interface->control_port, 0); outb(interface->device_port, 0xA0); uint8_t status = inb(interface->command_port); if (status == 0xFF) return 1; - outb(interface->device_port, interface->master ? 0xA0 : 0xB0); + outb(interface->device_port, (uint8_t) (interface->master ? 0xA0 : 0xB0)); outb(interface->sector_count_port, 0); outb(interface->lba_low_port, 0); outb(interface->lba_mid_port, 0); @@ -53,7 +53,7 @@ uint8_t *ata_read28(struct ata_interface *interface, uint32_t sector) { if (sector > 0x0FFFFFFF) return 0; - outb(interface->device_port, (interface->master ? 0xE0 : 0xF0) | ((sector & 0x0F000000) >> 24)); + outb(interface->device_port, (uint8_t) ((interface->master ? 0xE0 : 0xF0) | ((sector & 0x0F000000) >> 24))); uint8_t status = 0; for (int i = 0; i < 5; i++) status = inb(interface->command_port); @@ -61,19 +61,19 @@ uint8_t *ata_read28(struct ata_interface *interface, uint32_t sector) outb(interface->error_port, 0); outb(interface->sector_count_port, 1); - outb(interface->lba_low_port, sector & 0x000000FF); - outb(interface->lba_mid_port, (sector & 0x0000FF00) >> 8); - outb(interface->lba_high_port, (sector & 0x00FF0000) >> 16); + outb(interface->lba_low_port, (uint8_t) (sector & 0x000000FF)); + outb(interface->lba_mid_port, (uint8_t) ((sector & 0x0000FF00) >> 8)); + outb(interface->lba_high_port, (uint8_t) ((sector & 0x00FF0000) >> 16)); outb(interface->command_port, 0x20); // Read command status = inb(interface->command_port); while ((status & 0x80) && !(status & 0x01)) status = inb(interface->command_port); - uint8_t *ret = kmalloc(BYTES_PER_SECTOR); + uint8_t *ret = (uint8_t *) kmalloc(BYTES_PER_SECTOR); for (int i = 0; i < BYTES_PER_SECTOR; i += 2) { uint16_t data = inw(interface->data_port); - ret[i] = data & 0xFF; - ret[i + 1] = (data >> 8) & 0xFF; + ret[i] = (uint8_t) (data & 0xFF); + ret[i + 1] = (uint8_t) ((data >> 8) & 0xFF); } return ret; } @@ -83,7 +83,7 @@ uint8_t ata_write28(struct ata_interface *interface, uint32_t sector, const uint if (sector > 0x0FFFFFFF) return 1; asm ("cli"); - outb(interface->device_port, (interface->master ? 0xE0 : 0xF0) | ((sector & 0x0F000000) >> 24)); + outb(interface->device_port, (uint8_t) ((interface->master ? 0xE0 : 0xF0) | ((sector & 0x0F000000) >> 24))); uint8_t status = 0; for (int i = 0; i < 5; i++) status = inb(interface->command_port); @@ -91,9 +91,9 @@ uint8_t ata_write28(struct ata_interface *interface, uint32_t sector, const uint outb(interface->error_port, 0); outb(interface->sector_count_port, 1); - outb(interface->lba_low_port, sector & 0x000000FF); - outb(interface->lba_mid_port, (sector & 0x0000FF00) >> 8); - outb(interface->lba_high_port, (sector & 0x00FF0000) >> 16); + outb(interface->lba_low_port, (uint8_t) (sector & 0x000000FF)); + outb(interface->lba_mid_port, (uint8_t) ((sector & 0x0000FF00) >> 8)); + outb(interface->lba_high_port, (uint8_t) ((sector & 0x00FF0000) >> 16)); outb(interface->command_port, 0x30); // Write command while ((status & 0x80) || !(status & 0x08)) status = inb(interface->command_port); diff --git a/src/kernel/fs/atapi_pio.c b/src/kernel/fs/atapi_pio.c index c2cdd8c..39f32b6 100644 --- a/src/kernel/fs/atapi_pio.c +++ b/src/kernel/fs/atapi_pio.c @@ -1,7 +1,6 @@ #include #include #include -#include void ATAPI_read(uint16_t nblocks, uint32_t lba) { diff --git a/src/kernel/fs/install.c b/src/kernel/fs/install.c index af148c8..daeb91b 100644 --- a/src/kernel/fs/install.c +++ b/src/kernel/fs/install.c @@ -3,10 +3,11 @@ #include #include #include -#include #include #include #include +#include +#include void install_melvix() { @@ -27,6 +28,7 @@ void install_melvix() // Copy MBR info("Copying MBR... "); + serial_printf("Copying MBR... "); char *stage1_p[] = {"BOOT", "HDD1.BIN"}; struct iso9660_entity *stage1_e = ISO9660_get(stage1_p, 2); if (!stage1_e) @@ -37,10 +39,12 @@ void install_melvix() // Format disk info("Formatting disk..."); + serial_printf("Formatting disk..."); marfs_format(); // Copy second stage info("Copying second stage..."); + serial_printf("Copying second stage..."); char *stage2_p[] = {"BOOT", "HDD2.BIN"}; struct iso9660_entity *stage2_e = ISO9660_get(stage2_p, 2); if (!stage2_e) @@ -51,11 +55,12 @@ void install_melvix() // Copy the kernel info("Copying the kernel..."); + serial_printf("Copying the kernel..."); char *kernel_p[] = {"BOOT", "KERNEL.BIN"}; struct iso9660_entity *kernel_e = ISO9660_get(kernel_p, 2); if (!kernel_e) panic("WTH Kernel not found!?"); - uint8_t *kernel = kmalloc(kernel_e->length + 2048); + uint8_t *kernel = (uint8_t *) kmalloc(kernel_e->length + 2048); ATAPI_granular_read(1 + (kernel_e->length / 2048), kernel_e->lba, kernel); marfs_new_file(kernel_e->length, kernel, 0, 0, 0); kfree(kernel); @@ -63,6 +68,7 @@ void install_melvix() // Copy the userspace binary info("Copying userspace... "); + serial_printf("Copying userspace... "); char *userspace_p[] = {"USER.BIN"}; struct iso9660_entity *userspace_e = ISO9660_get(userspace_p, 1); if (!userspace_e) @@ -73,14 +79,10 @@ void install_melvix() // Copy the global font binary info("Copying font... "); + serial_printf("Copying font... "); char *font_p[] = {"FONT.BIN"}; struct iso9660_entity *font_e = ISO9660_get(font_p, 1); - if (!font_e) - panic("Font not found!"); - uint8_t *font = kmalloc(font_e->length + 2048); - ATAPI_granular_read(1 + (font_e->length / 2048), font_e->lba, font); - marfs_new_file(font_e->length, font, 0, 0, 0); - kfree(font); + marfs_new_file(font_e->length, (uint8_t *) font, 0, 0, 0); kfree(font_e); info("Installation successful!"); diff --git a/src/kernel/fs/iso9660/iso9660.c b/src/kernel/fs/iso9660/iso9660.c index 3c61d94..2262408 100644 --- a/src/kernel/fs/iso9660/iso9660.c +++ b/src/kernel/fs/iso9660/iso9660.c @@ -1,8 +1,8 @@ #include -#include #include #include #include +#include struct iso9660_entity *ISO9660_get(char **dirs, uint8_t dirs_sz) { diff --git a/src/kernel/fs/marfs/directory.c b/src/kernel/fs/marfs/directory.c index d0a1bff..dce92b1 100644 --- a/src/kernel/fs/marfs/directory.c +++ b/src/kernel/fs/marfs/directory.c @@ -2,6 +2,7 @@ #include #include #include +#include uint32_t marfs_new_dir(uint32_t uid) { @@ -17,7 +18,7 @@ void marfs_add_to_dir(uint32_t lba_inode, char *filename, uint32_t lba) uint8_t *old = marfs_allocate_and_read_whole_file(lba_inode); // Allocate memory - uint8_t *contents = kmalloc(inode->size + strlen(filename) + 1 + 4); + uint8_t *contents = (uint8_t *) kmalloc((uint32_t) (inode->size + strlen(filename) + 1 + 4)); // Copy the content uint8_t last_was_null = 0; @@ -26,16 +27,16 @@ void marfs_add_to_dir(uint32_t lba_inode, char *filename, uint32_t lba) if (old[i] == 0 && last_was_null) continue; contents[new_size++] = old[i]; - last_was_null = (old[i] == 0); + last_was_null = (uint8_t) (old[i] == 0); } kfree(old); // Append new file - for (size_t i = 0; i <= strlen(filename); i++) contents[new_size++] = filename[i]; - for (signed char j = 24; j > 0; j -= 8) contents[new_size++] = (lba >> j) & 0xFF; + for (size_t i = 0; i <= strlen(filename); i++) contents[new_size++] = (uint8_t) filename[i]; + for (signed char j = 24; j > 0; j -= 8) contents[new_size++] = (uint8_t) ((lba >> j) & 0xFF); // Free the blocks - uint32_t new_size_in_blocks = new_size / 512; + uint32_t new_size_in_blocks = (uint32_t) (new_size / 512); if (new_size % 512) new_size_in_blocks++; for (uint32_t i = 0; i < new_size_in_blocks; i++) marfs_mark_block_as_free(marfs_get_block(inode, i)); diff --git a/src/kernel/fs/marfs/new_file.c b/src/kernel/fs/marfs/new_file.c index 4fef3b9..ab1c241 100644 --- a/src/kernel/fs/marfs/new_file.c +++ b/src/kernel/fs/marfs/new_file.c @@ -1,7 +1,7 @@ #include #include -#include #include +#include static uint8_t last_max_level = 0; @@ -30,17 +30,17 @@ void marfs_update_recursive(uint8_t level, uint32_t i, uint32_t rec_lba, uint32_ uint32_t contents_idx = contents[idx]; kfree(contents); if (level != 1) { - marfs_update_recursive(level - 1, i, contents_idx, real_lba); + marfs_update_recursive((uint8_t) (level - 1), i, contents_idx, real_lba); } last_max_level = 0; } uint32_t marfs_new_file(uint64_t size, uint8_t *data, uint32_t uid, uint8_t exec, uint8_t dir) { - struct marfs_inode *inode = (struct marfs_inode *) kcalloc(1, 512); + struct marfs_inode *inode = (struct marfs_inode *) kmalloc(512); inode->size = size; inode->creation_time = inode->last_mod_time = inode->last_access_time = 0; // TODO: POSIX time - inode->n_blocks = size / 512; + inode->n_blocks = (uint32_t) (size / 512); if (size % 512) inode->n_blocks++; inode->uid = uid; inode->is_app = exec; diff --git a/src/kernel/fs/marfs/read_whole_file.c b/src/kernel/fs/marfs/read_whole_file.c index 85f9bbb..dda5daf 100644 --- a/src/kernel/fs/marfs/read_whole_file.c +++ b/src/kernel/fs/marfs/read_whole_file.c @@ -1,7 +1,7 @@ #include #include -#include #include +#include static uint8_t last_max_level = 0; @@ -19,7 +19,7 @@ uint32_t marfs_get_recursive(uint8_t level, uint32_t i, uint32_t rec_lba) kfree(contents); uint32_t toRet; - if (level > 1) toRet = marfs_get_recursive(level - 1, i, next_rec_lba); + if (level > 1) toRet = marfs_get_recursive((uint8_t) (level - 1), i, next_rec_lba); else toRet = next_rec_lba; last_max_level = 0; return toRet; @@ -48,7 +48,7 @@ void marfs_read_whole_file(uint32_t lba_inode, uint8_t *buffer) for (uint32_t i = 0; i < size_in_blocks; i++) { uint32_t this_block = marfs_get_block(inode, i); uint8_t *this_block_contents = ata_read28(interface, this_block); - uint16_t upper_bound = (i != size_in_blocks - 1) ? 512 : (inode->size % 512); + uint16_t upper_bound = (uint16_t) ((i != size_in_blocks - 1) ? 512 : (inode->size % 512)); for (uint16_t j = 0; j < upper_bound; j++) buffer[(i * 512) + j] = this_block_contents[j]; kfree(this_block_contents); } @@ -63,7 +63,7 @@ uint8_t *marfs_allocate_and_read_whole_file(uint32_t lba_inode) uint64_t size = inode->size; kfree(inode); - uint8_t *buffer = kmalloc(size); + uint8_t *buffer = (uint8_t *) kmalloc((uint32_t) size); marfs_read_whole_file(lba_inode, buffer); return buffer; } diff --git a/src/kernel/fs/marfs/sectorlevel.c b/src/kernel/fs/marfs/sectorlevel.c index d905315..8302054 100644 --- a/src/kernel/fs/marfs/sectorlevel.c +++ b/src/kernel/fs/marfs/sectorlevel.c @@ -1,7 +1,7 @@ #include -#include #include #include +#include uint8_t marfs_init(struct ata_interface *_interface) { @@ -62,7 +62,7 @@ static uint8_t marfs_mark_block(uint32_t lba_sector, uint8_t mode) { lba_sector -= 2; lba_sector -= sb_cache.s_first_chunk; - uint16_t block_in_chunk = lba_sector % 512; + uint16_t block_in_chunk = (uint16_t) (lba_sector % 512); lba_sector /= 512; lba_sector = 2 + sb_cache.s_first_chunk + (512 * lba_sector); -- cgit v1.2.3 From bb2a6b4d93512e8afc1b1999eb58f1f506cc27ae Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 26 Jan 2020 18:38:36 +0100 Subject: Magic commit Some things work, others don't. --- src/kernel/boot.asm | 9 +- src/kernel/fs/install.c | 2 +- src/kernel/fs/load.c | 34 ++++++ src/kernel/fs/load.h | 19 +++ src/kernel/graphics/font.c | 26 ---- src/kernel/graphics/font.h | 19 --- src/kernel/graphics/vesa.c | 2 +- src/kernel/graphics/vesa.h | 2 - src/kernel/kernel.c | 36 ++---- src/kernel/syscall/actions/sys_get_pointers.c | 2 +- src/kernel/syscall/syscall.c | 2 - src/kernel/system.c | 2 + src/kernel/system.h | 2 +- src/kernel/tasks/process.asm | 48 ++++++++ src/kernel/tasks/task.c | 168 ++++++++++++++++++++++++++ src/kernel/tasks/task.h | 30 +++++ src/kernel/timer/timer.c | 2 + src/userspace/syscall.c | 4 +- src/userspace/syscall.h | 95 +++++++-------- 19 files changed, 367 insertions(+), 137 deletions(-) create mode 100644 src/kernel/fs/load.c create mode 100644 src/kernel/fs/load.h delete mode 100644 src/kernel/graphics/font.c delete mode 100644 src/kernel/graphics/font.h create mode 100644 src/kernel/tasks/process.asm create mode 100644 src/kernel/tasks/task.c create mode 100644 src/kernel/tasks/task.h (limited to 'src/kernel/fs') diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index 85d4254..58ee8d6 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -15,16 +15,11 @@ section .text global _start extern kernel_main _start: - mov esp, STACK_TOP - push ebx - push eax + push esp cli call kernel_main cli - - hlt_L: - hlt - jmp hlt_L + jmp $ global jump_userspace jump_userspace: diff --git a/src/kernel/fs/install.c b/src/kernel/fs/install.c index daeb91b..f7e2489 100644 --- a/src/kernel/fs/install.c +++ b/src/kernel/fs/install.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include void install_melvix() { diff --git a/src/kernel/fs/load.c b/src/kernel/fs/load.c new file mode 100644 index 0000000..be7d5b8 --- /dev/null +++ b/src/kernel/fs/load.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include + +void load_binaries() +{ + userspace = kmalloc(10000); + font = (struct font *) kmalloc(100000);; // High quality shit + + uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000)); + if (boot_drive_id != 0xE0) { + struct ata_interface *primary_master = new_ata(1, 0x1F0); + marfs_init(primary_master); + marfs_read_whole_file(4, (uint8_t *) userspace); + marfs_read_whole_file(5, (uint8_t *) font); + } else { + char *font_p[] = {"FONT.BIN"}; + struct iso9660_entity *font_e = ISO9660_get(font_p, 1); + if (!font_e) panic("Font not found!"); + ATAPI_granular_read(1 + (font_e->length / 2048), font_e->lba, (uint8_t *) font); + kfree(font_e); + + char *user_p[] = {"USER.BIN"}; + struct iso9660_entity *user_e = ISO9660_get(user_p, 1); + if (!user_e) panic("Userspace binary not found!"); + ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *) userspace); + kfree(user_e); + } + vga_log("Successfully loaded binaries"); +} \ No newline at end of file diff --git a/src/kernel/fs/load.h b/src/kernel/fs/load.h new file mode 100644 index 0000000..7a0ec06 --- /dev/null +++ b/src/kernel/fs/load.h @@ -0,0 +1,19 @@ +#ifndef MELVIX_LOAD_H +#define MELVIX_LOAD_H + +#include + +uint32_t userspace; + +struct font *font; + +struct font { + uint16_t font_32[758][32]; + uint16_t font_24[758][24]; + uint8_t font_16[758][16]; + uint16_t cursor[19]; +}; + +void load_binaries(); + +#endif diff --git a/src/kernel/graphics/font.c b/src/kernel/graphics/font.c deleted file mode 100644 index 10372b3..0000000 --- a/src/kernel/graphics/font.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -void font_install() -{ - font = (struct font *) kmalloc(100000);; // High quality shit - - uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000)); - if (boot_drive_id != 0xE0) { - struct ata_interface *primary_master = new_ata(1, 0x1F0); - marfs_init(primary_master); - marfs_read_whole_file(5, (uint8_t *) font); - } else { - char *font_p[] = {"FONT.BIN"}; - struct iso9660_entity *font_e = ISO9660_get(font_p, 1); - if (!font_e) panic("Font not found!"); - ATAPI_granular_read(1 + (font_e->length / 2048), font_e->lba, (uint8_t *) font); - kfree(font_e); - } - vga_log("Successfully loaded font"); -} \ No newline at end of file diff --git a/src/kernel/graphics/font.h b/src/kernel/graphics/font.h deleted file mode 100644 index 7778979..0000000 --- a/src/kernel/graphics/font.h +++ /dev/null @@ -1,19 +0,0 @@ -// Generated using the Spleen font and the bdf2c converter (modified using the conv.sh script) -// Spleen font: (c) 2018-2019, Frederic Cambus, License: MIT -// bdf2c: (c) 2009-2010 Lutz Sammer, License: AGPLv3 - -#ifndef MELVIX_FONT_H -#define MELVIX_FONT_H - -#include - -struct font *font; - -struct font { - uint16_t font_32[758][32]; - uint16_t font_24[758][24]; - uint8_t font_16[758][16]; - uint16_t cursor[19]; -}; - -#endif diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index e2b0036..576fc18 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/src/kernel/graphics/vesa.h b/src/kernel/graphics/vesa.h index 2288760..22590de 100644 --- a/src/kernel/graphics/vesa.h +++ b/src/kernel/graphics/vesa.h @@ -185,8 +185,6 @@ void vesa_draw_cursor(int x, int y); */ void vesa_set_color(uint32_t color); -void font_install(); - /** * An enum with vesa colors * From https://github.com/joshdick/onedark.vim/ License: MIT diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index efa6ca0..91206a2 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -9,18 +9,15 @@ #include #include #include -#include -#include -#include #include #include -#include #include +#include +#include -extern void jump_userspace(); - -void kernel_main() +void kernel_main(uint32_t initial_stack) { + initial_esp = initial_stack; vga_log("Installing basic features of Melvix..."); // Install features @@ -28,13 +25,13 @@ void kernel_main() gdt_install(); init_serial(); acpi_install(); - paging_install(); idt_install(); isrs_install(); irq_install(); - font_install(); - serial_printf("%d", memory_get_all()); + paging_install(); + load_binaries(); set_optimal_resolution(); + serial_printf("%d", memory_get_all()); // Install drivers asm ("cli"); @@ -51,30 +48,17 @@ void kernel_main() // Print total memory info("Total memory found: %dMiB", (memory_get_all() >> 10) + 1); - uint8_t boot_drive_id = (uint8_t) (*((uint8_t *) 0x9000)); - #ifdef INSTALL_MELVIX #include serial_printf("Install flag given!"); - if (boot_drive_id == 0xE0) + if ((*((uint8_t *) 0x9000)) == 0xE0) install_melvix(); #endif - info("Switching to user mode..."); + tasking_install(); syscalls_install(); tss_flush(); - uint32_t userspace = (uint32_t) kmalloc(8096); - if (boot_drive_id == 0xE0) { - char *user_p[] = {"USER.BIN"}; - struct iso9660_entity *user_e = ISO9660_get(user_p, 1); - if (!user_e) panic("Userspace binary not found!"); - ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *) (userspace + 4096)); - kfree(user_e); - jump_userspace(userspace + 4096, userspace + 4096); - } else { - marfs_read_whole_file(4, (uint8_t *) (userspace + 4096)); - jump_userspace(userspace + 4096, userspace + 4096); - } + switch_to_usermode(userspace); panic("This should NOT happen!"); diff --git a/src/kernel/syscall/actions/sys_get_pointers.c b/src/kernel/syscall/actions/sys_get_pointers.c index 8e34ddd..bc00b3b 100644 --- a/src/kernel/syscall/actions/sys_get_pointers.c +++ b/src/kernel/syscall/actions/sys_get_pointers.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include struct userspace_pointers { diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c index 367fe30..7ca7f99 100644 --- a/src/kernel/syscall/syscall.c +++ b/src/kernel/syscall/syscall.c @@ -6,8 +6,6 @@ typedef uint32_t (*syscall_func)(unsigned int, ...); -extern void jump_userspace(); - uint32_t (*syscalls[])() = { [0] = (uint32_t (*)()) halt_loop, // DEBUG! [1] = sys_write, diff --git a/src/kernel/system.c b/src/kernel/system.c index 85cadc2..ae2e524 100644 --- a/src/kernel/system.c +++ b/src/kernel/system.c @@ -7,6 +7,8 @@ #include #include +uint32_t initial_esp; + char *vga_buffer = (char *) 0x500; void vga_clear() diff --git a/src/kernel/system.h b/src/kernel/system.h index 9c3ae80..8d124de 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -9,7 +9,7 @@ extern void ASM_KERNEL_END(); /** * The initial stack pointer */ -extern uint32_t STACK_TOP; +uint32_t initial_esp; /** * Initialize the basic features of the OS diff --git a/src/kernel/tasks/process.asm b/src/kernel/tasks/process.asm new file mode 100644 index 0000000..a46ac3d --- /dev/null +++ b/src/kernel/tasks/process.asm @@ -0,0 +1,48 @@ +[GLOBAL read_eip] +read_eip: + pop eax + jmp eax + +[GLOBAL copy_page_physical] +copy_page_physical: + push ebx + pushf + + cli + + mov ebx, [esp+12] + mov ecx, [esp+16] + + mov edx, cr0 + and edx, 0x7fffffff + mov cr0, edx + + mov edx, 1024 + +.loop: + mov eax, [ebx] + mov [ecx], eax + add ebx, 4 + add ecx, 4 + dec edx + jnz .loop + + mov edx, cr0 + or edx, 0x80000000 + mov cr0, edx + + popf + pop ebx + ret + +[GLOBAL perform_task_switch] +perform_task_switch: + cli + mov ecx, [esp+4] + mov eax, [esp+8] + mov ebp, [esp+12] + mov esp, [esp+16] + mov cr3, eax + mov eax, 0x12345 + sti + jmp ecx \ No newline at end of file diff --git a/src/kernel/tasks/task.c b/src/kernel/tasks/task.c new file mode 100644 index 0000000..e6caf9a --- /dev/null +++ b/src/kernel/tasks/task.c @@ -0,0 +1,168 @@ +#include +#include +#include +#include +#include +#include + +volatile task_t *current_task; +volatile task_t *ready_queue; + +extern page_directory_t *kernel_directory; +extern page_directory_t *current_directory; + +extern uint32_t read_eip(); + +uint32_t next_pid = 1; + +void tasking_install() +{ + asm ("cli"); + move_stack((void *) 0xE0000000, 0x2000); + + current_task = ready_queue = (task_t *) kmalloc(sizeof(task_t)); + current_task->id = (int) next_pid++; + current_task->esp = current_task->ebp = 0; + current_task->eip = 0; + current_task->page_directory = current_directory; + current_task->next = 0; + current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); + + vga_log("Installed Tasking"); + asm ("sti"); +} + +void move_stack(void *new_stack_start, uint32_t size) +{ + for (uint32_t i = (uint32_t) new_stack_start; + i >= ((uint32_t) new_stack_start - size); + i -= 0x1000) { + paging_alloc_frame(paging_get_page(i, 1, current_directory), 0, 1); + } + + uint32_t pd_addr; + asm volatile ("mov %%cr3, %0" : "=r" (pd_addr)); + asm volatile ("mov %0, %%cr3" : : "r" (pd_addr)); + + uint32_t old_stack_pointer; asm volatile ("mov %%esp, %0" : "=r" (old_stack_pointer)); + uint32_t old_base_pointer; asm volatile ("mov %%ebp, %0" : "=r" (old_base_pointer)); + + uint32_t offset = (uint32_t) new_stack_start - initial_esp; + + uint32_t new_stack_pointer = old_stack_pointer + offset; + uint32_t new_base_pointer = old_base_pointer + offset; + + memcpy((void *) new_stack_pointer, (void *) old_stack_pointer, initial_esp - old_stack_pointer); + + for (uint32_t i = (uint32_t) new_stack_start; i > (uint32_t) new_stack_start - size; i -= 4) { + uint32_t tmp = *(uint32_t *) i; + if ((old_stack_pointer < tmp) && (tmp < initial_esp)) { + tmp = tmp + offset; + uint32_t *tmp2 = (uint32_t *) i; + *tmp2 = tmp; + } + } + + asm volatile ("mov %0, %%esp" : : "r" (new_stack_pointer)); + asm volatile ("mov %0, %%ebp" : : "r" (new_base_pointer)); +} + +extern void perform_task_switch(uint32_t, uint32_t, uint32_t, uint32_t); + +void switch_task() +{ + if (!current_task) + return; + + uint32_t esp, ebp, eip; + asm volatile ("mov %%esp, %0" : "=r"(esp)); + asm volatile ("mov %%ebp, %0" : "=r"(ebp)); + + eip = read_eip(); + + if (eip == 0x12345) + return; + + current_task->eip = eip; + current_task->esp = esp; + current_task->ebp = ebp; + + current_task = current_task->next; + if (!current_task) current_task = ready_queue; + + eip = current_task->eip; + esp = current_task->esp; + ebp = current_task->ebp; + + current_directory = current_task->page_directory; + + set_kernel_stack(current_task->kernel_stack + KERNEL_STACK_SIZE); + + perform_task_switch(eip, current_directory->physicalAddr, ebp, esp); +} + +int fork() +{ + asm ("cli"); + + task_t *parent_task = (task_t *) current_task; + + page_directory_t *directory = paging_clone_directory(current_directory); + + task_t *new_task = (task_t *) kmalloc(sizeof(task_t)); + new_task->id = (int) next_pid++; + new_task->esp = new_task->ebp = 0; + new_task->eip = 0; + new_task->page_directory = directory; + current_task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); + new_task->next = 0; + + task_t *tmp_task = (task_t *) ready_queue; + while (tmp_task->next) + tmp_task = tmp_task->next; + tmp_task->next = new_task; + + uint32_t eip = read_eip(); + + if (current_task == parent_task) { + uint32_t esp; asm volatile ("mov %%esp, %0" : "=r"(esp)); + uint32_t ebp; asm volatile ("mov %%ebp, %0" : "=r"(ebp)); + new_task->esp = esp; + new_task->ebp = ebp; + new_task->eip = eip; + asm volatile ("sti"); + + return new_task->id; + } else { + return 0; + } +} + +int getpid() +{ + return current_task->id; +} + +void switch_to_usermode(uint32_t binary) +{ + set_kernel_stack(current_task->kernel_stack + KERNEL_STACK_SIZE); + + info("Switching to user mode..."); + + asm volatile ("\ + cli; \ + mov $0x23, %%ax; \ + mov %%ax, %%ds; \ + mov %%ax, %%es; \ + mov %%ax, %%fs; \ + mov %%ax, %%gs; \ + mov %%esp, %%eax; \ + pushl $0x23; \ + pushl %%esp; \ + pushf; \ + pushl $0x1B; \ + push %0; \ + iret; \ + 1: \ + " : : "r" (binary)); +} \ No newline at end of file diff --git a/src/kernel/tasks/task.h b/src/kernel/tasks/task.h new file mode 100644 index 0000000..97aeb15 --- /dev/null +++ b/src/kernel/tasks/task.h @@ -0,0 +1,30 @@ +#ifndef MELVIX_TASK_H +#define MELVIX_TASK_H + +#include +#include + +#define KERNEL_STACK_SIZE 2048 + +typedef struct task { + int id; + uint32_t esp, ebp; + uint32_t eip; + page_directory_t *page_directory; + uint32_t kernel_stack; + struct task *next; +} task_t; + +void tasking_install(); + +void switch_task(); + +int fork(); + +void move_stack(void *new_stack_start, uint32_t size); + +int getpid(); + +void switch_to_usermode(uint32_t); + +#endif diff --git a/src/kernel/timer/timer.c b/src/kernel/timer/timer.c index cc98bc4..9bf6014 100644 --- a/src/kernel/timer/timer.c +++ b/src/kernel/timer/timer.c @@ -1,6 +1,7 @@ #include #include #include +#include unsigned long timer_ticks = 0; @@ -16,6 +17,7 @@ void timer_phase(int hz) void timer_handler(struct regs *r) { timer_ticks++; + // switch_task(); } // "Delay" function with CPU sleep diff --git a/src/userspace/syscall.c b/src/userspace/syscall.c index 132cd49..9462b10 100644 --- a/src/userspace/syscall.c +++ b/src/userspace/syscall.c @@ -5,9 +5,9 @@ */ DEFN_SYSCALL0(halt, 0); -DEFN_SYSCALL1(write, 1, char *); +DEFN_SYSCALL1(write, 1, const char *); -DEFN_SYSCALL1(read, 2, char *); +DEFN_SYSCALL1(read, 2, const char *); DEFN_SYSCALL1(writec, 3, char); diff --git a/src/userspace/syscall.h b/src/userspace/syscall.h index e46f453..bd402a1 100644 --- a/src/userspace/syscall.h +++ b/src/userspace/syscall.h @@ -3,72 +3,69 @@ #include -#define DECL_SYSCALL0(fn) int syscall_##fn() -#define DECL_SYSCALL1(fn, p1) int syscall_##fn(p1) -#define DECL_SYSCALL2(fn, p1, p2) int syscall_##fn(p1,p2) -#define DECL_SYSCALL3(fn, p1, p2, p3) int syscall_##fn(p1,p2,p3) -#define DECL_SYSCALL4(fn, p1, p2, p3, p4) int syscall_##fn(p1,p2,p3,p4) -#define DECL_SYSCALL5(fn, p1, p2, p3, p4, p5) int syscall_##fn(p1,p2,p3,p4,p5) +#define DECL_SYSCALL0(fn) int syscall_##fn(); +#define DECL_SYSCALL1(fn, p1) int syscall_##fn(p1); +#define DECL_SYSCALL2(fn, p1, p2) int syscall_##fn(p1,p2); +#define DECL_SYSCALL3(fn, p1, p2, p3) int syscall_##fn(p1,p2,p3); +#define DECL_SYSCALL4(fn, p1, p2, p3, p4) int syscall_##fn(p1,p2,p3,p4); +#define DECL_SYSCALL5(fn, p1, p2, p3, p4, p5) int syscall_##fn(p1,p2,p3,p4,p5); #define DEFN_SYSCALL0(fn, num) \ - int syscall_##fn() { \ - int a; __asm__ __volatile__("int $0x80" : "=a" (a) : "0" (num)); \ - return a; \ - } +int syscall_##fn() \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num)); \ + return a; \ +} #define DEFN_SYSCALL1(fn, num, P1) \ - int syscall_##fn(P1 p1) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "r" ((int)(p1)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1)); \ + return a; \ +} #define DEFN_SYSCALL2(fn, num, P1, P2) \ - int syscall_##fn(P1 p1, P2 p2) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "r" ((int)(p1)), "c"((int)(p2)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1, P2 p2) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2)); \ + return a; \ +} #define DEFN_SYSCALL3(fn, num, P1, P2, P3) \ - int syscall_##fn(P1 p1, P2 p2, P3 p3) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "b" ((int)(p1)), "c"((p2)), "d"((int)(p3)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1, P2 p2, P3 p3) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d"((int)p3)); \ + return a; \ +} #define DEFN_SYSCALL4(fn, num, P1, P2, P3, P4) \ - int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "b" ((int)(p1)), "c"((int)(p2)), "d"((int)(p3)), "S"((int)(p4)) \ - : "memory"); \ - return __res; \ - } - -#define DEFN_SYSCALL5(fn, num, P1, P2, P3, P4, P5) \ - int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { \ - int __res; __asm__ __volatile__("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (num), "b" ((int)(p1)), "c"((int)(p2)), "d"((int)(p3)), "S"((int)(p4)), "D"((int)(p5)) \ - : "memory"); \ - return __res; \ - } +int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4)); \ + return a; \ +} + +#define DEFN_SYSCALL5(fn, num) \ +int syscall_##fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \ +{ \ + int a; \ + asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((int)p1), "c" ((int)p2), "d" ((int)p3), "S" ((int)p4), "D" ((int)p5)); \ + return a; \ +} /** * DECLARATIONS */ DECL_SYSCALL0(halt); -DECL_SYSCALL1(write, char *); +DECL_SYSCALL1(write, const char *); -DECL_SYSCALL1(read, char *); +DECL_SYSCALL1(read, const char *); DECL_SYSCALL1(writec, char); -- cgit v1.2.3