diff options
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/arch/i386/mmu.c | 50 | ||||
-rw-r--r-- | kernel/drivers/ahci.c | 435 | ||||
-rw-r--r-- | kernel/drivers/ahci.h | 1 | ||||
-rw-r--r-- | kernel/includes/mmu.h | 7 | ||||
-rw-r--r-- | kernel/init/kernel.c | 1 |
6 files changed, 486 insertions, 10 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 515ac51..86ec3c8 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,6 +1,6 @@ CC="i686-sb-gcc" AS="i686-sb-as" -OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o scalls/recvfrom.o math.o scalls/sendto.o signal.o scalls/kill.o scalls/sigaction.o network/tcp.o +OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o drivers/pci.o drivers/rtl8139.o network/ethernet.o network/arp.o network/bytes.o network/ipv4.o network/udp.o scalls/recvfrom.o math.o scalls/sendto.o signal.o scalls/kill.o scalls/sigaction.o network/tcp.o drivers/ahci.o CFLAGS = -O3 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. -Wno-pointer-sign INCLUDE=-I./includes/ -I./libc/include/ diff --git a/kernel/arch/i386/mmu.c b/kernel/arch/i386/mmu.c index 5d4252f..2b6c0b5 100644 --- a/kernel/arch/i386/mmu.c +++ b/kernel/arch/i386/mmu.c @@ -71,9 +71,7 @@ void *ksbrk_physical(size_t s, void **physical) { return r; } -u32 mmu_get_number_of_allocated_frames(void) { - return num_allocated_frames; -} +u32 mmu_get_number_of_allocated_frames(void) { return num_allocated_frames; } Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, int set_user) { @@ -246,8 +244,7 @@ PageDirectory *clone_directory(PageDirectory *original) { u32 physical_address; PageDirectory *new_directory = ksbrk_physical(sizeof(PageDirectory), (void **)&physical_address); - u32 offset = - (u32)new_directory->physical_tables - (u32)new_directory; + u32 offset = (u32)new_directory->physical_tables - (u32)new_directory; new_directory->physical_address = physical_address + offset; for (int i = 0; i < 1024; i++) { @@ -337,7 +334,6 @@ int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags, void *mmu_map_frames(void *const ptr, size_t s) { void *const r = mmu_find_unallocated_virtual_range((void *)0xEF000000, s); - kprintf("r: %x\n", r); size_t num_pages = s / 0x1000; for (size_t i = 0; i <= num_pages; i++) { Page *p = get_page((void *)(r + i * 0x1000), NULL, PAGE_ALLOCATE, 1); @@ -350,7 +346,6 @@ void *mmu_map_frames(void *const ptr, size_t s) { p->frame = (uintptr_t)(ptr + i * 0x1000) / 0x1000; write_to_frame((uintptr_t)ptr + i * 0x1000, 1); } - flush_tlb(); return r; } @@ -421,6 +416,44 @@ void mmu_map_physical(void *dst, PageDirectory *d, void *physical, flush_tlb(); } +struct PhysVirtMap { + u32 physical; + u32 virtual; + u32 length; + u8 in_use; +}; + +struct PhysVirtMap phys_to_virt_map[256] = {0}; + +void create_physical_to_virtual_mapping(void *physical, void *virtual, + u32 length) { + for (u16 i = 0; i < 256; i++) { + if (phys_to_virt_map[i].in_use) + continue; + phys_to_virt_map[i].physical = (u32)physical; + phys_to_virt_map[i].virtual = (u32) virtual; + phys_to_virt_map[i].length = length; + phys_to_virt_map[i].in_use = 1; + return; + } + assert(0); +} + +void *physical_to_virtual(void *address) { + for (u16 i = 0; i < 256; i++) { + if (!phys_to_virt_map[i].in_use) + continue; + if (phys_to_virt_map[i].physical + phys_to_virt_map[i].length < + (u32)address) + continue; + if (phys_to_virt_map[i].physical > (u32)address) + continue; + return (void *)phys_to_virt_map[i].virtual; + } + assert(0); + return NULL; +} + void *virtual_to_physical(void *address, PageDirectory *directory) { if (0 == directory) directory = get_active_pagedirectory(); @@ -448,8 +481,7 @@ void move_stack(u32 new_stack_address, u32 size) { // Copy the stack memcpy((void *)new_stack_pointer, (void *)old_stack_pointer, inital_esp - old_stack_pointer); - for (u32 i = (u32)new_stack_address; i > new_stack_address - size; - i -= 4) { + for (u32 i = (u32)new_stack_address; i > new_stack_address - size; i -= 4) { u32 tmp = *(u32 *)i; if (old_stack_pointer < tmp && tmp < inital_esp) { tmp = tmp + (new_stack_address - inital_esp); diff --git a/kernel/drivers/ahci.c b/kernel/drivers/ahci.c new file mode 100644 index 0000000..dfb9395 --- /dev/null +++ b/kernel/drivers/ahci.c @@ -0,0 +1,435 @@ +#include <assert.h> +#include <drivers/pci.h> +#include <mmu.h> +#include <stdio.h> + +#define ATA_DEV_BUSY 0x80 +#define ATA_DEV_DRQ 0x08 + +#define HBA_PxIS_TFES (1 << 30) + +// https://wiki.osdev.org/ATA_Command_Matrix +#define ATA_CMD_READ_DMA_EX 0x25 + +typedef enum { + FIS_TYPE_REG_H2D = 0x27, // Register FIS - host to device + FIS_TYPE_REG_D2H = 0x34, // Register FIS - device to host + FIS_TYPE_DMA_ACT = 0x39, // DMA activate FIS - device to host + FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional + FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional + FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional + FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host + FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host +} FIS_TYPE; + +struct HBA_PRDT_ENTRY { + u32 dba; // Data base address + u32 dbau; // Data base address upper 32 bits + u32 rsv0; // Reserved + + // DW3 + u32 dbc : 22; // Byte count, 4M max + u32 rsv1 : 9; // Reserved + u32 i : 1; // Interrupt on completion +}; + +struct HBA_CMD_TBL { + // 0x00 + u8 cfis[64]; // Command FIS + + // 0x40 + u8 acmd[16]; // ATAPI command, 12 or 16 bytes + + // 0x50 + u8 rsv[48]; // Reserved + + // 0x80 + struct HBA_PRDT_ENTRY + prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535 +}; + +// Host to device +struct FIS_REG_H2D { + // DWORD 0 + u8 fis_type; // FIS_TYPE_REG_H2D + + u8 pmport : 4; // Port multiplier + u8 rsv0 : 3; // Reserved + u8 c : 1; // 1: Command, 0: Control + + u8 command; // Command register + u8 featurel; // Feature register, 7:0 + + // DWORD 1 + u8 lba0; // LBA low register, 7:0 + u8 lba1; // LBA mid register, 15:8 + u8 lba2; // LBA high register, 23:16 + u8 device; // Device register + + // DWORD 2 + u8 lba3; // LBA register, 31:24 + u8 lba4; // LBA register, 39:32 + u8 lba5; // LBA register, 47:40 + u8 featureh; // Feature register, 15:8 + + // DWORD 3 + u8 countl; // Count register, 7:0 + u8 counth; // Count register, 15:8 + u8 icc; // Isochronous command completion + u8 control; // Control register + + // DWORD 4 + u8 rsv1[4]; // Reserved +}; + +struct HBA_PORT { + u32 clb; // 0x00, command list base address, 1K-byte aligned + u32 clbu; // 0x04, command list base address upper 32 bits + u32 fb; // 0x08, FIS base address, 256-byte aligned + u32 fbu; // 0x0C, FIS base address upper 32 bits + u32 is; // 0x10, interrupt status + u32 ie; // 0x14, interrupt enable + u32 cmd; // 0x18, command and status + u32 rsv0; // 0x1C, Reserved + u32 tfd; // 0x20, task file data + u32 sig; // 0x24, signature + u32 ssts; // 0x28, SATA status (SCR0:SStatus) + u32 sctl; // 0x2C, SATA control (SCR2:SControl) + u32 serr; // 0x30, SATA error (SCR1:SError) + u32 sact; // 0x34, SATA active (SCR3:SActive) + u32 ci; // 0x38, command issue + u32 sntf; // 0x3C, SATA notification (SCR4:SNotification) + u32 fbs; // 0x40, FIS-based switch control + u32 rsv1[11]; // 0x44 ~ 0x6F, Reserved + u32 vendor[4]; // 0x70 ~ 0x7F, vendor specific +}; + +struct HBA_MEM { + // 0x00 - 0x2B, Generic Host Control + u32 cap; // 0x00, Host capability + u32 ghc; // 0x04, Global host control + u32 is; // 0x08, Interrupt status + u32 pi; // 0x0C, Port implemented + u32 vs; // 0x10, Version + u32 ccc_ctl; // 0x14, Command completion coalescing control + u32 ccc_pts; // 0x18, Command completion coalescing ports + u32 em_loc; // 0x1C, Enclosure management location + u32 em_ctl; // 0x20, Enclosure management control + u32 cap2; // 0x24, Host capabilities extended + u32 bohc; // 0x28, BIOS/OS handoff control and status + + // 0x2C - 0x9F, Reserved + u8 rsv[0xA0 - 0x2C]; + + // 0xA0 - 0xFF, Vendor specific registers + u8 vendor[0x100 - 0xA0]; + + // 0x100 - 0x10FF, Port control registers + struct HBA_PORT ports[1]; // 1 ~ 32 +}; + +struct HBA_CMD_HEADER { + // DW0 + u8 cfl : 5; // Command FIS length in DWORDS, 2 ~ 16 + u8 a : 1; // ATAPI + u8 w : 1; // Write, 1: H2D, 0: D2H + u8 p : 1; // Prefetchable + + u8 r : 1; // Reset + u8 b : 1; // BIST + u8 c : 1; // Clear busy upon R_OK + u8 rsv0 : 1; // Reserved + u8 pmp : 4; // Port multiplier port + + u16 prdtl; // Physical region descriptor table length in entries + + // DW1 + volatile u32 prdbc; // Physical region descriptor byte count transferred + + // DW2, 3 + u32 ctba; // Command table descriptor base address + u32 ctbau; // Command table descriptor base address upper 32 bits + + // DW4 - 7 + u32 rsv1[4]; // Reserved +}; + +#define SATA_SIG_ATA 0x00000101 // SATA drive +#define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive +#define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge +#define SATA_SIG_PM 0x96690101 // Port multiplier + +#define AHCI_DEV_NULL 0 +#define AHCI_DEV_SATA 1 +#define AHCI_DEV_SEMB 2 +#define AHCI_DEV_PM 3 +#define AHCI_DEV_SATAPI 4 + +#define HBA_PORT_IPM_ACTIVE 1 +#define HBA_PORT_DET_PRESENT 3 + +u32 check_type(volatile struct HBA_PORT *port) { + u32 ssts = port->ssts; + + u8 ipm = (ssts >> 8) & 0x0F; + u8 det = ssts & 0x0F; + + if (det != HBA_PORT_DET_PRESENT) // Check drive status + return AHCI_DEV_NULL; + if (ipm != HBA_PORT_IPM_ACTIVE) + return AHCI_DEV_NULL; + + switch (port->sig) { + case SATA_SIG_ATAPI: + return AHCI_DEV_SATAPI; + case SATA_SIG_SEMB: + return AHCI_DEV_SEMB; + case SATA_SIG_PM: + return AHCI_DEV_PM; + default: + return AHCI_DEV_SATA; + } +} + +void ahci_start_command_execution(volatile struct HBA_PORT *port) { + // Wait for it to stop running. + // TODO: Figure out if this is really required. + for (; port->cmd & (1 << 14);) + ; + + // Start recieving FIS into PxFB + port->cmd |= ((u32)4 << 0); + // Start processing of commands + port->cmd |= ((u32)1 << 0); +} + +void ahci_stop_command_execution(volatile struct HBA_PORT *port) { + // Disable processing of commands + port->cmd &= ~((u32)1 << 0); + // Disable recieving FIS into PxFB + port->cmd &= ~((u32)1 << 4); + + // Check the CR and FR registers to make sure they are no longer running. + for (; (port->cmd & (1 << 14)) || (port->cmd & (1 << 15));) + ; +} + +// clb_address: size has to be 1024 and byte aligned to 1024 +// fb_address: size has to be 256 and byte aligned to 256 +// command_table_array: size has to be 256*32 +// They are both physical addresses +void ahci_set_base(volatile struct HBA_PORT *port, u32 virt_clb_address, + u32 virt_fb_address, u32 virt_command_table_array) { + u32 clb_address = (u32)virtual_to_physical((void *)virt_clb_address, NULL); + u32 fb_address = (u32)virtual_to_physical((void *)virt_fb_address, NULL); + u32 command_table_array = + (u32)virtual_to_physical((void *)virt_command_table_array, NULL); + + ahci_stop_command_execution(port); + + // Command List Base Address (CLB): Indicates the 32-bit base physical address + // for the command list for this port. This base is used when fetching + // commands to execute. This address must be 1K-byte aligned as indicated by + // bits 09:00 being read only. + assert(0 == (clb_address & (0x3FF))); + assert(0 == (fb_address & (0xFF))); + port->clb = clb_address & (~(u32)(0x3FF)); + port->clbu = 0; + + port->fb = fb_address; + port->fbu = 0; + + // Command table offset: 40K + 8K*portno + // Command table size = 256*32 = 8K per port + struct HBA_CMD_HEADER *cmdheader = + (struct HBA_CMD_HEADER *)(virt_clb_address); + for (u8 i = 0; i < 32; i++) { + cmdheader[i].prdtl = 8; // 8 prdt entries per command table + // 256 bytes per command table, 64+16+48+16*8 + cmdheader[i].ctba = command_table_array + i * 256; + cmdheader[i].ctbau = 0; + } + + ahci_start_command_execution(port); +} + +void ahci_sata_setup(volatile struct HBA_PORT *port) { + // clb_address: size has to be 1024 and byte aligned to 1024 + // fb_address: size has to be 256 and byte aligned to 256 + // command_table_array: size has to be 256*32 + u32 clb_address = (u32)ksbrk(1024); + u32 fb_address = (u32)ksbrk(256); + u32 command_table_array = (u32)ksbrk(256 * 32); + create_physical_to_virtual_mapping( + virtual_to_physical((void *)clb_address, NULL), (void *)clb_address, + 1024); + create_physical_to_virtual_mapping( + virtual_to_physical((void *)fb_address, NULL), (void *)fb_address, 256); + create_physical_to_virtual_mapping( + virtual_to_physical((void *)command_table_array, NULL), + (void *)command_table_array, 256 * 32); + + // TODO: Should it be the responsiblity of the caller to make sure these are + // clear? + memset((void *)clb_address, 0, 1024); + memset((void *)fb_address, 0, 256); + memset((void *)command_table_array, 0, 256 * 32); + + ahci_set_base(port, clb_address, fb_address, command_table_array); +} + +// Returns the command slot. +// Sets err if no free slot was found. +u8 get_free_command_slot(volatile struct HBA_PORT *port, u8 *err) { + u32 slots = (port->sact | port->ci); + for (u8 i = 0; i < 32; i++) { + if (!((slots >> i) & 1)) { + *err = 0; + return i; + } + } + *err = 1; + return 0; +} + +u8 ahci_read(volatile struct HBA_PORT *port, u32 startl, u32 starth, u32 count, + u16 *outbuffer) { + port->is = -1; // Clear pending interrupts + u8 err; + u32 command_slot = get_free_command_slot(port, &err); + if (err) { + klog("No command slot found", LOG_WARN); + return 0; + } + struct HBA_CMD_HEADER *cmdheader = + (struct HBA_CMD_HEADER *)physical_to_virtual((void *)port->clb); + cmdheader += command_slot; + cmdheader->w = 0; // No write(aka read) + cmdheader->cfl = sizeof(struct FIS_REG_H2D) / sizeof(u32); + cmdheader->prdtl = (u16)((count - 1) / 16 + 1); // Number of PRDT + + // Write to the prdtl + struct HBA_CMD_TBL *cmdtbl = + (struct HBA_CMD_TBL *)(physical_to_virtual((void *)cmdheader->ctba)); + + memset((void *)cmdtbl, 0, + sizeof(struct HBA_CMD_TBL) + + (cmdheader->prdtl - 1) * sizeof(struct HBA_PRDT_ENTRY)); + + // 8K bytes (16 sectors) per PRDT + u16 i = 0; + for (; i < cmdheader->prdtl - 1; i++) { + cmdtbl->prdt_entry[i].dba = (u32)virtual_to_physical(outbuffer, NULL); + cmdtbl->prdt_entry[i].dbc = + 8 * 1024 - 1; // 8K bytes (this value should always be set to 1 less + // than the actual value) + cmdtbl->prdt_entry[i].i = 1; + outbuffer += 4 * 1024; // 4K words + count -= 16; // 16 sectors + } + // FIXME: Edge case if the count does not fit. This should not be here it is + // ugly. Find a more general case. + cmdtbl->prdt_entry[i].dba = (u32)virtual_to_physical(outbuffer, NULL); + cmdtbl->prdt_entry[i].dbc = count * 512 - 1; + cmdtbl->prdt_entry[i].i = 1; + + struct FIS_REG_H2D *cmdfis = (struct FIS_REG_H2D *)(&cmdtbl->cfis); + + cmdfis->fis_type = FIS_TYPE_REG_H2D; + cmdfis->c = 1; + cmdfis->command = ATA_CMD_READ_DMA_EX; + + cmdfis->lba0 = (u8)startl; + cmdfis->lba1 = (u8)(startl >> 8); + cmdfis->lba2 = (u8)(startl >> 16); + cmdfis->device = 1 << 6; // LBA mode + + cmdfis->lba3 = (u8)(startl >> 24); + cmdfis->lba4 = (u8)starth; + cmdfis->lba5 = (u8)(starth >> 8); + + cmdfis->countl = count & 0xFF; + cmdfis->counth = (count >> 8) & 0xFF; + + // The below loop waits until the port is no longer busy before issuing a new + // command + u32 spin = 0; + while ((port->tfd & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && spin < 1000000) { + spin++; + } + if (spin == 1000000) { + kprintf("Port is hung\n"); + return 0; + } + + port->ci = 1 << command_slot; // Issue command + + // Wait for completion + for (;;) { + // In some longer duration reads, it may be helpful to spin on the DPS bit + // in the PxIS port field as well (1 << 5) + if ((port->ci & (1 << command_slot)) == 0) + break; + if (port->is & HBA_PxIS_TFES) // Task file error + { + kprintf("Read disk error\n"); + return 0; + } + } + + // Check again + if (port->is & HBA_PxIS_TFES) { + kprintf("Read disk error\n"); + return 0; + } + + return 1; +} + +void ahci_test(volatile struct HBA_PORT *port) { + char buffer[1024]; + memset(buffer, 1, 1024); + assert(ahci_read(port, 0, 0, 2, (u16 *)buffer)); + for (u32 i = 0; i < 1024; i++) { + kprintf("%x", buffer[i]); + } +} + +void ahci_init(void) { + struct PCI_DEVICE device; + if (!pci_devices_by_id(0x01, 0x06, &device)) + return; + kprintf("vendor: %x\n", device.vendor); + kprintf("device: %x\n", device.device); + kprintf("header_type: %x\n", device.header_type); + + struct PCI_BaseAddressRegister bar; + pci_get_bar(&device, 5, &bar); + + u8 *HBA_base = mmu_map_frames((void *)bar.address, bar.size); + volatile struct HBA_MEM *hba = (volatile struct HBA_MEM *)(HBA_base); + for (u8 i = 0; i < 32; i++) { + if (!((hba->pi >> i) & 1)) + continue; + u32 type = check_type(&hba->ports[i]); + switch (type) { + case AHCI_DEV_SATA: + ahci_sata_setup(&hba->ports[i]); + ahci_test(&hba->ports[i]); + kprintf("SATA drive found at port %d\n", i); + break; + case AHCI_DEV_SATAPI: + kprintf("SATAPI drive found at port %d\n", i); + break; + case AHCI_DEV_SEMB: + kprintf("SEMB drive found at port %d\n", i); + break; + case AHCI_DEV_PM: + kprintf("PM drive found at port %d\n", i); + break; + default: + kprintf("No drive found at port %d\n", i); + break; + } + } +} diff --git a/kernel/drivers/ahci.h b/kernel/drivers/ahci.h new file mode 100644 index 0000000..d075f07 --- /dev/null +++ b/kernel/drivers/ahci.h @@ -0,0 +1 @@ +void ahci_init(void); diff --git a/kernel/includes/mmu.h b/kernel/includes/mmu.h index c9b682f..8990bdf 100644 --- a/kernel/includes/mmu.h +++ b/kernel/includes/mmu.h @@ -56,7 +56,14 @@ void *virtual_to_physical(void *address, PageDirectory *directory); void *is_valid_userpointer(const void *const p, size_t s); void *is_valid_user_c_string(const char *ptr, size_t *size); void *ksbrk(size_t s); +void *ksbrk_physical(size_t s, void **physical); Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, int set_user); + +void create_physical_to_virtual_mapping(void *physical, void *virtual, + u32 length); +// This can only be used on addreses that be been mapped using: +// create_physical_to_virtual_mapping +void *physical_to_virtual(void *address); #endif diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c index 217967a..e9c8ea1 100644 --- a/kernel/init/kernel.c +++ b/kernel/init/kernel.c @@ -4,6 +4,7 @@ #include <cpu/spinlock.h> #include <cpu/syscall.h> #include <crypto/SHA1/sha1.h> +#include <drivers/ahci.h> #include <drivers/ata.h> #include <drivers/keyboard.h> #include <drivers/mouse.h> |