├── hda.img.bak ├── drivers ├── storage │ ├── ahci │ │ └── ahci.h │ ├── drive.h │ ├── atapio │ │ ├── atapio.h │ │ └── src │ │ │ └── atapio.cpp │ └── floppy │ │ ├── src │ │ └── floppy.cpp │ │ └── floppy.h ├── timer │ ├── pit.h │ └── src │ │ └── pit.cpp ├── pc_speaker │ ├── speaker.h │ └── src │ │ └── speaker.cpp ├── rtc │ ├── time.h │ └── src │ │ └── time.cpp ├── serial │ ├── serial.h │ └── src │ │ └── serial.cpp ├── text_term │ ├── terminal.h │ └── src │ │ └── terminal.cpp ├── keyboard │ ├── keyboard.h │ ├── keyboard_layouts.h │ └── src │ │ └── keyboard.cpp ├── pci │ ├── pci.h │ └── src │ │ └── pci.cpp └── filesystems │ └── ext2 │ ├── ext2fs.h │ └── src │ └── ext2fs.cpp ├── shell ├── shell.h ├── testtask.asm └── shell.cpp ├── ISO └── boot │ ├── MemeOS │ └── grub │ └── grub.cfg ├── libs ├── kernel │ ├── panic.h │ ├── pic.h │ ├── syscalls.h │ ├── src │ │ ├── asm_gdt.asm │ │ ├── pic.cpp │ │ ├── asm_paging.asm │ │ ├── tss.cpp │ │ ├── panic.cpp │ │ ├── syscalls.cpp │ │ ├── c_isr.cpp │ │ ├── gdt.cpp │ │ ├── idt.cpp │ │ ├── paging.cpp │ │ ├── asm_isr.asm │ │ └── liballoc.cpp │ ├── tss.h │ ├── paging.h │ ├── gdt.h │ ├── multiboot.h │ ├── io.h │ ├── idt.h │ └── liballoc.h ├── std │ ├── stdio.h │ ├── math.h │ ├── stdint.h │ ├── string.h │ ├── vector.h │ ├── stream.h │ └── src │ │ └── string.cpp ├── sys │ └── syscall.h └── _old │ ├── memory.h │ ├── gdt.h │ ├── memory.cpp │ ├── string.h │ ├── gdt.cpp │ ├── ahci.cpp │ ├── pci.h │ ├── idt.cpp │ ├── string.cpp │ ├── ahci.h │ └── pci.cpp ├── .gitattributes ├── .vscode ├── settings.json ├── c_cpp_properties.json └── tasks.json ├── .gitignore ├── licence ├── loader.asm ├── linker.ld ├── get_compiler.sh ├── bochsrc.bxrc ├── CMakeLists.txt └── kernel.cpp /hda.img.bak: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /drivers/storage/ahci/ahci.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shell/shell.h: -------------------------------------------------------------------------------- 1 | void shell_main(MultibootInfo_t* boot_info); -------------------------------------------------------------------------------- /ISO/boot/MemeOS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexandreRouma/MemeOS/HEAD/ISO/boot/MemeOS -------------------------------------------------------------------------------- /libs/kernel/panic.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void kernel_panic(uint16_t error_code, char* message); -------------------------------------------------------------------------------- /ISO/boot/grub/grub.cfg: -------------------------------------------------------------------------------- 1 | set timeout=0 2 | set default=0 3 | 4 | menuentry "MemeOS v4.20" { 5 | multiboot /boot/MemeOS 6 | } -------------------------------------------------------------------------------- /libs/kernel/pic.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class PIC_Class { 4 | public: 5 | void Init(); 6 | }; 7 | 8 | extern PIC_Class PIC; -------------------------------------------------------------------------------- /libs/std/stdio.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | inline void printf(char* str) { 4 | syscall(SYS_PRINT, (uint32_t)str, 0, 0); 5 | } -------------------------------------------------------------------------------- /libs/kernel/syscalls.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void syscall(uint32_t id, uint32_t ebx, uint32_t ecx, uint32_t edx); 4 | 5 | void KERN_EXEC_SYSCALL(uint32_t id, uint32_t ebx, uint32_t ecx, uint32_t edx); -------------------------------------------------------------------------------- /drivers/timer/pit.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class PIT_Class { 4 | public: 5 | void Init(); 6 | void delay(uint32_t ms); 7 | uint64_t system_ticks = 0; 8 | }; 9 | 10 | extern PIT_Class PIT; -------------------------------------------------------------------------------- /libs/sys/syscall.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SYS_PRINT 0x00 4 | 5 | inline void syscall(uint32_t id, uint32_t ebx, uint32_t ecx, uint32_t edx) { 6 | asm("int $0x69" :: "a" (id), "b" (ebx), "c" (ecx), "d" (edx)); 7 | } -------------------------------------------------------------------------------- /drivers/pc_speaker/speaker.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Speaker_Class { 4 | public: 5 | void tone(uint16_t frequency); 6 | void noTone(); 7 | void beep(); 8 | }; 9 | 10 | extern Speaker_Class Speaker; -------------------------------------------------------------------------------- /libs/_old/memory.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char* malloc(uint32_t size); 4 | char* calloc(uint32_t size); 5 | void free(uint32_t addr); 6 | uint32_t memused(); 7 | uint32_t memfree(); 8 | uint32_t getRamAmount(); 9 | uint32_t setRamAmount(); -------------------------------------------------------------------------------- /drivers/storage/drive.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Drive_t { 4 | public: 5 | virtual bool read(uint64_t addr, uint64_t size, uint8_t* buf) = 0 ; 6 | virtual bool write(uint64_t addr, uint64_t size, uint8_t* buf) = 0 ; 7 | //virtual uint64_t getCapacity() = 0 ; 8 | }; -------------------------------------------------------------------------------- /libs/kernel/src/asm_gdt.asm: -------------------------------------------------------------------------------- 1 | .global ASM_RELOAD_SEGMENTS 2 | 3 | ASM_RELOAD_SEGMENTS: 4 | movw $0x10, %ax 5 | movw %ax, %ds 6 | movw %ax, %es 7 | movw %ax, %fs 8 | movw %ax, %gs 9 | movw %ax, %ss 10 | ljmp $0x08, $flush2 11 | 12 | flush2: 13 | ret 14 | -------------------------------------------------------------------------------- /libs/_old/gdt.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class GDT_Class { 4 | public: 5 | void load(); 6 | void setGDTEntry(uint32_t index, uint32_t base, uint32_t limit, uint8_t type); 7 | }; 8 | 9 | extern "C" 10 | { 11 | extern void ASM_RELOAD_SEGMENTS(void); 12 | } 13 | 14 | 15 | extern GDT_Class GDT; -------------------------------------------------------------------------------- /drivers/rtc/time.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Time_t { 4 | uint8_t hours; 5 | uint8_t minutes; 6 | uint8_t seconds; 7 | uint8_t day; 8 | uint8_t month; 9 | uint8_t year; 10 | uint32_t epoch; 11 | }; 12 | 13 | class Time_Class { 14 | public: 15 | Time_t getTime(); 16 | }; 17 | 18 | extern Time_Class Time; -------------------------------------------------------------------------------- /libs/std/math.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | inline int floor(float value) { 4 | return (int)value; 5 | } 6 | 7 | inline int ceil(float value) { 8 | return floor(value) + 1; 9 | } 10 | 11 | inline int round(float value) { 12 | if ((float)(value - (int)value) > 0.5f) { 13 | return floor(value) + 1; 14 | } 15 | return floor(value); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /shell/testtask.asm: -------------------------------------------------------------------------------- 1 | .org 0x00000000 2 | .global ASM_USER_TASK 3 | .global _END_ASM_USER_TASK 4 | 5 | ASM_USER_TASK: 6 | push %eax 7 | push %ebx 8 | 9 | mov $0x00, %eax 10 | mov $msg, %ebx 11 | int $0x69 12 | 13 | pop %ebx 14 | pop %eax 15 | 16 | ret 17 | _END_ASM_USER_TASK: 18 | 19 | msg: 20 | .ascii "Hello World from userspace task!0" 21 | -------------------------------------------------------------------------------- /libs/_old/memory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char* malloc(uint32_t size) { 6 | 7 | } 8 | 9 | char* calloc(uint32_t size) { 10 | // Malloc but clears the area 11 | } 12 | 13 | void free(uint32_t addr) { 14 | 15 | } 16 | 17 | uint32_t memused() { 18 | 19 | } 20 | 21 | uint32_t memfree() { 22 | return MAX_MEM - memused(); 23 | } -------------------------------------------------------------------------------- /libs/kernel/src/pic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | PIC_Class PIC; 5 | 6 | void PIC_Class::Init() { 7 | outb(0x20, 0x11); 8 | outb(0xA0, 0x11); 9 | outb(0x21, 0x20); 10 | outb(0xA1, 0x28); 11 | outb(0x21, 0x04); 12 | outb(0xA1, 0x02); 13 | outb(0x21, 0x01); 14 | outb(0xA1, 0x01); 15 | outb(0x21, 0x0); 16 | outb(0xA1, 0x0); 17 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /drivers/serial/serial.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Serial { 5 | public: 6 | Serial(uint16_t baud, uint16_t addr); 7 | void print(char* str); 8 | void println(char* str); 9 | void write(char c); 10 | 11 | uint16_t baudrate; 12 | uint16_t address; 13 | stream outStream; 14 | 15 | private: 16 | static void _streamHandler(char*, int, Serial*); 17 | }; -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.intelliSenseEngineFallback": "Enabled", 3 | "C_Cpp.errorSquiggles": "Disabled", 4 | "files.associations": { 5 | "*.php": "html", 6 | "array": "cpp", 7 | "initializer_list": "cpp", 8 | "utility": "cpp", 9 | "functional": "cpp", 10 | "tuple": "cpp", 11 | "type_traits": "cpp", 12 | "*.tcc": "cpp", 13 | "iosfwd": "cpp", 14 | "xutility": "cpp" 15 | } 16 | } -------------------------------------------------------------------------------- /libs/kernel/src/asm_paging.asm: -------------------------------------------------------------------------------- 1 | .text 2 | .globl ASM_LOAD_PAGE_DIRECTORY 3 | ASM_LOAD_PAGE_DIRECTORY: 4 | push %ebp 5 | mov %esp, %ebp 6 | mov 8(%esp), %eax 7 | mov %eax, %cr3 8 | mov %ebp, %esp 9 | pop %ebp 10 | ret 11 | 12 | .text 13 | .globl ASM_ENABLE_PAGING 14 | ASM_ENABLE_PAGING: 15 | push %ebp 16 | mov %esp, %ebp 17 | mov %cr0, %eax 18 | or $0x80000000, %eax 19 | mov %eax, %cr0 20 | mov %ebp, %esp 21 | pop %ebp 22 | ret 23 | -------------------------------------------------------------------------------- /drivers/rtc/src/time.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | Time_Class Time; 6 | 7 | Time_t Time_Class::getTime() { 8 | Time_t time; 9 | outb(0x70, 0x00); 10 | time.seconds = inb(0x71); 11 | outb(0x70, 0x02); 12 | time.minutes = inb(0x71); 13 | outb(0x70, 0x04); 14 | time.hours = inb(0x71); 15 | outb(0x70, 0x07); 16 | time.day = inb(0x71); 17 | outb(0x70, 0x08); 18 | time.month = inb(0x71); 19 | outb(0x70, 0x09); 20 | time.year = inb(0x71); 21 | return time; 22 | } -------------------------------------------------------------------------------- /libs/kernel/src/tss.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct tss kernel_tss; 6 | 7 | void initTss() { 8 | memset(&kernel_tss, 0x00, sizeof(kernel_tss)); 9 | kernel_tss.debug_flag = 0x00; 10 | kernel_tss.io_map = 0x68; 11 | kernel_tss.esp0 = (uint32_t)&ASM_STACK_TOP; 12 | kernel_tss.ss0 = 0x10; 13 | } 14 | 15 | void loadTss() { 16 | asm(" movw $0x20, %ax \n \ 17 | ltr %ax"); 18 | 19 | asm(" movw %%ss, %0 \n \ 20 | movl %%esp, %1" : "=m" (kernel_tss.ss0), "=m" (kernel_tss.esp0) : ); 21 | } -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "WSL", 5 | "includePath": [ 6 | "${workspaceFolder}", 7 | "${workspaceFolder}/libs/std" 8 | ], 9 | "defines": [ 10 | "_DEBUG", 11 | "UNICODE", 12 | "_UNICODE" 13 | ], 14 | "compilerPath": "/home/dragon/opt/cross/bin/i686-elf-gcc", 15 | "cStandard": "c11", 16 | "cppStandard": "c++17", 17 | "intelliSenseMode": "gcc-x64" 18 | } 19 | ], 20 | "version": 4 21 | } -------------------------------------------------------------------------------- /drivers/timer/src/pit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | PIT_Class PIT; 6 | 7 | void PIT_Class::Init() { 8 | int divisor = 1193180 / 1000; /* Calculate our divisor */ 9 | outb(0x43, 0x36); /* Set our command byte 0x36 */ 10 | outb(0x40, divisor & 0xFF); /* Set low byte of divisor */ 11 | outb(0x40, divisor >> 8); /* Set high byte of divisor */ 12 | } 13 | 14 | void PIT_Class::delay(uint32_t ms) { 15 | uint32_t endtick = system_ticks + ms; 16 | while (system_ticks < endtick) { 17 | asm("nop"); 18 | } 19 | } -------------------------------------------------------------------------------- /drivers/storage/atapio/atapio.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class ATAPIODrive_t : public Drive_t { 5 | public: 6 | ATAPIODrive_t(uint8_t id); 7 | bool read(uint64_t addr, uint64_t size, uint8_t* buf); 8 | bool write(uint64_t addr, uint64_t size, uint8_t* buf); 9 | //int getCapacity(float) = 0 ; // TODO: Finish 10 | 11 | private: 12 | uint8_t id; 13 | }; 14 | 15 | class ATAPIO_Class { 16 | public: 17 | int readBlock(int drive, int numblock, int count, char *buf); 18 | int writeBlock(int drive, int numblock, int count, char *buf); 19 | }; 20 | 21 | extern ATAPIO_Class ATAPIO; -------------------------------------------------------------------------------- /drivers/pc_speaker/src/speaker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Speaker_Class Speaker; 7 | 8 | void Speaker_Class::tone(uint16_t frequency) { 9 | uint32_t Div; 10 | uint8_t tmp; 11 | 12 | Div = 1193180 / frequency; // Find divider 13 | outb(0x43, 0xb6); 14 | outb(0x42, (uint8_t) (Div) ); 15 | outb(0x42, (uint8_t) (Div >> 8)); 16 | 17 | tmp = inb(0x61); 18 | if (tmp != (tmp | 3)) { 19 | outb(0x61, tmp | 3); 20 | } 21 | } 22 | 23 | void Speaker_Class::noTone() { 24 | uint8_t tmp = inb(0x61) & 0xFC; 25 | outb(0x61, tmp); 26 | } 27 | 28 | void Speaker_Class::beep() { 29 | tone(1000); 30 | PIT.delay(100); 31 | noTone(); 32 | } -------------------------------------------------------------------------------- /libs/kernel/tss.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct tss { 4 | uint16_t previous_task, __previous_task_unused; 5 | uint32_t esp0; 6 | uint16_t ss0, __ss0_unused; 7 | uint32_t esp1; 8 | uint16_t ss1, __ss1_unused; 9 | uint32_t esp2; 10 | uint16_t ss2, __ss2_unused; 11 | uint32_t cr3; 12 | uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; 13 | uint16_t es, __es_unused; 14 | uint16_t cs, __cs_unused; 15 | uint16_t ss, __ss_unused; 16 | uint16_t ds, __ds_unused; 17 | uint16_t fs, __fs_unused; 18 | uint16_t gs, __gs_unused; 19 | uint16_t ldt_selector, __ldt_sel_unused; 20 | uint16_t debug_flag, io_map; 21 | } __attribute__ ((packed)); 22 | 23 | extern struct tss kernel_tss; 24 | 25 | void initTss(); 26 | void loadTss(); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | *.img 17 | 18 | # Windows shortcuts 19 | *.lnk 20 | 21 | # ========================= 22 | # Operating System Files 23 | # ========================= 24 | 25 | # OSX 26 | # ========================= 27 | 28 | .DS_Store 29 | .AppleDouble 30 | .LSOverride 31 | 32 | # Thumbnails 33 | ._* 34 | 35 | # Files that might appear in the root of a volume 36 | .DocumentRevisions-V100 37 | .fseventsd 38 | .Spotlight-V100 39 | .TemporaryItems 40 | .Trashes 41 | .VolumeIcon.icns 42 | 43 | # Directories potentially created on remote AFP share 44 | .AppleDB 45 | .AppleDesktop 46 | Network Trash Folder 47 | Temporary Items 48 | .apdisk 49 | 50 | # Binaries 51 | /build -------------------------------------------------------------------------------- /libs/kernel/paging.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Paging_Class { 4 | public: 5 | void enable(uint32_t maxmem); 6 | void mapPage(uint32_t phy, uint32_t virt, uint16_t flags); 7 | uint32_t getPhysicalAddr(uint32_t virt); 8 | uint16_t getFlags(uint32_t virt); 9 | void setFlags(uint32_t virt, uint16_t flags); 10 | uint16_t getDirectoryFlags(uint32_t virt); 11 | void setDirectoryFlags(uint32_t virt, uint16_t flags); 12 | void setPresent(uint32_t virt, uint32_t count); 13 | void setAbsent(uint32_t virt, uint32_t count); 14 | uint32_t findPages(uint32_t count); 15 | uint32_t allocPages(uint32_t count); 16 | uint32_t getUsedPages(); 17 | }; 18 | 19 | extern "C" 20 | { 21 | extern void ASM_LOAD_PAGE_DIRECTORY(uint32_t*); 22 | extern void ASM_ENABLE_PAGING(void); 23 | } 24 | 25 | 26 | extern Paging_Class Paging; -------------------------------------------------------------------------------- /libs/kernel/gdt.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define GDT_ACCESS_PRESENT 0x90 4 | #define GDT_ACCESS_PR_TSS 0x80 5 | #define GDT_ACCESS_PRIV_3 0x60 6 | #define GDT_ACCESS_PRIV_2 0x40 7 | #define GDT_ACCESS_PRIV_1 0x20 8 | #define GDT_ACCESS_EXEC 0x08 9 | #define GDT_ACCESS_DIR_D 0x04 10 | #define GDT_ACCESS_RW 0x02 11 | #define GDT_ACCESS_ACCESSED 0x01 12 | 13 | #define GDT_FLAG_GR_PAGE 0x08 14 | #define GDT_FLAG_SZ_32B 0x04 15 | 16 | class GDT_Class { 17 | public: 18 | void load(); 19 | void setGDTEntry(uint32_t index, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags); 20 | uint32_t findFreeEntry(); 21 | uint32_t allocEntry(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags); 22 | void freeEntry(uint32_t index); 23 | }; 24 | 25 | extern "C" 26 | { 27 | extern void ASM_RELOAD_SEGMENTS(void); 28 | } 29 | 30 | 31 | extern GDT_Class GDT; -------------------------------------------------------------------------------- /libs/std/stdint.h: -------------------------------------------------------------------------------- 1 | # define INT8_MIN (-128) 2 | # define INT16_MIN (-32767-1) 3 | # define INT32_MIN (-2147483647-1) 4 | # define INT64_MIN (-__INT64_C(9223372036854775807)-1) 5 | 6 | # define INT8_MAX (127) 7 | # define INT16_MAX (32767) 8 | # define INT32_MAX (2147483647) 9 | # define INT64_MAX (__INT64_C(9223372036854775807)) 10 | 11 | # define UINT8_MAX (255) 12 | # define UINT16_MAX (65535) 13 | # define UINT32_MAX (4294967295U) 14 | # define UINT64_MAX (__UINT64_C(18446744073709551615)) 15 | 16 | typedef signed char int8_t; 17 | typedef short int int16_t; 18 | typedef int int32_t; 19 | typedef long int int64_t; 20 | typedef long long int int64_t; 21 | typedef unsigned char uint8_t; 22 | typedef unsigned short int uint16_t; 23 | typedef unsigned int uint32_t; 24 | typedef unsigned long long int uint64_t; -------------------------------------------------------------------------------- /licence: -------------------------------------------------------------------------------- 1 | Copyright 2018 Alexandre Rouma (WhatsTheGeek) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /loader.asm: -------------------------------------------------------------------------------- 1 | /* Declare constants for the multiboot header. */ 2 | .set ALIGN, 1<<0 /* align loaded modules on page boundaries */ 3 | .set MEMINFO, 1<<1 /* provide memory map */ 4 | .set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */ 5 | .set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ 6 | .set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ 7 | 8 | .section .multiboot 9 | .align 4 10 | .long MAGIC 11 | .long FLAGS 12 | .long CHECKSUM 13 | 14 | .section .bss 15 | .align 16 16 | .global ASM_STACK_BOTTOM 17 | .global ASM_STACK_TOP 18 | ASM_STACK_BOTTOM: 19 | .skip 16384 # 16 KiB 20 | ASM_STACK_TOP: 21 | 22 | .section .text 23 | .global _start 24 | .type _start, @function 25 | _start: 26 | mov $ASM_STACK_TOP, %esp 27 | push %ebx 28 | push %eax 29 | call kernel_main 30 | cli 31 | 32 | _end: 33 | hlt 34 | jmp _end 35 | 36 | .size _start, . - _start 37 | 38 | .section .sizedetect 39 | .global ASM_KERNEL_END 40 | ASM_KERNEL_END: 41 | # Kernel size detection 42 | -------------------------------------------------------------------------------- /libs/kernel/multiboot.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct MultibootInfo_t{ 4 | uint32_t flags; 5 | uint32_t mem_lower; 6 | uint32_t mem_upper; 7 | uint32_t boot_devices; 8 | uint32_t cmdline; 9 | uint32_t mods_count; 10 | uint32_t mods_addr; 11 | uint32_t syms_num; 12 | uint32_t syms_size; 13 | uint32_t syms_addr; 14 | uint32_t syms_shndx; 15 | uint32_t mmap_length; 16 | uint32_t mmap_addr; 17 | uint32_t drives_length; 18 | uint32_t drives_addr; 19 | uint32_t config_table; 20 | char boot_loader_name[4]; 21 | uint32_t apm_table; 22 | uint32_t vbe_control_info; 23 | uint32_t vbe_mode_info; 24 | uint16_t vbe_mode; 25 | uint16_t vbe_interface_seg; 26 | uint16_t vbe_interface_off; 27 | uint16_t vbe_interface_len; 28 | uint64_t framebuffer_addr; 29 | uint32_t framebuffer_pitch; 30 | uint32_t framebuffer_width; 31 | uint32_t framebuffer_height; 32 | }; 33 | 34 | extern "C" 35 | { 36 | extern void ASM_KERNEL_END(void); 37 | extern void ASM_STACK_BOTTOM(void); 38 | extern void ASM_STACK_TOP(void); 39 | } -------------------------------------------------------------------------------- /drivers/text_term/terminal.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Terminal_Class { 6 | public: 7 | void Init(uint8_t width, uint8_t height); 8 | void setColor(char color); 9 | void putcar(char c, uint8_t x, uint8_t y); 10 | void print(char* str); 11 | void println(char* str); 12 | void print(string str); 13 | void println(string str); 14 | void setCursor(uint8_t x, uint8_t y); 15 | void clear(); 16 | void scrollUp(uint8_t n); 17 | void scrollDown(uint8_t n); 18 | void newLine(); 19 | void showCursor(uint8_t thickness); 20 | void hideCursor(); 21 | void OK(bool newLine = true); 22 | void WARN(bool newLine = true); 23 | void FAILED(bool newLine = true); 24 | uint8_t getWidth(); 25 | uint8_t getHeight(); 26 | uint8_t getCursorX(); 27 | uint8_t getCursorY(); 28 | string readLine(); 29 | 30 | stream outStream; 31 | private: 32 | static void _streamHandler(char*, int, Terminal_Class*); 33 | }; 34 | 35 | extern Terminal_Class Terminal; -------------------------------------------------------------------------------- /drivers/serial/src/serial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | Serial::Serial(uint16_t baud, uint16_t addr) { 6 | this->baudrate = baud; 7 | this->address = addr; 8 | uint8_t lcr = inb(addr + 0x03); 9 | lcr |= 0x80; 10 | outb(addr + 0x03, lcr); 11 | uint16_t divisor = 115200 / baud; 12 | outb(addr, divisor & 0x00FF); 13 | outb(addr + 0x01, (divisor >> 8) & 0x00FF); 14 | lcr = inb(addr + 0x03); 15 | lcr &= 0x7F; 16 | outb(addr + 0x03, lcr); 17 | outStream = stream(_streamHandler, this); 18 | } 19 | 20 | void Serial::print(char* str) { 21 | for (uint32_t i = 0; i < strlen(str); i++) { 22 | outb(this->address, str[i]); 23 | } 24 | } 25 | 26 | void Serial::println(char* str) { 27 | for (uint32_t i = 0; i < strlen(str); i++) { 28 | outb(this->address, str[i]); 29 | } 30 | outb(this->address, '\n'); 31 | } 32 | 33 | void Serial::write(char c) { 34 | outb(this->address, c); 35 | } 36 | 37 | void Serial::_streamHandler(char* str, int size, Serial* serial) { 38 | for (int i = 0; i < size; i++) { 39 | serial->write(str[i]); 40 | } 41 | } -------------------------------------------------------------------------------- /libs/kernel/io.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static inline uint8_t inb(uint16_t port) 4 | { 5 | uint8_t ret; 6 | asm volatile ( "inb %1, %0" 7 | : "=a"(ret) 8 | : "Nd"(port) ); 9 | return ret; 10 | } 11 | 12 | static inline void outb(uint16_t port, uint8_t val) 13 | { 14 | asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); 15 | } 16 | 17 | static inline uint16_t inw(uint16_t port) 18 | { 19 | uint16_t ret; 20 | asm volatile ( "inw %1, %0" 21 | : "=a"(ret) 22 | : "Nd"(port) ); 23 | return ret; 24 | } 25 | 26 | static inline void outw(uint16_t port, uint16_t val) 27 | { 28 | asm volatile ( "outw %0, %1" : : "a"(val), "Nd"(port) ); 29 | } 30 | 31 | static inline uint32_t inl(uint16_t port) 32 | { 33 | uint32_t ret; 34 | asm volatile ( "inl %1, %0" 35 | : "=a"(ret) 36 | : "Nd"(port) ); 37 | return ret; 38 | } 39 | 40 | static inline void outl(uint16_t port, uint32_t val) 41 | { 42 | asm volatile ( "outl %0, %1" : : "a"(val), "Nd"(port) ); 43 | } 44 | 45 | static inline void io_wait(void) 46 | { 47 | /* TODO: This is probably fragile. */ 48 | asm volatile ( "jmp 1f\n\t" 49 | "1:jmp 2f\n\t" 50 | "2:" ); 51 | } -------------------------------------------------------------------------------- /linker.ld: -------------------------------------------------------------------------------- 1 | /* The bootloader will look at this image and start execution at the symbol 2 | designated as the entry point. */ 3 | ENTRY(_start) 4 | 5 | /* Tell where the various sections of the object files will be put in the final 6 | kernel image. */ 7 | SECTIONS 8 | { 9 | /* Begin putting sections at 1 MiB, a conventional place for kernels to be 10 | loaded at by the bootloader. */ 11 | . = 1M; 12 | 13 | /* First put the multiboot header, as it is required to be put very early 14 | early in the image or the bootloader won't recognize the file format. 15 | Next we'll put the .text section. */ 16 | .text BLOCK(4K) : ALIGN(4K) 17 | { 18 | *(.multiboot) 19 | *(.text) 20 | } 21 | 22 | /* Read-only data. */ 23 | .rodata BLOCK(4K) : ALIGN(4K) 24 | { 25 | *(.rodata) 26 | } 27 | 28 | /* Read-write data (initialized) */ 29 | .data BLOCK(4K) : ALIGN(4K) 30 | { 31 | *(.data) 32 | } 33 | 34 | /* Read-write data (uninitialized) and stack */ 35 | .bss BLOCK(4K) : ALIGN(4K) 36 | { 37 | *(COMMON) 38 | *(.bss) 39 | } 40 | 41 | /* Kernel size detection */ 42 | .sizedetect BLOCK(4K) : ALIGN(4K) 43 | { 44 | *(.sizedetect) 45 | } 46 | 47 | /* The compiler may produce other sections, by default it will put them in 48 | a segment with the same name. Simply add stuff here as needed. */ 49 | } -------------------------------------------------------------------------------- /drivers/storage/floppy/src/floppy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const uint8_t IMPLIED_SEEK = 1; 5 | const uint8_t FIFO_DISABLE = 0; 6 | const uint8_t POLL_DISABLE = 1; 7 | const uint8_t THRESHOLD = 8; 8 | 9 | FloppyClass Floppy; 10 | 11 | bool FloppyClass::init() { 12 | outb(FD_REG_DATA_FIFO, FD_CMD_VERSION); 13 | if (inb(FD_REG_DATA_FIFO) != 0x90) { 14 | return false; 15 | } 16 | 17 | // Configuration 18 | outb(FD_REG_DATA_FIFO, FD_CMD_CONFIGURE); 19 | outb(FD_REG_DATA_FIFO, 0x00); 20 | uint8_t config = (IMPLIED_SEEK << 6) | (FIFO_DISABLE << 5) | (POLL_DISABLE << 4) | ((THRESHOLD - 1) & 0b00001111); 21 | outb(FD_REG_DATA_FIFO, config); 22 | outb(FD_REG_DATA_FIFO, 0x00); 23 | uint8_t dor = inb(FD_REG_DIGITAL_OUTPUT_REGISTER); 24 | dor |= 0x08; 25 | outb(FD_REG_DIGITAL_OUTPUT_REGISTER, dor); 26 | 27 | // Lock 28 | outb(FD_REG_DATA_FIFO, FD_CMD_LOCK); 29 | 30 | reset(); 31 | 32 | // TODO: Add recalibrate for each drive 33 | return true; 34 | } 35 | 36 | FloppyDrive_t FloppyClass::getDrive(uint32_t id) { 37 | FloppyDrive_t drv; 38 | return drv; 39 | } 40 | 41 | void FloppyClass::irq() { 42 | irq_rcv = true; 43 | } 44 | 45 | void FloppyClass::reset() { 46 | outb(FD_REG_DATARATE_SELECT_REGISTER, 0x80); 47 | } -------------------------------------------------------------------------------- /libs/_old/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class string { 6 | public: 7 | string(char* str); 8 | string(); 9 | ~string(); 10 | string operator+(string str); 11 | string operator+(char c); 12 | void operator+=(string str); 13 | void operator+=(char c); 14 | char operator[](uint32_t i); 15 | bool operator==(string str); 16 | bool operator!=(string str); 17 | bool operator==(char* str); 18 | bool operator!=(char* str); 19 | operator char*() const { return this->_str; } 20 | char* toCharArray(); 21 | uint32_t length(); 22 | void reserve(uint32_t len); 23 | string substring(uint32_t index); 24 | string substring(uint32_t index, uint32_t length); 25 | bool startsWith(string str); 26 | bool endWith(string str); 27 | string toUpper(); 28 | string toLower(); 29 | private: 30 | char* _str; 31 | }; 32 | 33 | uint32_t strlen(char* str); 34 | bool strcmp(char* str_a, char* str_b); 35 | void* memmove(void* dstptr, void* srcptr, uint64_t size); 36 | void* memcmp(void* aprt, void* bptr, uint64_t size); 37 | char* dumpHexByte(uint8_t n); 38 | string itoa(uint32_t n, uint8_t base); 39 | uint32_t strcnt(char* str, char c); 40 | int strfio(char* str, char c); 41 | char* substr(char* str, uint32_t index); -------------------------------------------------------------------------------- /libs/kernel/src/panic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void kernel_panic(uint16_t error_code, char* message) { 7 | asm("cli"); 8 | Terminal.hideCursor(); 9 | Terminal.setColor(0x4F); 10 | Terminal.clear(); 11 | Terminal.setColor(0x70); 12 | for (int x = 0; x < Terminal.getWidth(); x++) { 13 | Terminal.putcar(' ', x, 0); 14 | } 15 | for (int x = 0; x < Terminal.getWidth(); x++) { 16 | Terminal.putcar(' ', x, Terminal.getHeight() - 1); 17 | } 18 | Terminal.setCursor((Terminal.getWidth() / 2) - 6, 0); 19 | Terminal.print("KERNEL PANIC"); 20 | Terminal.setCursor(0, Terminal.getHeight() - 1); 21 | Terminal.print("ERROR CODE: 0x"); 22 | Terminal.print(dumpHexByte((error_code >> 24) & 0xFF)); 23 | Terminal.print(dumpHexByte((error_code >> 16) & 0xFF)); 24 | Terminal.print(dumpHexByte((error_code >> 8) & 0xFF)); 25 | Terminal.print(dumpHexByte(error_code & 0xFF)); 26 | Terminal.setColor(0x4F); 27 | Terminal.setCursor(2, 3); 28 | Terminal.println(message); 29 | Terminal.setCursor(2, 21); 30 | Terminal.setColor(0x4E); 31 | Terminal.println("OOPSIE WOOPSIE!! Uwu We made a fucky wucky!! A wittle fucko boingo! The code\n monkeys at our headquarters are working VEWY HAWD to fix this!"); 32 | 33 | for (;;) { 34 | asm("hlt"); 35 | } 36 | } -------------------------------------------------------------------------------- /libs/kernel/src/syscalls.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void syscall(uint32_t id, uint32_t ebx, uint32_t ecx, uint32_t edx) { 7 | asm("int $0x69" :: "a" (id), "b" (ebx), "c" (ecx), "d" (edx)); 8 | } 9 | 10 | void KERN_EXEC_SYSCALL(uint32_t id, uint32_t ebx, uint32_t ecx, uint32_t edx) { 11 | if (id == 0x00) { 12 | char* str = (char*)ebx; 13 | Terminal.print(str); 14 | } 15 | else { 16 | Terminal.print("Syscall!\nID: 0x"); 17 | Terminal.print(dumpHexByte(id >> 24)); 18 | Terminal.print(dumpHexByte(id >> 16)); 19 | Terminal.print(dumpHexByte(id >> 8)); 20 | Terminal.println(dumpHexByte(id >> 0)); 21 | 22 | Terminal.print("EBX: 0x"); 23 | Terminal.print(dumpHexByte(ebx >> 24)); 24 | Terminal.print(dumpHexByte(ebx >> 16)); 25 | Terminal.print(dumpHexByte(ebx >> 8)); 26 | Terminal.println(dumpHexByte(ebx >> 0)); 27 | 28 | Terminal.print("ECX: 0x"); 29 | Terminal.print(dumpHexByte(ecx >> 24)); 30 | Terminal.print(dumpHexByte(ecx >> 16)); 31 | Terminal.print(dumpHexByte(ecx >> 8)); 32 | Terminal.println(dumpHexByte(ecx >> 0)); 33 | 34 | Terminal.print("EDX: 0x"); 35 | Terminal.print(dumpHexByte(edx >> 24)); 36 | Terminal.print(dumpHexByte(edx >> 16)); 37 | Terminal.print(dumpHexByte(edx >> 8)); 38 | Terminal.println(dumpHexByte(edx >> 0)); 39 | } 40 | } -------------------------------------------------------------------------------- /libs/std/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class string { 6 | public: 7 | string(char* str); 8 | string(); 9 | ~string(); 10 | string operator+(string str); 11 | string operator+(char c); 12 | void operator+=(string str); 13 | void operator+=(char c); 14 | char operator[](uint32_t i); 15 | bool operator==(string str); 16 | bool operator!=(string str); 17 | bool operator==(char* str); 18 | bool operator!=(char* str); 19 | void operator=(string str); 20 | void operator=(char* str); 21 | //operator char*() const { return this->_str; } 22 | char* toCharArray(); 23 | uint32_t length(); 24 | void reserve(uint32_t len); 25 | string substring(uint32_t index); 26 | string substring(uint32_t index, uint32_t length); 27 | bool startsWith(string str); 28 | bool endWith(string str); 29 | string toUpper(); 30 | string toLower(); 31 | char* c_str(); 32 | 33 | private: 34 | char* _str; 35 | uint32_t _length; 36 | }; 37 | 38 | uint32_t strlen(char* str); 39 | bool strcmp(char* str_a, char* str_b); 40 | void* memmove(void* dstptr, void* srcptr, uint64_t size); 41 | bool memcmp(void* aptr, void* bptr, uint64_t size); 42 | void* memset(void* bufptr, uint8_t value, uint64_t size); 43 | char* dumpHexByte(uint8_t n); 44 | string itoa(uint32_t n, uint8_t base); 45 | uint32_t strcnt(char* str, char c); 46 | int strfio(char* str, char c); 47 | char* substr(char* str, uint32_t index); -------------------------------------------------------------------------------- /get_compiler.sh: -------------------------------------------------------------------------------- 1 | # Install requirements 2 | echo "Installing requirements..." 3 | sudo apt install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo 4 | 5 | # Configuration 6 | export PREFIX="$HOME/opt/cross" 7 | export TARGET=i686-elf 8 | export PATH="$PREFIX/bin:$PATH" 9 | 10 | # Create directories 11 | mkdir $HOME/src 12 | 13 | # Download binutils + gcc 14 | echo "Downloading binutils and gcc..." 15 | wget https://ftp.nluug.nl/pub/gnu/binutils/binutils-2.31.tar.xz -O $HOME/src/binutils-2.31.tar.xz 16 | wget https://ftp.gnu.org/gnu/gcc/gcc-8.2.0/gcc-8.2.0.tar.xz -O $HOME/src/gcc-8.2.0.tar.xz 17 | 18 | # Decompress 19 | echo "Decompressing..." 20 | cd $HOME/src 21 | tar -xf binutils-2.31.tar.xz 22 | tar -xf gcc-8.2.0.tar.xz 23 | 24 | # Build binutils 25 | echo "Building binutils..." 26 | cd $HOME/src 27 | mkdir build-binutils 28 | cd build-binutils 29 | ../binutils-2.31/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror 30 | make -j4 31 | make install 32 | 33 | # Build GCC 34 | echo "Building gcc..." 35 | cd $HOME/src 36 | which -- $TARGET-as || echo $TARGET-as is not in the PATH 37 | mkdir build-gcc 38 | cd build-gcc 39 | ../gcc-8.2.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers 40 | make all-gcc -j4 41 | make all-target-libgcc -j4 42 | make install-gcc 43 | make install-target-libgcc 44 | 45 | # Add GCC to path 46 | echo "Adding gcc to path..." 47 | echo export PATH=\"\$HOME/opt/cross/bin:\$PATH\" >> ~/.profile 48 | 49 | # Install grub + xorriso 50 | echo "Installing grub2 utils and xorriso..." 51 | sudo apt install grub2 xorriso 52 | 53 | # Done 54 | echo "Done!" -------------------------------------------------------------------------------- /libs/kernel/idt.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define IDT_ATTR_PRESENT 0x80 4 | #define IDT_ATTR_PRIV_3 0x60 5 | #define IDT_ATTR_PRIV_2 0x40 6 | #define IDT_ATTR_PRIV_1 0x20 7 | #define IDT_ATTR_TYPE_INT 0x0E 8 | #define IDT_ATTR_TYPE_TRAP 0x0F 9 | #define IDT_ATTR_TYPE_TASK 0x15 10 | 11 | class IDT_Class { 12 | public: 13 | void load(); 14 | }; 15 | 16 | extern "C" 17 | { 18 | extern void ASM_ISR_0(void); 19 | extern void ASM_ISR_PIT(void); 20 | extern void ASM_ISR_KBD(void); 21 | extern void ASM_ISR_FLOPPY(void); 22 | extern void ASM_ISR_SYSCALL(void); 23 | extern void _isr0(void); 24 | extern void _isr1(void); 25 | extern void _isr2(void); 26 | extern void _isr3(void); 27 | extern void _isr4(void); 28 | extern void _isr5(void); 29 | extern void _isr6(void); 30 | extern void _isr7(void); 31 | extern void _isr8(void); 32 | extern void _isr9(void); 33 | extern void _isr10(void); 34 | extern void _isr11(void); 35 | extern void _isr12(void); 36 | extern void _isr13(void); 37 | extern void _isr14(void); 38 | extern void _isr15(void); 39 | extern void _isr16(void); 40 | extern void _isr17(void); 41 | extern void _isr18(void); 42 | extern void _isr19(void); 43 | extern void _isr20(void); 44 | extern void _isr21(void); 45 | extern void _isr22(void); 46 | extern void _isr23(void); 47 | extern void _isr24(void); 48 | extern void _isr25(void); 49 | extern void _isr26(void); 50 | extern void _isr27(void); 51 | extern void _isr28(void); 52 | extern void _isr29(void); 53 | extern void _isr30(void); 54 | extern void _isr31(void); 55 | } 56 | 57 | extern IDT_Class IDT; -------------------------------------------------------------------------------- /libs/std/vector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | class vector { 8 | public: 9 | vector(); 10 | void push_back(T item); 11 | T pop_back(); 12 | void push_front(T item); 13 | T pop_front(); 14 | uint32_t size(); 15 | 16 | T & operator[](uint32_t index); 17 | 18 | //~vector(); 19 | 20 | private: 21 | T* _items; 22 | uint32_t itemCount = 0; 23 | }; 24 | 25 | template 26 | vector::vector() { 27 | _items = (T*)malloc(sizeof(T)); 28 | } 29 | 30 | // template 31 | // vector::~vector() { 32 | // free(_items); 33 | // itemCount = 0; 34 | // } 35 | 36 | template 37 | void vector::push_back(T item) { 38 | itemCount++; 39 | realloc(_items, itemCount * sizeof(T)); 40 | _items[itemCount - 1] = item; 41 | } 42 | 43 | template 44 | T vector::pop_back() { 45 | if (itemCount == 0) { 46 | return NULL; 47 | } 48 | itemCount--; 49 | T item = _items[itemCount]; 50 | realloc(_items, itemCount * sizeof(T)); 51 | return item; 52 | } 53 | 54 | template 55 | void vector::push_front(T item) { 56 | itemCount++; 57 | realloc(_items, itemCount * sizeof(T)); 58 | 59 | _items[0] = item; 60 | } 61 | 62 | template 63 | T vector::pop_front() { 64 | if (itemCount == 0) { 65 | return NULL; 66 | } 67 | itemCount--; 68 | T item = _items[0]; 69 | memmove(&_items[0], &_items[1], itemCount * sizeof(T)); 70 | realloc(_items, itemCount * sizeof(T)); 71 | return item; 72 | } 73 | 74 | template 75 | uint32_t vector::size() { 76 | return itemCount; 77 | } 78 | 79 | template 80 | T& vector::operator[](uint32_t index) { 81 | return _items[index]; 82 | } -------------------------------------------------------------------------------- /drivers/keyboard/keyboard.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct KeyboardEvent_t { 4 | uint8_t type; 5 | uint8_t keycode; 6 | }; 7 | 8 | class Keyboard_Class { 9 | public: 10 | void Init(); 11 | void update(); 12 | bool NumlockState; 13 | bool CapslockState; 14 | bool LSHIFTState; 15 | bool RSHIFTState; 16 | bool LCTRLState; 17 | bool RCTRLState; 18 | bool LALTState; 19 | bool ALTGRState; 20 | KeyboardEvent_t readEvent(bool wait); 21 | char getKeyChar(uint8_t keycode); 22 | struct _KEYCODES { 23 | enum _KEYCODES_ { 24 | ESC, K1, K2, K3, K4, K5, K6, K7, 25 | K8, K9, K0, MINUS, EQUAL, BACKSPACE, TAB, Q, 26 | W, E, R, T, Y, U, I, O, 27 | P, LBRACKET, RBRACKET, ENTER, LCTRL, A, S, D, 28 | F, G, H, J, K, L, SEMICOLMUMN, QUOTE, 29 | BACKTICK, LSHIFT, BACKSLASH, Z, X, C, V, B, 30 | N, M, COMMA, DOT, FSLASH, RSHIFT, KPMULT, LALT, 31 | SPACE, CAPSLOCK, F1, F2, F3, F4, F5, F6, 32 | F7, F8, F9, F10, NUMLOCK, SCRLOCK, KP7, KP8, 33 | KP9, KPMINUS, KP4, KP5, KP6, KPPLUS, KP1, KP2, 34 | KP3, KP0, KPDOT, F11, F12, MMPT, MMNT, KPENTER, 35 | RCTRL, MMMUTE, MMCALC, MMPLAY, MMSTOP, MMVD, MMVU,MMHOME, 36 | KPSLASH, ALTGR, HOME, UP, PGUP, LEFT, RIGHT, END, 37 | DOWN, PGDOWN, INSERT, DEL, LGUI, RGUI, APPS, POWER, 38 | SLEEP, WAKE, WWSEARCH, WWFAVORITE, WWREFRESH, WWSTOP, WWFORWARD, WWBACK, 39 | MMMY, MMEMAIL, MMSELECT 40 | }; 41 | } KEYCODES; 42 | struct _EVENTTYPES { 43 | enum _EVENTTYPES_ { 44 | INVALID, 45 | PRESSED, 46 | RELEASED 47 | }; 48 | } EVENTTYPES; 49 | }; 50 | 51 | extern Keyboard_Class Keyboard; -------------------------------------------------------------------------------- /libs/_old/gdt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define GDT_ENTRY_COUNT 256 7 | 8 | GDT_Class GDT; 9 | 10 | char _GDT[GDT_ENTRY_COUNT * 8]; 11 | 12 | void lgdt(void* base, uint16_t size) { // This function works in 32 and 64bit mode 13 | struct { 14 | uint16_t length; 15 | void* base; 16 | } __attribute__((packed)) GDTR = { size, base }; 17 | 18 | asm ( "lgdt %0" : : "m"(GDTR) ); // let the compiler choose an addressing mode 19 | } 20 | 21 | void encodeGdtEntry(uint32_t index, uint32_t base, uint32_t limit, uint8_t type) { 22 | char* target = &_GDT[index * 8]; 23 | 24 | target[6] = 0xD0; 25 | 26 | // Encode the limit 27 | target[0] = limit & 0xFF; 28 | target[1] = (limit >> 8) & 0xFF; 29 | target[6] |= (limit >> 16) & 0x0F; 30 | 31 | // Encode the base 32 | target[2] = base & 0xFF; 33 | target[3] = (base >> 8) & 0xFF; 34 | target[4] = (base >> 16) & 0xFF; 35 | target[7] = (base >> 24) & 0xFF; 36 | 37 | // And... Type 38 | target[5] = type; 39 | } 40 | 41 | void GDT_Class::load() { 42 | asm("cli"); 43 | encodeGdtEntry(0x00, 0x00000000, 0x00000000, 0x00); // Null descriptor 44 | encodeGdtEntry(0x01, 0x00000000, 0xFFFFFFFF, 0x9A); // Code 45 | encodeGdtEntry(0x02, 0x00000000, 0xFFFFFFFF, 0x92); // Data 46 | encodeGdtEntry(0x03, 0x00000000, 0x00000000, 0x96); // Stack 47 | encodeGdtEntry(0x04, (uint32_t)&kernel_tss, 0x67, 0xE9); // TSS 48 | 49 | initTss(); 50 | 51 | lgdt(&_GDT, sizeof(_GDT)); 52 | ASM_RELOAD_SEGMENTS(); 53 | 54 | asm(" movw $0x20, %ax \n \ 55 | ltr %ax"); 56 | 57 | asm(" movw %%ss, %0 \n \ 58 | movl %%esp, %1" : "=m" (kernel_tss.ss0), "=m" (kernel_tss.esp0) : ); 59 | } 60 | 61 | void GDT_Class::setGDTEntry(uint32_t index, uint32_t base, uint32_t limit, uint8_t type) { 62 | encodeGdtEntry(index, base, limit, type); 63 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build", 8 | "type": "shell", 9 | "command": "bash --login -c 'cd build && make -j8'", 10 | "group": { 11 | "kind": "build", 12 | "isDefault": true 13 | }, 14 | "problemMatcher": [] 15 | }, 16 | { 17 | "label": "Build (With ISO)", 18 | "type": "shell", 19 | "command": "bash --login -c 'cd build && make -j8 iso'", 20 | "group": { 21 | "kind": "test", 22 | "isDefault": true, 23 | }, 24 | "problemMatcher": [] 25 | }, 26 | { 27 | "label": "Run", 28 | "type": "shell", 29 | "command": "bash --login -c 'cd build && make -j8'; &('C:/Program Files/qemu/qemu-system-i386') -kernel build/MemeOS.bin -serial mon:stdio -drive file=hda.img,format=raw", 30 | "group": { 31 | "kind": "test", 32 | "isDefault": true 33 | } 34 | }, 35 | { 36 | "label": "Run (With ISO)", 37 | "type": "shell", 38 | "command": "bash --login -c 'cd build && make -j8 iso'; &('C:/Program Files/qemu/qemu-system-i386') -cdrom build/MemeOS.iso -serial mon:stdio -drive file=hda.img,format=raw", 39 | "group": { 40 | "kind": "test", 41 | "isDefault": true 42 | } 43 | }, 44 | { 45 | "label": "Run in BOCHS (Rqrs. ISO)", 46 | "type": "shell", 47 | "command": "bash --login -c 'cd build && make -j8 iso'; &('C:/Program Files (x86)/Bochs-2.6.9/bochsdbg.exe') -f bochsrc.bxrc -q", 48 | "group": { 49 | "kind": "test", 50 | "isDefault": true 51 | } 52 | } 53 | ] 54 | } -------------------------------------------------------------------------------- /libs/std/stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | class iostream { 8 | public: 9 | inline iostream() { 10 | 11 | } 12 | virtual int read(T* buf, int size) { 13 | return read(buf, size); 14 | } 15 | virtual int write(T* buf, int size) { 16 | return write(buf, size); 17 | } 18 | virtual void flush() { 19 | flush(); 20 | } 21 | }; 22 | 23 | template 24 | class stream : public iostream { 25 | public: 26 | stream(); 27 | stream(void (*handler)(T*, int, D*), D* args, int buffer_size = 1); 28 | int read(T* buf, int size); 29 | int write(T* buf, int size); 30 | void flush(); 31 | 32 | private: 33 | T _item_unb; 34 | T* _items; 35 | uint32_t itemCount = 0; 36 | uint32_t bufferSize = 0; 37 | void (*_handler)(T*, int, D*); 38 | D* _args = nullptr; 39 | }; 40 | 41 | template 42 | stream::stream() { 43 | bufferSize = 0; 44 | } 45 | 46 | template 47 | stream::stream(void (*handler)(T*, int, D*), D* args, int buffer_size) { 48 | bufferSize = buffer_size; 49 | _handler = handler; 50 | _args = args; 51 | if (buffer_size <= 1) { 52 | _items = &_item_unb; 53 | } 54 | else { 55 | _items = (T*)malloc(buffer_size); 56 | } 57 | } 58 | 59 | template 60 | int stream::read(T* buf, int size) { 61 | if (size == 0 || bufferSize == 0) { 62 | return -1; 63 | } 64 | if (size > itemCount) { 65 | size = itemCount; 66 | } 67 | memmove(buf, _items, size); 68 | return size; 69 | } 70 | 71 | template 72 | int stream::write(T* buf, int size) { 73 | if (size <= 0 || bufferSize == 0) { 74 | return -1; 75 | } 76 | for (int i = 0; i < size; i++) { 77 | _items[itemCount] = buf[i]; 78 | itemCount++; 79 | if (itemCount == bufferSize) { 80 | flush(); 81 | } 82 | } 83 | return size; 84 | } 85 | 86 | template 87 | void stream::flush() { 88 | if (bufferSize == 0) { 89 | return; 90 | } 91 | 92 | _handler(_items, itemCount, _args); 93 | itemCount = 0; 94 | } -------------------------------------------------------------------------------- /bochsrc.bxrc: -------------------------------------------------------------------------------- 1 | # configuration file generated by Bochs 2 | plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, gameport=1 3 | config_interface: win32config 4 | display_library: win32 5 | memory: host=32, guest=32 6 | romimage: file="C:\Program Files (x86)\Bochs-2.6.9/BIOS-bochs-latest", address=0x0, options=none 7 | vgaromimage: file="C:\Program Files (x86)\Bochs-2.6.9/VGABIOS-lgpl-latest" 8 | boot: cdrom 9 | floppy_bootsig_check: disabled=0 10 | # no floppya 11 | # no floppyb 12 | ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 13 | ata0-master: type=cdrom, path="D:\Documents\GitHub\MemeOS\build\MemeOS.iso", status=inserted, model="Generic 1234", biosdetect=auto 14 | ata0-slave: type=none 15 | ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 16 | ata1-master: type=none 17 | ata1-slave: type=none 18 | ata2: enabled=0 19 | ata3: enabled=0 20 | optromimage1: file=none 21 | optromimage2: file=none 22 | optromimage3: file=none 23 | optromimage4: file=none 24 | optramimage1: file=none 25 | optramimage2: file=none 26 | optramimage3: file=none 27 | optramimage4: file=none 28 | pci: enabled=1, chipset=i440fx 29 | vga: extension=vbe, update_freq=5, realtime=1 30 | cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 31 | cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string=" Intel(R) Pentium(R) 4 CPU " 32 | cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0 33 | cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0 34 | cpuid: smep=0, smap=0, mwait=1, vmx=1 35 | print_timestamps: enabled=0 36 | port_e9_hack: enabled=0 37 | private_colormap: enabled=0 38 | clock: sync=none, time0=local, rtc_sync=0 39 | # no cmosimage 40 | # no loader 41 | log: - 42 | logprefix: %t%e%d 43 | debug: action=ignore 44 | info: action=report 45 | error: action=report 46 | panic: action=ask 47 | keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none 48 | mouse: type=ps2, enabled=0, toggle=ctrl+mbutton 49 | sound: waveoutdrv=win, waveout=none, waveindrv=win, wavein=none, midioutdrv=win, midiout=none 50 | speaker: enabled=1, mode=sound 51 | parport1: enabled=1, file=none 52 | parport2: enabled=0 53 | com1: enabled=1, mode=null 54 | com2: enabled=0 55 | com3: enabled=0 56 | com4: enabled=0 -------------------------------------------------------------------------------- /drivers/storage/floppy/floppy.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum FloppyRegisters 4 | { 5 | FD_REG_STATUS_REGISTER_A = 0x3F0, 6 | FD_REG_STATUS_REGISTER_B = 0x3F1, 7 | FD_REG_DIGITAL_OUTPUT_REGISTER = 0x3F2, 8 | FD_REG_TAPE_DRIVE_REGISTER = 0x3F3, 9 | FD_REG_MAIN_STATUS_REGISTER = 0x3F4, 10 | FD_REG_DATARATE_SELECT_REGISTER = 0x3F4, 11 | FD_REG_DATA_FIFO = 0x3F5, 12 | FD_REG_DIGITAL_INPUT_REGISTER = 0x3F7, 13 | FD_REG_CONFIGURATION_CONTROL_REGISTER = 0x3F7 14 | }; 15 | 16 | enum FloppyCommands 17 | { 18 | FD_CMD_READ_TRACK = 2, // generates IRQ6 19 | FD_CMD_SPECIFY = 3, // * set drive parameters 20 | FD_CMD_SENSE_DRIVE_STATUS = 4, 21 | FD_CMD_WRITE_DATA = 5, // * write to the disk 22 | FD_CMD_READ_DATA = 6, // * read from the disk 23 | FD_CMD_RECALIBRATE = 7, // * seek to cylinder 0 24 | FD_CMD_SENSE_INTERRUPT = 8, // * ack IRQ6, get status of last command 25 | FD_CMD_WRITE_DELETED_DATA = 9, 26 | FD_CMD_READ_ID = 10, // generates IRQ6 27 | FD_CMD_READ_DELETED_DATA = 12, 28 | FD_CMD_FORMAT_TRACK = 13, // * 29 | FD_CMD_DUMPREG = 14, 30 | FD_CMD_SEEK = 15, // * seek both heads to cylinder X 31 | FD_CMD_VERSION = 16, // * used during initialization, once 32 | FD_CMD_SCAN_EQUAL = 17, 33 | FD_CMD_PERPENDICULAR_MODE = 18, // * used during initialization, once, maybe 34 | FD_CMD_CONFIGURE = 19, // * set controller parameters 35 | FD_CMD_LOCK = 20, // * protect controller params from a reset 36 | FD_CMD_VERIFY = 22, 37 | FD_CMD_SCAN_LOW_OR_EQUAL = 25, 38 | FD_CMD_SCAN_HIGH_OR_EQUAL = 29 39 | }; 40 | 41 | class FloppyDrive_t { 42 | public: 43 | uint8_t id; 44 | 45 | private: 46 | 47 | }; 48 | 49 | class FloppyClass { 50 | public: 51 | bool init(); 52 | FloppyDrive_t getDrive(uint32_t id); 53 | void irq(); 54 | void reset(); 55 | 56 | private: 57 | bool irq_rcv = false; 58 | FloppyDrive_t* _drives; 59 | uint32_t _driveCount; 60 | }; 61 | 62 | extern FloppyClass Floppy; -------------------------------------------------------------------------------- /libs/kernel/src/c_isr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define BochsBreak() outw(0x8A00,0x8A00); outw(0x8A00,0x08AE0); 11 | 12 | /* This defines what the stack looks like after an ISR was running */ 13 | struct regs 14 | { 15 | unsigned int gs, fs, es, ds; /* pushed the segs last */ 16 | unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ 17 | unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ 18 | unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ 19 | }; 20 | 21 | char *exception_messages[] ={ 22 | "Division By Zero", 23 | "Debug", 24 | "Non Maskable Interrupt", 25 | "Break Point", 26 | "Into Detect Overflow", 27 | "Out of bounds Exception", 28 | "Invalid Opcode", 29 | "No Coprocessor", 30 | "Double Fault", 31 | "Coprocessor Segment Overrun", 32 | "Bad TSS Exception", 33 | "Segment not present", 34 | "Stack Fault", 35 | "General Protection Fault", 36 | "Page Fault", 37 | "Unknown Interrupt", 38 | "Coprocessor Fault", 39 | "Alignement Check Exception", 40 | "Machine Check Exception", 41 | "Reserved", 42 | "Reserved", 43 | "Reserved", 44 | "Reserved", 45 | "Reserved", 46 | "Reserved", 47 | "Reserved", 48 | "Reserved", 49 | "Reserved", 50 | "Reserved", 51 | "Reserved", 52 | "Reserved", 53 | "Reserved" 54 | }; 55 | 56 | extern "C" 57 | { 58 | void ISR_0(void) { 59 | outb(0x20,0x20); // STFU no one cares XD 60 | } 61 | 62 | void ISR_PIT(void) { 63 | outb(0x20,0x20); 64 | PIT.system_ticks++; 65 | } 66 | 67 | void ISR_KBD(void) { 68 | Keyboard.update(); 69 | outb(0x20,0x20); 70 | } 71 | 72 | void ISR_FLOPPY(void) { 73 | Floppy.irq(); 74 | outb(0x20,0x20); 75 | } 76 | 77 | void ISR_SYSCALL(uint32_t id, uint32_t ebx, uint32_t ecx, uint32_t edx) { 78 | KERN_EXEC_SYSCALL(id, ebx, ecx, edx); 79 | } 80 | 81 | void _fault_handler(struct regs *r) { 82 | if (r->int_no < 32) 83 | { 84 | uint32_t val; 85 | asm volatile ( "mov %%cr2, %0" : "=r"(val) ); 86 | kernel_panic(val, exception_messages[r->int_no]); 87 | for (;;); 88 | } 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /libs/kernel/liballoc.h: -------------------------------------------------------------------------------- 1 | // All rights reserved to liballoc, I'm too lazy to make a memory manager lol 2 | 3 | #ifndef _LIBALLOC_H 4 | #define _LIBALLOC_H 5 | 6 | 7 | 8 | // If we are told to not define our own size_t, then we 9 | // skip the define. 10 | #ifndef _ALLOC_SKIP_DEFINE 11 | 12 | #ifndef _HAVE_SIZE_T 13 | #define _HAVE_SIZE_T 14 | typedef unsigned int size_t; 15 | #endif 16 | 17 | 18 | #ifndef NULL 19 | #define NULL 0 20 | #endif 21 | 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | 29 | /** This is a boundary tag which is prepended to the 30 | * page or section of a page which we have allocated. It is 31 | * used to identify valid memory blocks that the 32 | * application is trying to free. 33 | */ 34 | struct boundary_tag 35 | { 36 | unsigned int magic; //< It's a kind of ... 37 | unsigned int size; //< Requested size. 38 | unsigned int real_size; //< Actual size. 39 | int index; //< Location in the page table. 40 | 41 | struct boundary_tag *split_left; //< Linked-list info for broken pages. 42 | struct boundary_tag *split_right; //< The same. 43 | 44 | struct boundary_tag *next; //< Linked list info. 45 | struct boundary_tag *prev; //< Linked list info. 46 | }; 47 | 48 | 49 | 50 | 51 | /** This function is supposed to lock the memory data structures. It 52 | * could be as simple as disabling interrupts or acquiring a spinlock. 53 | * It's up to you to decide. 54 | * 55 | * \return 0 if the lock was acquired successfully. Anything else is 56 | * failure. 57 | */ 58 | extern int liballoc_lock(); 59 | 60 | /** This function unlocks what was previously locked by the liballoc_lock 61 | * function. If it disabled interrupts, it enables interrupts. If it 62 | * had acquiried a spinlock, it releases the spinlock. etc. 63 | * 64 | * \return 0 if the lock was successfully released. 65 | */ 66 | extern int liballoc_unlock(); 67 | 68 | /** This is the hook into the local system which allocates pages. It 69 | * accepts an integer parameter which is the number of pages 70 | * required. The page size was set up in the liballoc_init function. 71 | * 72 | * \return NULL if the pages were not allocated. 73 | * \return A pointer to the allocated memory. 74 | */ 75 | extern void* liballoc_alloc(int); 76 | 77 | /** This frees previously allocated memory. The void* parameter passed 78 | * to the function is the exact same value returned from a previous 79 | * liballoc_alloc call. 80 | * 81 | * The integer value is the number of pages to free. 82 | * 83 | * \return 0 if the memory was successfully freed. 84 | */ 85 | extern int liballoc_free(void*,int); 86 | 87 | 88 | 89 | void *malloc(size_t); //< The standard function. 90 | void *realloc(void *, size_t); //< The standard function. 91 | void *calloc(size_t, size_t); //< The standard function. 92 | void free(void *); //< The standard function. 93 | 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif -------------------------------------------------------------------------------- /libs/_old/ahci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | AHCI_Class AHCI; 10 | 11 | int getCommandSlot(HBAPort_t* port) { 12 | for (int i = 0; i < 32; i++) { 13 | if ((port->ci >> i) & 1 == 0) { 14 | port->ci |= 1 << i; 15 | return i; 16 | } 17 | } 18 | return -1; 19 | } 20 | 21 | uint8_t checkPort(HBAPort_t* port) { 22 | uint32_t ssts = port->ssts; 23 | uint8_t ipm = (ssts >> 8) & 0x0F; 24 | uint8_t det = ssts & 0x0F; 25 | 26 | if (det != HBA_PORT_DET_PRESENT || ipm != HBA_PORT_IPM_ACTIVE) { 27 | return AHCI_DEV_NULL; 28 | } 29 | 30 | switch (port->sig) 31 | { 32 | case SATA_SIG_ATAPI: 33 | return AHCI_DEV_SATAPI; 34 | case SATA_SIG_SEMB: 35 | return AHCI_DEV_SEMB; 36 | case SATA_SIG_PM: 37 | return AHCI_DEV_PM; 38 | default: 39 | return AHCI_DEV_SATA; 40 | } 41 | } 42 | 43 | void AHCI_Class::scanControllers() { 44 | _ahciControllers = (ACHIController_t*)malloc(sizeof(ACHIController_t)); 45 | for (uint8_t id = 0; id < PCI.getDeviceCount(); id++) { 46 | PCIDevice_t dev = PCI.getDevice(id); 47 | if (dev.classCode == 0x01 && dev.subclass == 0x06) { 48 | ACHIController_t cnt; 49 | cnt.pciDevice = dev; 50 | cnt.drives = (ACHIDrive_t*)malloc(sizeof(ACHIDrive_t)); 51 | Paging.setPresent(dev.standardHeader.BAR5, (sizeof(HBAMem_t) / 4096) + 1); 52 | cnt.hbaMem = (HBAMem_t*)dev.standardHeader.BAR5; 53 | for (uint8_t i = 0; i < 32; i++) { 54 | if ((cnt.hbaMem->pi >> i) & 1 == 1) { 55 | uint8_t drvType = checkPort(&cnt.hbaMem->ports[i]); 56 | if (drvType != AHCI_DEV_NULL) { 57 | 58 | ACHIDrive_t drv; 59 | drv.port = &cnt.hbaMem->ports[i]; 60 | drv.type = drvType; 61 | drv.controllerID = _controllerCount; 62 | cnt.driveCount++; 63 | cnt.drives = (ACHIDrive_t*)realloc(cnt.drives, sizeof(ACHIDrive_t) * cnt.driveCount); 64 | cnt.drives[cnt.driveCount - 1] = drv; 65 | Terminal.println(itoa(getCommandSlot(&cnt.hbaMem->ports[i]), 16)); 66 | } 67 | } 68 | } 69 | _controllerCount++; 70 | _ahciControllers = (ACHIController_t*)realloc(_ahciControllers, sizeof(ACHIController_t) * _controllerCount); 71 | _ahciControllers[_controllerCount - 1] = cnt; 72 | } 73 | } 74 | } 75 | 76 | uint32_t AHCI_Class::getControllerCount() { 77 | return _controllerCount; 78 | } 79 | 80 | ACHIController_t AHCI_Class::getController(uint32_t id) { 81 | if (id < _controllerCount) { 82 | return _ahciControllers[id]; 83 | } 84 | else { 85 | ACHIController_t invalid; 86 | invalid.pciDevice.vendorID = 0xFFFF; 87 | return invalid; 88 | } 89 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | project(MemeOS) 3 | 4 | enable_language(ASM) 5 | 6 | set(CMAKE_ASM_COMPILER "i686-elf-as") 7 | set(CMAKE_C_COMPILER "i686-elf-gcc") 8 | set(CMAKE_CXX_COMPILER "i686-elf-g++") 9 | 10 | set(CMAKE_CXX_FLAGS "-ffreestanding -O2 -fno-rtti -Wno-write-strings -Wno-multichar -Wno-unused-parameter -Wno-overflow -Wno-narrowing -fno-exceptions -Wno-trigraphs ${CMAKE_CXX_FLAGS}") 11 | set(CMAKE_EXE_LINKER_FLAGS "-T ../linker.ld -ffreestanding -O2 -nostdlib -lgcc -Wwrite-strings ${CMAKE_EXE_LINKER_FLAGS}") 12 | 13 | include_directories(MemeOS "./") 14 | 15 | # Kernel source 16 | file(GLOB KERN_SRC "*.cpp" "*.asm") 17 | 18 | if(${ARCH} STREQUAL "x86") 19 | # Configure code 20 | 21 | # Driver source 22 | file(GLOB DRV_FS_EXT2 "drivers/filesystems/ext2/src/*.cpp" "drivers/filesystems/ext2/src/*.asm") 23 | file(GLOB DRV_KEYBOARD "drivers/keyboard/src/*.cpp" "drivers/keyboard/src/*.asm") 24 | file(GLOB DRV_PC_SPKR "drivers/pc_speaker/src/*.cpp" "drivers/pc_speaker/src/*.asm") 25 | file(GLOB DRV_PCI "drivers/pci/src/*.cpp" "drivers/pci/src/*.asm") 26 | file(GLOB DRV_RTC "drivers/rtc/src/*.cpp" "drivers/rtc/src/*.asm") 27 | file(GLOB DRV_SERIAL "drivers/serial/src/*.cpp" "drivers/serial/src/*.asm") 28 | file(GLOB DRV_ST_AHCI "drivers/storage/ahci/src/*.cpp" "drivers/storage/ahci/src/*.asm") 29 | file(GLOB DRV_ST_ATAPIO "drivers/storage/atapio/src/*.cpp" "drivers/storage/atapio/src/*.asm") 30 | file(GLOB DRV_ST_FLOPPY "drivers/storage/floppy/src/*.cpp" "drivers/storage/floppy/src/*.asm") 31 | file(GLOB DRV_TEXT_TERM "drivers/text_term/src/*.cpp" "drivers/text_term/src/*.asm") 32 | file(GLOB DRV_TIMER "drivers/timer/src/*.cpp" "drivers/timer/src/*.asm") 33 | 34 | # Library source 35 | file(GLOB LIB_KERNEL "libs/kernel/src/*.cpp" "libs/kernel/src/*.asm") 36 | file(GLOB LIB_STD "libs/std/src/*.cpp" "libs/std/src/*.asm") 37 | file(GLOB LIB_SYS "libs/sys/src/*.cpp" "libs/sys/src/*.asm") 38 | 39 | # Shell source 40 | file(GLOB SHELL_SRC "shell/*.cpp" "shell/*.asm") 41 | 42 | set(SRCS ${KERN_SRC} ${DRV_FS_EXT2} ${DRV_KEYBOARD} ${DRV_PC_SPKR} ${DRV_PCI} 43 | ${DRV_RTC} ${DRV_SERIAL} ${DRV_ST_AHCI} ${DRV_ST_ATAPIO} ${DRV_ST_FLOPPY} 44 | ${DRV_TEXT_TERM} ${DRV_TIMER} ${LIB_KERNEL} ${LIB_STD} ${LIB_SYS} 45 | ${SHELL_SRC}) 46 | elseif(${ARCH} STREQUAL "arm") 47 | set(SRCS ${KERN_SRC}) 48 | elseif(${ARCH} STREQUAL "nspire") 49 | set(SRCS ${KERN_SRC}) 50 | endif(${ARCH} STREQUAL "arm") 51 | 52 | 53 | 54 | add_executable(MemeOS ${SRCS}) 55 | 56 | 57 | set_target_properties(MemeOS PROPERTIES OUTPUT_NAME "MemeOS.bin") 58 | #set_target_properties(MemeOS PROPERTIES LINK_DEPENDS "../linker.ld") 59 | 60 | #add_custom_command(TARGET MemeOS POST_BUILD COMMAND cp MemeOS.bin ../ISO/boot/MemeOS && grub-mkrescue -o MemeOS.iso ../ISO) 61 | add_custom_target(iso COMMAND cp MemeOS.bin ../ISO/boot/MemeOS && grub-mkrescue -o MemeOS.iso ../ISO) 62 | add_dependencies(iso MemeOS) 63 | 64 | #add_custom_command(TARGET MemeOS POST_BUILD COMMAND genzehn --input tiapp.elf --output tiapp.tns --name "helloworld-cpp") -------------------------------------------------------------------------------- /libs/kernel/src/gdt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define GDT_ENTRY_COUNT 256 10 | 11 | GDT_Class GDT; 12 | 13 | // Note: Not sure about the endianess :/ May cause weird ass bugs 14 | struct GDTEntry_t { 15 | uint16_t limit_0; 16 | uint16_t base_0; 17 | uint8_t base_1; 18 | uint8_t access; 19 | uint8_t limit_1:4; 20 | uint8_t flags:4; 21 | uint8_t base_2; 22 | } __attribute__((packed)); 23 | 24 | GDTEntry_t _GDT[GDT_ENTRY_COUNT]; 25 | 26 | void lgdt(void* base, uint16_t size) { // This function works in 32 and 64bit mode 27 | struct { 28 | uint16_t length; 29 | void* base; 30 | } __attribute__((packed)) GDTR = { size, base }; 31 | 32 | asm ( "lgdt %0" : : "m"(GDTR) ); // let the compiler choose an addressing mode 33 | } 34 | 35 | void encodeGdtEntry(uint32_t index, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags) { 36 | _GDT[index].base_0 = (base >> 0) & 0xFFFF; 37 | _GDT[index].base_1 = (base >> 16) & 0xFF; 38 | _GDT[index].base_2 = (base >> 24) & 0xFF; 39 | _GDT[index].limit_0 = (limit >> 0) & 0xFFFF; 40 | _GDT[index].limit_1 = (limit >> 16) & 0x0F; 41 | _GDT[index].access = access; 42 | _GDT[index].flags = flags & 0x0F; 43 | } 44 | 45 | void GDT_Class::load() { 46 | asm("cli"); 47 | 48 | // Clear GDT 49 | memset(&_GDT, 0x00, sizeof(_GDT)); 50 | 51 | // Code 52 | encodeGdtEntry(0x01, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); 53 | 54 | // Data 55 | encodeGdtEntry(0x02, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); 56 | 57 | // Stack 58 | encodeGdtEntry(0x03, 0x00000000, 0x00000000, GDT_ACCESS_PRESENT | GDT_ACCESS_RW | GDT_ACCESS_DIR_D, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); 59 | 60 | // TSS 61 | encodeGdtEntry(0x04, (uint32_t)&kernel_tss, 0x68, GDT_ACCESS_PR_TSS | GDT_ACCESS_EXEC | GDT_ACCESS_ACCESSED | GDT_ACCESS_PRIV_3, GDT_FLAG_SZ_32B); 62 | 63 | lgdt(&_GDT, sizeof(_GDT)); 64 | ASM_RELOAD_SEGMENTS(); 65 | } 66 | 67 | void GDT_Class::setGDTEntry(uint32_t index, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags) { 68 | encodeGdtEntry(index, base, limit, access, flags); 69 | } 70 | 71 | uint32_t GDT_Class::findFreeEntry() { 72 | uint8_t dummy[8]; 73 | memset(&dummy, 0x00, 0x08); 74 | for (uint32_t i = 1; i < GDT_ENTRY_COUNT; i++) { 75 | GDTEntry_t e = _GDT[i]; 76 | if (memcmp(&_GDT[i], &dummy, 0x08)) { 77 | return i; 78 | } 79 | } 80 | return 0; 81 | } 82 | 83 | uint32_t GDT_Class::allocEntry(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags) { 84 | uint32_t index = findFreeEntry(); 85 | if (index == 0) { 86 | kernel_panic(0x1111, "Ran out of GDT entries :("); 87 | return 0; 88 | } 89 | setGDTEntry(index, base, limit, access, flags); 90 | return index; 91 | } 92 | 93 | void GDT_Class::freeEntry(uint32_t index) { 94 | memset(&_GDT[index], 0x00, 0x08); 95 | } -------------------------------------------------------------------------------- /drivers/pci/pci.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #define PCI_CONFIG_ADDRESS 0x0CF8 6 | #define PCI_CONFIG_DATA 0x0CFC 7 | 8 | struct PCIStandardHeader_t { 9 | uint32_t BAR0; 10 | uint32_t BAR1; 11 | uint32_t BAR2; 12 | uint32_t BAR3; 13 | uint32_t BAR4; 14 | uint32_t BAR5; 15 | uint32_t cardbusCISPtr; 16 | uint16_t subsysVendorID; 17 | uint16_t subsysID; 18 | uint32_t expROMAddr; 19 | uint8_t capPtr; 20 | uint8_t intLine; 21 | uint8_t intPIN; 22 | uint8_t minGrant; 23 | uint8_t maxLantency; 24 | }; 25 | 26 | struct PCIP2PHeader_t { 27 | uint32_t BAR0; 28 | uint32_t BAR1; 29 | uint8_t primBusNumber; 30 | uint8_t secBusNumber; 31 | uint8_t subBusNumber; 32 | uint8_t secLatencyTimer; 33 | uint8_t ioBase; 34 | uint8_t ioLimit; 35 | uint16_t secStatus; 36 | uint16_t memBase; 37 | uint16_t memLimit; 38 | uint16_t prefetchMemBase; 39 | uint16_t prefetchMemLimit; 40 | uint32_t prefetchBaseUpper; 41 | uint32_t prefetchLimitUpper; 42 | uint16_t ioBaseUpper; 43 | uint16_t ioLimitUpper; 44 | uint8_t capPtr; 45 | uint8_t intLine; 46 | uint8_t intPIN; 47 | }; 48 | 49 | struct PCIP2CHeader_t { 50 | uint32_t cardbusBaseAddr; 51 | uint8_t capListOffset; 52 | uint16_t secStatus; 53 | uint8_t pciBusNumber; 54 | uint8_t cardbusBusNuber; 55 | uint8_t subBusNumber; 56 | uint8_t cardbusLatTimer; 57 | uint32_t memBaseAddr0; 58 | uint32_t memLimit0; 59 | uint32_t memBaseAddr1; 60 | uint32_t memLimit1; 61 | uint32_t ioBaseAddr0; 62 | uint32_t ioLimit0; 63 | uint32_t ioBaseAddr1; 64 | uint32_t ioLimit1; 65 | uint8_t intLine; 66 | uint8_t intPIN; 67 | uint16_t subsysDeviceID; 68 | uint16_t subsysVendorID; 69 | uint32_t legacyBaseAddr; 70 | }; 71 | 72 | struct PCIDevice_t { 73 | uint8_t bus; 74 | uint8_t slot; 75 | uint8_t function; 76 | uint16_t vendorID; 77 | uint16_t deviceID; 78 | uint8_t revisionID; 79 | uint8_t progIF; 80 | uint8_t subclass; 81 | uint8_t classCode; 82 | uint8_t cacheLineSize; 83 | uint8_t latencyTimer; 84 | uint8_t headerType; 85 | uint8_t bist; 86 | char* vendorShortName; 87 | char* vendorFullName; 88 | char* deviceChip; 89 | char* deviceChipDesc; 90 | PCIStandardHeader_t standardHeader; // headerType = 0x00 91 | PCIP2PHeader_t pciToPciHeader; // headerType = 0x01 92 | PCIP2CHeader_t pciToCardbusHeader; // headerType = 0x02 93 | }; 94 | 95 | class PCI_Class { 96 | public: 97 | uint16_t getVendorID(uint8_t bus, uint8_t slot, uint8_t function); 98 | char* getVendorShortName(uint16_t vendorID); 99 | char* getVendorFullName(uint16_t vendorID); 100 | uint16_t getDeviceID(uint8_t bus, uint8_t slot, uint8_t function); 101 | char* getDeviceName(uint16_t vendorID, uint16_t deviceID); 102 | char* getDeviceDescription(uint16_t vendorID, uint16_t deviceID); 103 | PCIDevice_t getDevice(uint8_t bus, uint8_t slot, uint8_t function); 104 | PCIDevice_t getDevice(uint32_t id); 105 | void scanDevices(); 106 | uint32_t getDeviceCount(); 107 | 108 | private: 109 | vector _devices; 110 | }; 111 | 112 | extern PCI_Class PCI; -------------------------------------------------------------------------------- /libs/_old/pci.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #define PCI_CONFIG_ADDRESS 0x0CF8 6 | #define PCI_CONFIG_DATA 0x0CFC 7 | 8 | struct PCIStandardHeader_t { 9 | uint32_t BAR0; 10 | uint32_t BAR1; 11 | uint32_t BAR2; 12 | uint32_t BAR3; 13 | uint32_t BAR4; 14 | uint32_t BAR5; 15 | uint32_t cardbusCISPtr; 16 | uint16_t subsysVendorID; 17 | uint16_t subsysID; 18 | uint32_t expROMAddr; 19 | uint8_t capPtr; 20 | uint8_t intLine; 21 | uint8_t intPIN; 22 | uint8_t minGrant; 23 | uint8_t maxLantency; 24 | }; 25 | 26 | struct PCIP2PHeader_t { 27 | uint32_t BAR0; 28 | uint32_t BAR1; 29 | uint8_t primBusNumber; 30 | uint8_t secBusNumber; 31 | uint8_t subBusNumber; 32 | uint8_t secLatencyTimer; 33 | uint8_t ioBase; 34 | uint8_t ioLimit; 35 | uint16_t secStatus; 36 | uint16_t memBase; 37 | uint16_t memLimit; 38 | uint16_t prefetchMemBase; 39 | uint16_t prefetchMemLimit; 40 | uint32_t prefetchBaseUpper; 41 | uint32_t prefetchLimitUpper; 42 | uint16_t ioBaseUpper; 43 | uint16_t ioLimitUpper; 44 | uint8_t capPtr; 45 | uint8_t intLine; 46 | uint8_t intPIN; 47 | }; 48 | 49 | struct PCIP2CHeader_t { 50 | uint32_t cardbusBaseAddr; 51 | uint8_t capListOffset; 52 | uint16_t secStatus; 53 | uint8_t pciBusNumber; 54 | uint8_t cardbusBusNuber; 55 | uint8_t subBusNumber; 56 | uint8_t cardbusLatTimer; 57 | uint32_t memBaseAddr0; 58 | uint32_t memLimit0; 59 | uint32_t memBaseAddr1; 60 | uint32_t memLimit1; 61 | uint32_t ioBaseAddr0; 62 | uint32_t ioLimit0; 63 | uint32_t ioBaseAddr1; 64 | uint32_t ioLimit1; 65 | uint8_t intLine; 66 | uint8_t intPIN; 67 | uint16_t subsysDeviceID; 68 | uint16_t subsysVendorID; 69 | uint32_t legacyBaseAddr; 70 | }; 71 | 72 | struct PCIDevice_t { 73 | uint8_t bus; 74 | uint8_t slot; 75 | uint8_t function; 76 | uint16_t vendorID; 77 | uint16_t deviceID; 78 | uint8_t revisionID; 79 | uint8_t progIF; 80 | uint8_t subclass; 81 | uint8_t classCode; 82 | uint8_t cacheLineSize; 83 | uint8_t latencyTimer; 84 | uint8_t headerType; 85 | uint8_t bist; 86 | char* vendorShortName; 87 | char* vendorFullName; 88 | char* deviceChip; 89 | char* deviceChipDesc; 90 | PCIStandardHeader_t standardHeader; // headerType = 0x00 91 | PCIP2PHeader_t pciToPciHeader; // headerType = 0x01 92 | PCIP2CHeader_t pciToCardbusHeader; // headerType = 0x02 93 | }; 94 | 95 | class PCI_Class { 96 | public: 97 | uint16_t getVendorID(uint8_t bus, uint8_t slot, uint8_t function); 98 | char* getVendorShortName(uint16_t vendorID); 99 | char* getVendorFullName(uint16_t vendorID); 100 | uint16_t getDeviceID(uint8_t bus, uint8_t slot, uint8_t function); 101 | char* getDeviceName(uint16_t vendorID, uint16_t deviceID); 102 | char* getDeviceDescription(uint16_t vendorID, uint16_t deviceID); 103 | PCIDevice_t getDevice(uint8_t bus, uint8_t slot, uint8_t function); 104 | PCIDevice_t getDevice(uint32_t id); 105 | void scanDevices(); 106 | uint32_t getDeviceCount(); 107 | 108 | private: 109 | PCIDevice_t* _devices; 110 | uint32_t _deviceCount; 111 | }; 112 | 113 | extern PCI_Class PCI; -------------------------------------------------------------------------------- /libs/_old/idt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define IDT_ENTRY_COUNT 256 6 | 7 | #define INT_GATE 0x8E 8 | #define TRAP_GATE 0xEF 9 | 10 | IDT_Class IDT; 11 | 12 | uint8_t _IDT[IDT_ENTRY_COUNT * 8]; 13 | 14 | void lidt(void* base, uint16_t size) 15 | { // This function works in 32 and 64bit mode 16 | struct { 17 | uint16_t length; 18 | void* base; 19 | } __attribute__((packed)) IDTR = { size, base }; 20 | 21 | asm ( "lidt %0" : : "m"(IDTR) ); // let the compiler choose an addressing mode 22 | } 23 | 24 | void encodeIdtEntry(uint8_t index, uint32_t offset, uint16_t selector, uint8_t type) 25 | { 26 | uint8_t* target = &_IDT[8 * index]; 27 | 28 | // Encode the offset 29 | target[0] = offset & 0xFF; 30 | target[1] = (offset >> 8) & 0xFF; 31 | target[6] = (offset >> 16) & 0xFF; 32 | target[7] = (offset >> 24) & 0xFF; 33 | 34 | // Encode the selector 35 | target[2] = selector & 0xFF; 36 | target[3] = (selector >> 8) & 0xFF; 37 | 38 | // Encode the Zero 39 | target[4] = 0x00; 40 | 41 | // And... Type 42 | target[5] = type; 43 | } 44 | 45 | void IDT_Class::load() { 46 | 47 | for (int i = 0; i < 256; i++) { 48 | encodeIdtEntry(i, (uint32_t)&ASM_ISR_0, 0x08, TRAP_GATE); 49 | } 50 | 51 | encodeIdtEntry(0x00, (uint32_t)&_isr0, 0x08, INT_GATE); // Exceptions 52 | encodeIdtEntry(0x01, (uint32_t)&_isr1, 0x08, INT_GATE); 53 | encodeIdtEntry(0x02, (uint32_t)&_isr2, 0x08, INT_GATE); 54 | encodeIdtEntry(0x03, (uint32_t)&_isr3, 0x08, INT_GATE); 55 | encodeIdtEntry(0x04, (uint32_t)&_isr4, 0x08, INT_GATE); 56 | encodeIdtEntry(0x05, (uint32_t)&_isr5, 0x08, INT_GATE); 57 | encodeIdtEntry(0x06, (uint32_t)&_isr6, 0x08, INT_GATE); 58 | encodeIdtEntry(0x07, (uint32_t)&_isr7, 0x08, INT_GATE); 59 | encodeIdtEntry(0x08, (uint32_t)&_isr8, 0x08, INT_GATE); 60 | encodeIdtEntry(0x09, (uint32_t)&_isr9, 0x08, INT_GATE); 61 | encodeIdtEntry(0x0A, (uint32_t)&_isr10, 0x08, INT_GATE); 62 | encodeIdtEntry(0x0B, (uint32_t)&_isr11, 0x08, INT_GATE); 63 | encodeIdtEntry(0x0C, (uint32_t)&_isr12, 0x08, INT_GATE); 64 | encodeIdtEntry(0x0D, (uint32_t)&_isr13, 0x08, INT_GATE); 65 | encodeIdtEntry(0x0E, (uint32_t)&_isr14, 0x08, INT_GATE); 66 | encodeIdtEntry(0x0F, (uint32_t)&_isr15, 0x08, INT_GATE); 67 | encodeIdtEntry(0x10, (uint32_t)&_isr16, 0x08, INT_GATE); 68 | encodeIdtEntry(0x11, (uint32_t)&_isr17, 0x08, INT_GATE); 69 | encodeIdtEntry(0x12, (uint32_t)&_isr18, 0x08, INT_GATE); 70 | encodeIdtEntry(0x13, (uint32_t)&_isr19, 0x08, INT_GATE); 71 | encodeIdtEntry(0x14, (uint32_t)&_isr20, 0x08, INT_GATE); 72 | encodeIdtEntry(0x15, (uint32_t)&_isr21, 0x08, INT_GATE); 73 | encodeIdtEntry(0x16, (uint32_t)&_isr22, 0x08, INT_GATE); 74 | encodeIdtEntry(0x17, (uint32_t)&_isr23, 0x08, INT_GATE); 75 | encodeIdtEntry(0x18, (uint32_t)&_isr24, 0x08, INT_GATE); 76 | encodeIdtEntry(0x19, (uint32_t)&_isr25, 0x08, INT_GATE); 77 | encodeIdtEntry(0x1A, (uint32_t)&_isr26, 0x08, INT_GATE); 78 | encodeIdtEntry(0x1B, (uint32_t)&_isr27, 0x08, INT_GATE); 79 | encodeIdtEntry(0x1C, (uint32_t)&_isr28, 0x08, INT_GATE); 80 | encodeIdtEntry(0x1D, (uint32_t)&_isr29, 0x08, INT_GATE); 81 | encodeIdtEntry(0x1E, (uint32_t)&_isr30, 0x08, INT_GATE); 82 | encodeIdtEntry(0x1F, (uint32_t)&_isr31, 0x08, INT_GATE); 83 | 84 | encodeIdtEntry(0x20, (uint32_t)&ASM_ISR_PIT, 0x08, INT_GATE); // PIT 85 | encodeIdtEntry(0x21, (uint32_t)&ASM_ISR_KBD, 0x08, INT_GATE); // Keyboard 86 | encodeIdtEntry(0x26, (uint32_t)&ASM_ISR_FLOPPY, 0x08, INT_GATE); // Floppy 87 | encodeIdtEntry(0x69, (uint32_t)&ASM_ISR_SYSCALL, 0x08, TRAP_GATE); // Syscall 88 | 89 | lidt(&_IDT, sizeof(_IDT)); 90 | } -------------------------------------------------------------------------------- /drivers/filesystems/ext2/ext2fs.h: -------------------------------------------------------------------------------- 1 | #define EXT2_STATE_CLEAN 1 2 | #define EXT2_STATE_ERROR 2 3 | 4 | #define EXT2_ERR_IGNORE 1 5 | #define EXT2_ERR_REMOUNT 2 6 | #define EXT2_ERR_PANIC 3 7 | 8 | #define EXT2_CREATOR_LINUX 0 9 | #define EXT2_CREATOR_HURD 1 10 | #define EXT2_CREATOR_MASIX 2 11 | #define EXT2_CREATOR_FRBSD 3 12 | #define EXT2_CREATOR_BSD 4 13 | 14 | #define EXT2_OFF_PREALLOC 0x01 15 | #define EXT2_OFF_AFS 0x02 16 | #define EXT2_OFF_JOURNAL 0x04 17 | #define EXT2_OFF_EXT_ATT 0x08 18 | #define EXT2_OFF_RESIZE 0x10 19 | #define EXT2_OFF_HASH_IND 0x20 20 | 21 | #define EXT2_RFF_COMPRESS 0x01 22 | #define EXT2_RFF_TYPE_FLD 0x02 23 | #define EXT2_RFF_REP_JRNL 0x04 24 | #define EXT2_RFF_JRNL_DEV 0x08 25 | 26 | #define EXT2_ROFF_SPARSE 0x01 27 | #define EXT2_ROFF_64BIT 0x02 28 | #define EXT2_ROFF_BINTREE 0x04 29 | 30 | struct Ext2BaseSuperBlock_t { 31 | uint32_t totalInode; 32 | uint32_t totalBlock; 33 | uint32_t suResBlocks; 34 | uint32_t totalUnallocInode; 35 | uint32_t totalUnallocBlock; 36 | uint32_t sbBlockID; 37 | uint32_t log2BlockSize; 38 | uint32_t log2FragmentSize; 39 | uint32_t blockPerGroup; 40 | uint32_t fragmentPerGroup; 41 | uint32_t inodePerGroup; 42 | uint32_t lastMountTime; 43 | uint32_t lastWriteTime; 44 | uint16_t mountCountSinceCC; 45 | uint16_t maxMountCount; 46 | uint16_t ext2Signature; 47 | uint16_t fsState; 48 | uint16_t errorFunction; 49 | uint16_t versionMin; 50 | uint32_t lastCCTime; 51 | uint32_t ccInterval; 52 | uint32_t osID; 53 | uint32_t versionMaj; 54 | uint16_t blockResUsrID; 55 | uint16_t blockResGrpID; 56 | }__attribute__((packed)); 57 | 58 | struct Ext2ExtendedSuperBlock_t { 59 | uint32_t firstNonReservedInode; 60 | uint16_t inodeSize; 61 | uint16_t blockGround; 62 | uint32_t optFeatures; 63 | uint32_t reqFeatures; 64 | uint32_t nonSupportedFeatures; 65 | char fileSystemID[16]; 66 | char volumeName[16]; 67 | char lastMountPath[64]; 68 | uint32_t compAlgorithm; 69 | char filePreAllocBlockCount; 70 | char dirPreAllocBlockCount; 71 | uint16_t _unused; 72 | char journalID[16]; 73 | uint32_t journalInode; 74 | uint32_t journalDevice; 75 | uint32_t orphanInodeHead; 76 | bool present; 77 | }__attribute__((packed)); 78 | 79 | struct Ext2BlockGroupDeskEntry_t { 80 | uint32_t blockUsageBmpAddr; 81 | uint32_t inodeUsageBmpAddr; 82 | uint32_t inodeStartBlockAddr; 83 | uint16_t unAllocBlockCount; 84 | uint16_t unAllocInodeCount; 85 | uint16_t unAllocDirCount; 86 | char unused[14]; 87 | }__attribute__((packed)); 88 | 89 | struct Ext2Inode_t { 90 | uint16_t typeNPerms; 91 | uint16_t userID; 92 | uint32_t size_l; 93 | uint32_t lastAccessTime; 94 | uint32_t creationTime; 95 | uint32_t lastModTime; 96 | uint32_t deletionTime; 97 | uint16_t groupID; 98 | uint16_t hardLinkCount; 99 | uint32_t diskSectorCount; 100 | uint32_t flags; 101 | uint32_t osSpecific1; 102 | uint32_t directBlockPointer0; 103 | uint32_t directBlockPointer1; 104 | uint32_t directBlockPointer2; 105 | uint32_t directBlockPointer3; 106 | uint32_t directBlockPointer4; 107 | uint32_t directBlockPointer5; 108 | uint32_t directBlockPointer6; 109 | uint32_t directBlockPointer7; 110 | uint32_t directBlockPointer8; 111 | uint32_t directBlockPointer9; 112 | uint32_t directBlockPointer10; 113 | uint32_t directBlockPointer11; 114 | uint32_t singlyBlockPointer; 115 | uint32_t doublyBlockPointer; 116 | uint32_t triplyBlockPointer; 117 | uint32_t generationNumber; 118 | uint32_t res_extAttrib; 119 | uint32_t res_size_h; 120 | uint32_t fragmentBlockAddr; 121 | char osSpecific2[12]; 122 | }__attribute__((packed)); 123 | 124 | void parseFs(); -------------------------------------------------------------------------------- /drivers/storage/atapio/src/atapio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | ATAPIO_Class ATAPIO; 10 | 11 | extern "C" void __cxa_pure_virtual() { while (1); } 12 | 13 | int selectDrive(int drive, int numblock, int count) 14 | { 15 | outb(0x1F1, 0x00); /* NULL byte to port 0x1F1 */ 16 | outb(0x1F2, count); /* Sector count */ 17 | outb(0x1F3, (uint8_t) numblock); /* Low 8 bits of the block address */ 18 | outb(0x1F4, (uint8_t) (numblock >> 8)); /* Next 8 bits of the block address */ 19 | outb(0x1F5, (uint8_t) (numblock >> 16)); /* Next 8 bits of the block address */ 20 | 21 | /* Drive indicator, magic bits, and highest 4 bits of the block address */ 22 | outb(0x1F6, 0xE0 | (drive << 4) | ((numblock >> 24) & 0x0F)); 23 | 24 | return 0; 25 | } 26 | 27 | int ATAPIO_Class::readBlock(int drive, int numblock, int count, char *buf) { 28 | uint16_t tmpword; 29 | int idx; 30 | 31 | if (count == 0) { 32 | kernel_panic(0x1234, "Null sector count read"); 33 | } 34 | 35 | selectDrive(drive, numblock, count); 36 | 37 | outb(0x1F7, 0x20); 38 | 39 | for (int i = 0; i < count; i++) { 40 | PIT.delay(1); 41 | uint8_t status = inb(0x1F7); 42 | while ((status & 0x80) && !(status & 0x08)) { 43 | status = inb(0x1F7); 44 | } 45 | 46 | for (idx = 0; idx < 256 * count; idx++) { 47 | tmpword = inw(0x1F0); 48 | buf[(idx * 2) + (i * 512)] = (uint8_t)tmpword; 49 | buf[(idx * 2 + 1) + (i * 512)] = (uint8_t)(tmpword >> 8); 50 | } 51 | } 52 | 53 | return count; 54 | } 55 | 56 | int ATAPIO_Class::writeBlock(int drive, int numblock, int count, char *buf) { 57 | uint16_t tmpword; 58 | int idx; 59 | 60 | if (count == 0) { 61 | kernel_panic(0x1234, "Null sector count write"); 62 | } 63 | 64 | selectDrive(drive, numblock, count); 65 | outb(0x1F7, 0x30); 66 | 67 | // Wait for ready signal 68 | uint8_t status = (inb(0x1F7) & 0x08); 69 | while (!status) { 70 | status = (inb(0x1F7) & 0x08); 71 | } 72 | 73 | for (idx = 0; idx < 256 * count; idx++) { 74 | tmpword = (buf[idx * 2 + 1] << 8) | buf[idx * 2]; 75 | outw(0x1F0, tmpword); 76 | } 77 | 78 | return count; 79 | } 80 | 81 | ATAPIODrive_t::ATAPIODrive_t(uint8_t id) { 82 | this->id = id; 83 | } 84 | 85 | bool ATAPIODrive_t::read(uint64_t addr, uint64_t size, uint8_t* buf) { 86 | uint64_t base = floor(addr / 512); 87 | uint64_t limit = ceil((addr + size) / 512); 88 | uint64_t start = addr % 512; 89 | uint8_t* buffer = (uint8_t*)malloc(((limit - base) + 1) * 512); 90 | ATAPIO.readBlock(0, base, (limit - base) + 1, (char*)buffer); // TODO: Change first param to this->id 91 | memmove(buf, buffer + start, size); 92 | free(buffer); 93 | return true; // TODO: Check operation worked 94 | } 95 | 96 | bool ATAPIODrive_t::write(uint64_t addr, uint64_t size, uint8_t* buf) { 97 | uint64_t base = floor((float)addr / 512.0f); 98 | uint64_t limit = floor((float)(addr + size) / 512.0f); 99 | uint64_t start = addr % 512; 100 | uint8_t* buffer = (uint8_t*)malloc(((limit - base) + 1) * 512); 101 | 102 | Terminal.println(itoa(base, 10)); 103 | Terminal.println(itoa(limit, 10)); 104 | Terminal.println(itoa(start, 10)); 105 | Terminal.println(itoa((limit - base) + 1, 10)); 106 | 107 | ATAPIO.readBlock(0, base, (limit - base) + 2, (char*)buffer); // TODO: Change first param to this->id 108 | memmove(buffer + start, buf, size); 109 | Terminal.println((char*)(buffer + start)); 110 | ATAPIO.writeBlock(0, base, (limit - base) + 2, (char*)buffer); 111 | free(buffer); 112 | return true; // TODO: Check operation worked 113 | } -------------------------------------------------------------------------------- /drivers/keyboard/keyboard_layouts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | const char KEYBOARD_LAYOUT_FR_BE[8][85] = { 5 | { // NO SHIFT, NO NUM, NO ALTGR 6 | 0, '&', 'é', '"', '\'', '(', '§', 'è', 7 | '!', 'ç', 'à', ')', '-', 0, 0, 'a', 8 | 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 9 | 'p', '^', '$', '\n', 0, 'q', 's', 'd', 10 | 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'ù', 11 | '²', 0, 'µ', 'w', 'x', 'c', 'v', 'b', 12 | 'n', ',', ';', ':', '=', 0, '*', 0, 13 | ' ', 0, 0, 0, 0, 0, 0, 0, 14 | 0, 0, 0, 0, 0, 0, 0, 0, 15 | 0, '-', 0, 0, 0, '+', 0, 0, 16 | 0, 0, '<', 0, 0 17 | }, 18 | { // SHIFT, NO NUM, NO ALTGR 19 | 0, '1', '2', '3', '4', '5', '6', '7', 20 | '8', '9', '0', '°', '_', 0, 0, 'A', 21 | 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 22 | 'P', '¨', '*', '\n', 0, 'Q', 'S', 'R', 23 | 'F', 'G', 'H', 'J', 'K', 'L', 'M', '%', 24 | '³', 0, '£', 'W', 'X', 'C', 'V', 'B', 25 | 'N', '?', '.', '/', '+', 0, '*', 0, 26 | ' ', 0, 0, 0, 0, 0, 0, 0, 27 | 0, 0, 0, 0, 0, 0, 0, 0, 28 | 0, '-', 0, 0, 0, '+', 0, 0, 29 | 0, 0, '>', 0, 0 30 | }, 31 | { // NO SHIFT, NUM, NO ALTGR 32 | 0, '&', 'é', '"', '\'', '(', '§', 'è', 33 | '!', 'ç', 'à', ')', '-', 0, 0, 'a', 34 | 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 35 | 'p', '^', '$', '\n', 0, 'q', 's', 'd', 36 | 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'ù', 37 | '²', 0, 'µ', 'w', 'x', 'c', 'v', 'b', 38 | 'n', ',', ';', ':', '=', 0, '*', 0, 39 | ' ', 0, 0, 0, 0, 0, 0, 0, 40 | 0, 0, 0, 0, 0, 0, '7', '8', 41 | '9', '-', '4', '5', '6', '+', '1', '2', 42 | '3', '0', '<', 0, 0 43 | }, 44 | { // SHIFT, NUM, NO ALTGR 45 | 0, '1', '2', '3', '4', '5', '6', '7', 46 | '8', '9', '0', '°', '_', 0, 0, 'A', 47 | 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 48 | 'P', '¨', '*', '\n', 0, 'Q', 'S', 'R', 49 | 'F', 'G', 'H', 'J', 'K', 'L', 'M', '%', 50 | '³', 0, '£', 'W', 'X', 'C', 'V', 'B', 51 | 'N', '?', '.', '/', '+', 0, '*', 0, 52 | ' ', 0, 0, 0, 0, 0, 0, 0, 53 | 0, 0, 0, 0, 0, 0, '7', '8', 54 | '9', '-', '4', '5', '6', '+', '1', '2', 55 | '3', '0', '>', 0, 0 56 | }, 57 | { // NO SHIFT, NO NUM, ALTGR 58 | 0, '|', '@', '#', '{', '[', '^', 0, 59 | 0, '{', '}', 0, '-', 0, 0, 0, 60 | 0, 0, 0, 0, 0, 0, 0, 0, 61 | 0, '[', ']', 0, 0, 0, 0, 0, 62 | 0, 0, 0, 0, 0, 0, 0, '´', 63 | 0, 0, '`', 0, 0, 0, 0, 0, 64 | 0, 0, 0, 0, '~', 0, 0, 0, 65 | 0, 0, 0, 0, 0, 0, 0, 0, 66 | 0, 0, 0, 0, 0, 0, 0, 0, 67 | 0, 0, '\\', 0, 0 68 | }, 69 | { // SHIFT, NO NUM, ALTGR 70 | 0, 0, 0, 0, 0, 0, 0, 0, 71 | 0, 0, 0, 0, 0, 0, 0, 0, 72 | 0, 0, 0, 0, 0, 0, 0, 0, 73 | 0, 0, 0, 0, 0, 0, 0, 0, 74 | 0, 0, 0, 0, 0, 0, 0, 0, 75 | 0, 0, 0, 0, 0, 0, 0, 0, 76 | 0, 0, 0, 0, 0, 0, 0, 0, 77 | 0, 0, 0, 0, 0, 0, 0, 0, 78 | 0, 0, 0, 0, 0, 0, 0, 0, 79 | 0, 0, 0, 0, 0, 0, 0, 0 80 | }, 81 | { // NO SHIFT, NUM, ALTGR 82 | 0, '|', '@', '#', '{', '[', '^', 0, 83 | 0, '{', '}', 0, '-', 0, 0, 0, 84 | 0, 0, 0, 0, 0, 0, 0, 0, 85 | 0, '[', ']', 0, 0, 0, 0, 0, 86 | 0, 0, 0, 0, 0, 0, 0, '´', 87 | 0, 0, '`', 0, 0, 0, 0, 0, 88 | 0, 0, 0, 0, '~', 0, 0, 0, 89 | 0, 0, 0, 0, 0, 0, 0, 0, 90 | 0, 0, 0, 0, 0, 0, 0, 0, 91 | 0, 0, '\\', 0, 0 92 | }, 93 | { // SHIFT, NUM, ALTGR 94 | 0, 0, 0, 0, 0, 0, 0, 0, 95 | 0, 0, 0, 0, 0, 0, 0, 0, 96 | 0, 0, 0, 0, 0, 0, 0, 0, 97 | 0, 0, 0, 0, 0, 0, 0, 0, 98 | 0, 0, 0, 0, 0, 0, 0, 0, 99 | 0, 0, 0, 0, 0, 0, 0, 0, 100 | 0, 0, 0, 0, 0, 0, 0, 0, 101 | 0, 0, 0, 0, 0, 0, 0, 0, 102 | 0, 0, 0, 0, 0, 0, 0, 0, 103 | 0, 0, 0, 0, 0, 0, 0, 0 104 | } 105 | }; -------------------------------------------------------------------------------- /drivers/filesystems/ext2/src/ext2fs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | Ext2BaseSuperBlock_t _baseSuperBLock; 11 | Ext2ExtendedSuperBlock_t _extSuperBlock; 12 | uint32_t blockGroupCount = 0; 13 | uint32_t blockSize; 14 | uint32_t fragmentSize; 15 | uint32_t inodeSize; 16 | Ext2BlockGroupDeskEntry_t* _blockGroupDescriptorTable; 17 | char* buffer; 18 | 19 | Ext2BaseSuperBlock_t parseBaseSuperblock() { 20 | Ext2BaseSuperBlock_t ret; 21 | buffer = (char*)malloc(1024); 22 | ATAPIO.readBlock(0, 2, 2, buffer); 23 | memmove(&ret, buffer, sizeof(Ext2BaseSuperBlock_t)); 24 | free(buffer); 25 | return ret; 26 | } 27 | 28 | Ext2ExtendedSuperBlock_t parseExtSuperblock() { 29 | Ext2ExtendedSuperBlock_t ret; 30 | char* buffer = (char*)malloc(1024); 31 | ATAPIO.readBlock(0, 2, 2, buffer); 32 | memmove(&ret, buffer + 84, sizeof(Ext2ExtendedSuperBlock_t)); 33 | free(buffer); 34 | return ret; 35 | } 36 | 37 | uint32_t getPhysicalBlock(uint32_t block) { 38 | return (blockSize / 512) * block; 39 | } 40 | 41 | uint32_t getBlockCount(uint32_t block) { 42 | return (blockSize / 512) * block; 43 | } 44 | 45 | void parseBlockGroupDescriptorTable() { 46 | char* buffer = (char*)malloc(blockSize); // 1 block 47 | if (blockSize == 1024) { 48 | ATAPIO.readBlock(0, getPhysicalBlock(2), getBlockCount(1), buffer); 49 | } 50 | else { 51 | ATAPIO.readBlock(0, getPhysicalBlock(1), getBlockCount(1), buffer); 52 | } 53 | _blockGroupDescriptorTable = (Ext2BlockGroupDeskEntry_t*)malloc(sizeof(Ext2BlockGroupDeskEntry_t) * blockGroupCount); 54 | memmove(_blockGroupDescriptorTable, buffer, sizeof(Ext2BlockGroupDeskEntry_t) * blockGroupCount); 55 | free(buffer); 56 | } 57 | 58 | uint32_t getBlockGroup(uint32_t inode) { 59 | return (inode - 1) / _baseSuperBLock.inodePerGroup; 60 | } 61 | 62 | uint32_t getInodeIndex(uint32_t inode) { 63 | return (inode - 1) % _baseSuperBLock.inodePerGroup; 64 | } 65 | 66 | uint32_t getInodeBlock(uint32_t index) { 67 | return (index * inodeSize) / blockSize; 68 | } 69 | 70 | void parseFs() { 71 | _baseSuperBLock = parseBaseSuperblock(); 72 | if (_baseSuperBLock.ext2Signature != 0xEF53) { 73 | Terminal.setColor(0x04); 74 | Terminal.println("Invalid filesystem"); 75 | Terminal.setColor(0x07); 76 | return; 77 | } 78 | if (_baseSuperBLock.versionMaj >= 1) { 79 | _extSuperBlock = parseExtSuperblock(); 80 | _extSuperBlock.present = true; 81 | } 82 | uint32_t blockGroupCount_b = _baseSuperBLock.totalBlock / _baseSuperBLock.blockPerGroup; 83 | uint32_t blockGroupCount_i = _baseSuperBLock.totalInode / _baseSuperBLock.inodePerGroup; 84 | if (blockGroupCount_b != blockGroupCount_i) { 85 | Terminal.setColor(0x04); 86 | Terminal.println("Invalid block group count"); 87 | Terminal.setColor(0x07); 88 | return; 89 | } 90 | blockGroupCount = blockGroupCount_b; 91 | blockSize = 1024 << _baseSuperBLock.log2BlockSize; 92 | fragmentSize = 1024 << _baseSuperBLock.log2FragmentSize; 93 | if (_baseSuperBLock.versionMaj >= 1) { 94 | inodeSize = _extSuperBlock.inodeSize; 95 | } 96 | else { 97 | inodeSize = 128; 98 | } 99 | parseBlockGroupDescriptorTable(); 100 | 101 | uint32_t blockGroup = getBlockGroup(13); 102 | uint32_t inodeTableAddr = _blockGroupDescriptorTable[blockGroup].inodeStartBlockAddr; 103 | uint32_t inodeIndex = getInodeIndex(13); 104 | uint32_t blockOffset = getInodeBlock(inodeIndex); 105 | 106 | char* buffer = (char*)malloc(blockSize); 107 | ATAPIO.readBlock(0, getPhysicalBlock(inodeTableAddr + blockOffset), getBlockCount(1), buffer); 108 | Ext2Inode_t inode; 109 | uint32_t offset = 768;//inodeIndex * inodeSize; 110 | memmove(&inode, buffer + offset, sizeof(Ext2Inode_t)); 111 | free(buffer); 112 | 113 | Terminal.println(itoa(_extSuperBlock.inodeSize, 10)); 114 | 115 | Terminal.println(itoa(offset + (getPhysicalBlock(inodeTableAddr + blockOffset) * 512), 16)); 116 | Terminal.println(itoa(getPhysicalBlock(inodeTableAddr + blockOffset), 10)); 117 | Terminal.println(itoa(inode.lastAccessTime, 10)); 118 | } -------------------------------------------------------------------------------- /libs/kernel/src/idt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define IDT_ENTRY_COUNT 256 8 | 9 | #define BochsBreak() outw(0x8A00,0x8A00); outw(0x8A00,0x08AE0); 10 | 11 | IDT_Class IDT; 12 | 13 | struct IDTEntry_t { 14 | uint16_t offset_0; 15 | uint16_t selector; 16 | uint8_t _zero; 17 | uint8_t type; 18 | uint16_t offset_1; 19 | }; 20 | 21 | IDTEntry_t _IDT[IDT_ENTRY_COUNT]; 22 | 23 | void lidt(void* base, uint16_t size) 24 | { // This function works in 32 and 64bit mode 25 | struct { 26 | uint16_t length; 27 | void* base; 28 | } __attribute__((packed)) IDTR = { size, base }; 29 | 30 | asm ( "lidt %0" : : "m"(IDTR) ); // let the compiler choose an addressing mode 31 | } 32 | 33 | void encodeIdtEntry(uint8_t index, uint32_t offset, uint16_t selector, uint8_t type) 34 | { 35 | _IDT[index].offset_0 = (offset >> 0) & 0xFFFF; 36 | _IDT[index].offset_1 = (offset >> 16) & 0xFFFF; 37 | _IDT[index].selector = selector * 8; // A GDT entry is 8 bytes long 38 | _IDT[index].type = type; 39 | _IDT[index]._zero = 0x00; 40 | } 41 | 42 | void IDT_Class::load() { 43 | 44 | for (int i = 0; i < 256; i++) { 45 | encodeIdtEntry(i, (uint32_t)&ASM_ISR_0, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_TRAP | IDT_ATTR_PRIV_3); 46 | } 47 | 48 | 49 | 50 | encodeIdtEntry(0x00, (uint32_t)&_isr0, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); // Exceptions 51 | encodeIdtEntry(0x01, (uint32_t)&_isr1, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 52 | encodeIdtEntry(0x02, (uint32_t)&_isr2, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 53 | encodeIdtEntry(0x03, (uint32_t)&_isr3, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 54 | encodeIdtEntry(0x04, (uint32_t)&_isr4, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 55 | encodeIdtEntry(0x05, (uint32_t)&_isr5, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 56 | encodeIdtEntry(0x06, (uint32_t)&_isr6, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 57 | encodeIdtEntry(0x07, (uint32_t)&_isr7, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 58 | encodeIdtEntry(0x08, (uint32_t)&_isr8, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 59 | encodeIdtEntry(0x09, (uint32_t)&_isr9, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 60 | encodeIdtEntry(0x0A, (uint32_t)&_isr10, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 61 | encodeIdtEntry(0x0B, (uint32_t)&_isr11, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 62 | encodeIdtEntry(0x0C, (uint32_t)&_isr12, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 63 | encodeIdtEntry(0x0D, (uint32_t)&_isr13, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 64 | encodeIdtEntry(0x0E, (uint32_t)&_isr14, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 65 | encodeIdtEntry(0x0F, (uint32_t)&_isr15, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 66 | encodeIdtEntry(0x10, (uint32_t)&_isr16, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 67 | encodeIdtEntry(0x11, (uint32_t)&_isr17, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 68 | encodeIdtEntry(0x12, (uint32_t)&_isr18, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 69 | encodeIdtEntry(0x13, (uint32_t)&_isr19, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 70 | encodeIdtEntry(0x14, (uint32_t)&_isr20, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 71 | encodeIdtEntry(0x15, (uint32_t)&_isr21, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 72 | encodeIdtEntry(0x16, (uint32_t)&_isr22, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 73 | encodeIdtEntry(0x17, (uint32_t)&_isr23, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 74 | encodeIdtEntry(0x18, (uint32_t)&_isr24, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 75 | encodeIdtEntry(0x19, (uint32_t)&_isr25, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 76 | encodeIdtEntry(0x1A, (uint32_t)&_isr26, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 77 | encodeIdtEntry(0x1B, (uint32_t)&_isr27, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 78 | encodeIdtEntry(0x1C, (uint32_t)&_isr28, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 79 | encodeIdtEntry(0x1D, (uint32_t)&_isr29, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 80 | encodeIdtEntry(0x1E, (uint32_t)&_isr30, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 81 | encodeIdtEntry(0x1F, (uint32_t)&_isr31, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); 82 | 83 | encodeIdtEntry(0x20, (uint32_t)&ASM_ISR_PIT, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); // PIT 84 | encodeIdtEntry(0x21, (uint32_t)&ASM_ISR_KBD, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); // Keyboard 85 | encodeIdtEntry(0x26, (uint32_t)&ASM_ISR_FLOPPY, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_INT); // Floppy 86 | encodeIdtEntry(0x69, (uint32_t)&ASM_ISR_SYSCALL, 0x01, IDT_ATTR_PRESENT | IDT_ATTR_TYPE_TRAP | IDT_ATTR_PRIV_3); // Syscall 87 | 88 | lidt(&_IDT, sizeof(_IDT)); 89 | 90 | BochsBreak(); 91 | } -------------------------------------------------------------------------------- /libs/kernel/src/paging.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | Paging_Class Paging; 8 | 9 | uint32_t page_directory[1024] __attribute__((aligned(4096))); 10 | uint32_t page_tables[1024][1024] __attribute__((aligned(4096))); 11 | 12 | uint32_t _maxMem = 0; 13 | 14 | void initPageDirectory() { 15 | for (uint16_t i = 0; i < 1024; i++) { 16 | page_directory[i] = 0x00000002; 17 | } 18 | } 19 | 20 | void initPageTables() { 21 | for (uint16_t i = 0; i < 1024; i++) { 22 | for (uint16_t j = 0; j < 1024; j++) { 23 | page_tables[i][j] = 0x00000002; 24 | } 25 | } 26 | } 27 | 28 | void initPageTable() { 29 | for (uint32_t i = 0; i < 1024; i++) { 30 | for (uint32_t j = 0; j < 1024; j++) { 31 | page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | 2; 32 | } 33 | } 34 | } 35 | 36 | void fillPageDirectory() { 37 | for (int i = 0; i < 1024; i++) { 38 | page_directory[i] = ((uint32_t)&page_tables[i][0]) | 3; 39 | } 40 | } 41 | 42 | void Paging_Class::enable(uint32_t maxmem) { 43 | _maxMem = maxmem; 44 | initPageDirectory(); 45 | initPageTables(); 46 | initPageTable(); 47 | fillPageDirectory(); 48 | setPresent(0, ((uint32_t)ASM_KERNEL_END / 4096) + 1); // Allocate for the kernel 49 | ASM_LOAD_PAGE_DIRECTORY(page_directory); 50 | ASM_ENABLE_PAGING(); 51 | } 52 | 53 | void Paging_Class::mapPage(uint32_t phy, uint32_t virt, uint16_t flags) { 54 | uint32_t pdi = virt >> 22; 55 | uint32_t pti = virt >> 12 & 0x03FF; 56 | page_tables[pdi][pti] = phy | flags; 57 | } 58 | 59 | uint32_t Paging_Class::getPhysicalAddr(uint32_t virt) { 60 | uint32_t pdi = virt >> 22; 61 | uint32_t pti = virt >> 12 & 0x03FF; 62 | return page_tables[pdi][pti] & 0xFFFFF000; 63 | } 64 | 65 | uint16_t Paging_Class::getFlags(uint32_t virt) { 66 | uint32_t pdi = virt >> 22; 67 | uint32_t pti = virt >> 12 & 0x03FF; 68 | return page_tables[pdi][pti] & 0xFFF; 69 | } 70 | 71 | void Paging_Class::setFlags(uint32_t virt, uint16_t flags) { 72 | uint32_t pdi = virt >> 22; 73 | uint32_t pti = virt >> 12 & 0x03FF; 74 | page_tables[pdi][pti] &= 0xFFFFF000; 75 | page_tables[pdi][pti] |= flags; 76 | } 77 | 78 | uint16_t Paging_Class::getDirectoryFlags(uint32_t virt) { 79 | uint32_t pdi = virt >> 22; 80 | return page_directory[pdi] & 0xFFF; 81 | } 82 | 83 | void Paging_Class::setDirectoryFlags(uint32_t virt, uint16_t flags) { 84 | uint32_t pdi = virt >> 22; 85 | page_directory[pdi] &= 0xFFFFF000; 86 | page_directory[pdi] |= flags; 87 | } 88 | 89 | void Paging_Class::setPresent(uint32_t virt, uint32_t count) { 90 | uint32_t pdi = virt >> 22; 91 | uint32_t pti = virt >> 12 & 0x03FF; 92 | 93 | uint32_t usedCount = 0; 94 | 95 | for (uint32_t i = pdi; i < 1024; i++) { 96 | for (uint32_t j = pti; j < 1024; j++) { 97 | page_tables[i][j] |= 1; 98 | usedCount++; 99 | if (usedCount >= count) { 100 | return; 101 | } 102 | } 103 | } 104 | } 105 | 106 | void Paging_Class::setAbsent(uint32_t virt, uint32_t count) { 107 | uint32_t pdi = virt >> 22; 108 | uint32_t pti = virt >> 12 & 0x03FF; 109 | 110 | uint32_t usedCount = 0; 111 | 112 | for (uint32_t i = pdi; i < 1024; i++) { 113 | for (uint32_t j = pti; j < 1024; j++) { 114 | page_tables[i][j] &= 0xFFFFFFFE; 115 | usedCount++; 116 | if (usedCount >= count) { 117 | return; 118 | } 119 | } 120 | } 121 | } 122 | 123 | uint32_t Paging_Class::findPages(uint32_t count) { 124 | uint32_t continous = 0; 125 | for (uint32_t i = 0; i < 1024; i++) { 126 | for (uint32_t j = 0; j < 1024; j++) { 127 | uint8_t free = !(page_tables[i][j] & 1); 128 | if (free == 1) { 129 | continous++; 130 | } 131 | else { 132 | continous = 0; 133 | } 134 | if (continous == count) { 135 | return (i * 0x400000) + (j * 0x1000); 136 | } 137 | } 138 | } 139 | kernel_panic(0xF0CC, "Out of memory :/"); 140 | return 0; 141 | } 142 | 143 | uint32_t Paging_Class::allocPages(uint32_t count) { 144 | uint32_t ptr = findPages(count); 145 | setPresent(ptr, count); 146 | return ptr; 147 | } 148 | 149 | uint32_t Paging_Class::getUsedPages() { 150 | uint32_t n = 0; 151 | for (uint32_t i = 0; i < 1024; i++) { 152 | for (uint32_t j = 0; j < 1024; j++) { 153 | uint8_t flags = page_tables[i][j] & 0x01; 154 | if (flags == 1) { 155 | n++; 156 | } 157 | } 158 | } 159 | return n; 160 | } -------------------------------------------------------------------------------- /kernel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "shell/shell.h" 20 | #include 21 | #include 22 | #include 23 | 24 | #define BochsBreak() outw(0x8A00,0x8A00); outw(0x8A00,0x08AE0); 25 | 26 | struct VBE2Block_t { 27 | uint8_t signature[4]; 28 | uint8_t ver_maj; 29 | uint8_t ver_min; 30 | }; 31 | 32 | void test(iostream strm) { 33 | return; 34 | char* data = "Hello from stream\n"; 35 | strm.write(data, 18); 36 | } 37 | 38 | extern "C" // Use C link for kernel_main 39 | 40 | void kernel_main(uint32_t multiboot_magic, MultibootInfo_t* multiboot_info) 41 | { 42 | Terminal.Init(80, 25); 43 | Terminal.hideCursor(); 44 | Terminal.setColor(0x0E); 45 | Terminal.clear(); 46 | 47 | if (multiboot_magic != 0x2BADB002) { 48 | kernel_panic(0xFFFF, "Invalid multiboot signature !"); 49 | } 50 | 51 | Serial serial(115200, 0x3F8); 52 | 53 | test(serial.outStream); 54 | //test(Terminal.outStream); 55 | 56 | Terminal.println("Welcome to MemeOS v1.8 !"); 57 | Terminal.setColor(0x07); 58 | 59 | Terminal.print("Loading GDT... "); 60 | GDT.load(); 61 | Terminal.OK(); 62 | 63 | Terminal.print("Enabling paging... "); 64 | Paging.enable(multiboot_info->mem_upper / 4); 65 | Terminal.OK(); 66 | 67 | // Memory Management can now be used! 68 | 69 | Terminal.print("Remapping PIC... "); 70 | PIC.Init(); 71 | Terminal.OK(); 72 | 73 | Terminal.print("Loading IDT... "); 74 | IDT.load(); 75 | Terminal.OK(); 76 | 77 | // Interrupts can now be used! 78 | 79 | Terminal.print("Loading TSS... "); 80 | initTss(); 81 | loadTss(); 82 | Terminal.OK(); 83 | 84 | Terminal.print("Configuring PIT... "); 85 | PIT.Init(); 86 | Terminal.OK(); 87 | 88 | Terminal.print("Initialising Keyboard... "); 89 | Keyboard.Init(); 90 | Terminal.OK(); 91 | 92 | asm("sti"); 93 | 94 | Terminal.print("Finding ACPI pointer... "); 95 | 96 | uint32_t RSDPTR = 0x00000000; 97 | char* RSDSIG = "RSD PTR "; 98 | char* RAMPTR = 0x00000000; 99 | 100 | for (uint32_t i = 0; i < 0x100000; i++) { 101 | uint8_t match = 0; 102 | for (uint8_t j = 0; j < 8; j++) { 103 | if (RAMPTR[i + j] == RSDSIG[j]) { 104 | match++; 105 | } 106 | } 107 | if (match >= 8) { 108 | RSDPTR = i; 109 | break; 110 | } 111 | } 112 | 113 | if (RSDPTR != 0) { 114 | Terminal.OK(); 115 | } 116 | else { 117 | Terminal.FAILED(); 118 | } 119 | 120 | 121 | Terminal.print("Scanning PCI devices... "); 122 | PCI.scanDevices(); 123 | Terminal.OK(); 124 | 125 | // Terminal.print("Initializing floppy controller... "); 126 | // if (Floppy.init()) { 127 | // Terminal.OK(); 128 | // } 129 | // else { 130 | // Terminal.FAILED(); 131 | // } 132 | 133 | Terminal.print("Scanning ATA devices... "); 134 | // Enable ata shit here 135 | Terminal.OK(); 136 | 137 | // -drive id=disk,file=hda.img,if=none -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 138 | //Terminal.print("Scanning ACHI controllers... "); 139 | //AHCI.scanControllers(); 140 | //Terminal.OK(); 141 | 142 | Terminal.setColor(0x03); 143 | 144 | Terminal.println(""); 145 | 146 | Terminal.print("Kernel end: 0x"); 147 | Terminal.print(dumpHexByte(((uint32_t)(&ASM_KERNEL_END)) >> 24)); 148 | Terminal.print(dumpHexByte(((uint32_t)(&ASM_KERNEL_END)) >> 16)); 149 | Terminal.print(dumpHexByte(((uint32_t)(&ASM_KERNEL_END)) >> 8)); 150 | Terminal.println(dumpHexByte(((uint32_t)(&ASM_KERNEL_END)) >> 0)); 151 | 152 | Terminal.print("Stack top: 0x"); 153 | Terminal.print(dumpHexByte((uint32_t)ASM_STACK_TOP >> 24)); 154 | Terminal.print(dumpHexByte((uint32_t)ASM_STACK_TOP >> 16)); 155 | Terminal.print(dumpHexByte((uint32_t)ASM_STACK_TOP >> 8)); 156 | Terminal.println(dumpHexByte((uint32_t)ASM_STACK_TOP >> 0)); 157 | 158 | Terminal.print("RSDPTR: 0x"); 159 | Terminal.print(dumpHexByte(RSDPTR >> 24)); 160 | Terminal.print(dumpHexByte(RSDPTR >> 16)); 161 | Terminal.print(dumpHexByte(RSDPTR >> 8)); 162 | Terminal.println(dumpHexByte(RSDPTR >> 0)); 163 | 164 | Terminal.setColor(0x07); 165 | 166 | shell_main(multiboot_info); 167 | 168 | for (;;) { 169 | asm("hlt"); 170 | } 171 | } -------------------------------------------------------------------------------- /drivers/keyboard/src/keyboard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define PRESSED 1 12 | #define RELEASED 2 13 | 14 | Keyboard_Class Keyboard; 15 | 16 | KeyboardEvent_t last_event; 17 | 18 | void writeToBuffer(uint8_t keycode, uint8_t type) { 19 | if (type == PRESSED) { 20 | if (keycode == Keyboard.KEYCODES.NUMLOCK) { 21 | Keyboard.NumlockState = !Keyboard.NumlockState; 22 | } 23 | if (keycode == Keyboard.KEYCODES.CAPSLOCK) { 24 | Keyboard.CapslockState = !Keyboard.CapslockState; 25 | } 26 | if (keycode == Keyboard.KEYCODES.LSHIFT) { 27 | Keyboard.LSHIFTState = true; 28 | } 29 | if (keycode == Keyboard.KEYCODES.RSHIFT) { 30 | Keyboard.RSHIFTState = true; 31 | } 32 | if (keycode == Keyboard.KEYCODES.LCTRL) { 33 | Keyboard.LCTRLState = true; 34 | } 35 | if (keycode == Keyboard.KEYCODES.RCTRL) { 36 | Keyboard.RCTRLState = true; 37 | } 38 | if (keycode == Keyboard.KEYCODES.LALT) { 39 | Keyboard.LALTState = true; 40 | } 41 | if (keycode == Keyboard.KEYCODES.ALTGR) { 42 | Keyboard.ALTGRState = true; 43 | } 44 | KeyboardEvent_t event; 45 | event.keycode = keycode; 46 | event.type = PRESSED; 47 | last_event = event; 48 | } 49 | else { 50 | if (keycode == Keyboard.KEYCODES.LSHIFT) { 51 | Keyboard.LSHIFTState = false; 52 | } 53 | if (keycode == Keyboard.KEYCODES.RSHIFT) { 54 | Keyboard.RSHIFTState = false; 55 | } 56 | if (keycode == Keyboard.KEYCODES.LCTRL) { 57 | Keyboard.LCTRLState = false; 58 | } 59 | if (keycode == Keyboard.KEYCODES.RCTRL) { 60 | Keyboard.RCTRLState = false; 61 | } 62 | if (keycode == Keyboard.KEYCODES.LALT) { 63 | Keyboard.LALTState = false; 64 | } 65 | if (keycode == Keyboard.KEYCODES.ALTGR) { 66 | Keyboard.ALTGRState = false; 67 | } 68 | KeyboardEvent_t event; 69 | event.keycode = keycode; 70 | event.type = RELEASED; 71 | last_event = event; 72 | } 73 | } 74 | 75 | KeyboardEvent_t Keyboard_Class::readEvent(bool wait) { 76 | while (wait && last_event.type == 0) { 77 | asm("nop"); 78 | } 79 | KeyboardEvent_t event = last_event; 80 | last_event.type = 0; 81 | return event; 82 | } 83 | 84 | char Keyboard_Class::getKeyChar(uint8_t keycode) { 85 | bool shift = (Keyboard.CapslockState & !Keyboard.ALTGRState) ^ (Keyboard.LSHIFTState | Keyboard.RSHIFTState); 86 | uint8_t mods = shift | (Keyboard.NumlockState << 1) | (Keyboard.ALTGRState << 2); 87 | return KEYBOARD_LAYOUT_FR_BE[mods][keycode]; 88 | } 89 | 90 | void waitIO() { 91 | uint8_t status = inb(0x64); 92 | while ((status & 0b00000001) == 1) { 93 | uint8_t dummy = inb(0x60); 94 | } 95 | } 96 | 97 | void Keyboard_Class::Init() { 98 | outb(0x64, 0xAD); 99 | outb(0x64, 0xA7); 100 | waitIO(); 101 | outb(0x64, 0xAE); 102 | outb(0x64, 0xA8); 103 | Keyboard.NumlockState = true; 104 | } 105 | 106 | bool E0 = false; 107 | uint8_t E1 = 0; 108 | 109 | uint8_t last = 0; 110 | 111 | void Keyboard_Class::update() { 112 | uint8_t scancode = inb(0x60); 113 | if (E1 > 0) { 114 | E1--; 115 | return; 116 | } 117 | if (scancode == 0xE0) { 118 | E0 = true; 119 | return; 120 | } 121 | if (scancode == 0xE1) { 122 | E1 = 3; 123 | return; 124 | // Pause Pressed / Released 125 | } 126 | if (E0) { 127 | E0 = false; 128 | scancode = inb(0x60); 129 | if (scancode == 0x2A) { 130 | scancode = inb(0x60); 131 | scancode = inb(0x60); 132 | // PrtScr Pressed 133 | } 134 | else if (scancode == 0xB7) { 135 | scancode = inb(0x60); 136 | scancode = inb(0x60); 137 | // PrtScr Released 138 | } 139 | else { 140 | if (scancode <= 0x53) { 141 | writeToBuffer(scancode + 0x29, PRESSED); 142 | } 143 | else if (scancode <= 0x58){ 144 | writeToBuffer(scancode + 0x26, PRESSED); 145 | } 146 | else if (scancode <= 0xD3){ 147 | writeToBuffer(scancode - 0x57, RELEASED); 148 | } 149 | else { 150 | writeToBuffer(scancode - 0x5A, RELEASED); 151 | } 152 | } 153 | } 154 | else if (E1) { 155 | E1 = false; 156 | } 157 | else { 158 | if (scancode <= 0x53) { 159 | writeToBuffer(scancode - 0x01, PRESSED); 160 | } 161 | else if (scancode <= 0x58){ 162 | writeToBuffer(scancode - 0x04, PRESSED); 163 | } 164 | else if (scancode <= 0xD3){ 165 | writeToBuffer(scancode - 0x81, RELEASED); 166 | } 167 | else { 168 | writeToBuffer(scancode - 0x84, RELEASED); 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /libs/_old/string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | uint32_t strlen(char* str){ 6 | uint32_t len = 0; 7 | while (str[len]) 8 | len++; 9 | return len; 10 | } 11 | 12 | bool strcmp(char* str_a, char* str_b) { 13 | if (strlen(str_a) != strlen(str_b)) { 14 | return false; 15 | } 16 | for (uint32_t i = 0; i < strlen(str_a); i++) { 17 | if (str_a[i] != str_b[i]) { 18 | return false; 19 | } 20 | } 21 | return true; 22 | } 23 | 24 | void* memmove(void* dstptr, void* srcptr, uint64_t size) { 25 | unsigned char* dst = (unsigned char*) dstptr; 26 | unsigned char* src = (unsigned char*) srcptr; 27 | if (dst < src) { 28 | for (uint64_t i = 0; i < size; i++) 29 | dst[i] = src[i]; 30 | } else { 31 | for (uint64_t i = size; i != 0; i--) 32 | dst[i-1] = src[i-1]; 33 | } 34 | return dstptr; 35 | } 36 | 37 | char HEX_ALPHABET[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 38 | 39 | char* dumpHexByte(uint8_t n) { 40 | char* rtn = "00"; 41 | rtn[1] = HEX_ALPHABET[n & 0x0F]; 42 | rtn[0] = HEX_ALPHABET[(n & 0xF0) >> 4]; 43 | return rtn; 44 | } 45 | 46 | string itoa(uint32_t n, uint8_t base) { 47 | string ret = ""; 48 | while (n > 0) { 49 | uint32_t digit = n % base; 50 | string str = ""; 51 | str += HEX_ALPHABET[digit]; 52 | ret = str + ret; 53 | n -= digit; 54 | n /= base; 55 | } 56 | return ret; 57 | } 58 | 59 | uint32_t strcnt(char* str, char c) { 60 | uint32_t count = 0; 61 | for (uint32_t i = 0; i < strlen(str); i++) { 62 | if (str[i] == c) { 63 | count++; 64 | } 65 | } 66 | return count; 67 | } 68 | 69 | int strfio(char* str, char c) { 70 | uint32_t index = 0; 71 | for (uint32_t i = 0; i < strlen(str); i++) { 72 | if (str[i] == c) { 73 | return i; 74 | } 75 | } 76 | return -1; 77 | } 78 | 79 | char* substr(char* str, uint32_t index) { 80 | return str + index; 81 | } 82 | 83 | string::string(char* str) { 84 | this->_str = (char*)malloc(strlen(str) + 1); 85 | for (uint32_t i = 0; i < strlen(str) + 1; i++) { 86 | this->_str[i] = str[i]; 87 | } 88 | } 89 | 90 | string::string() { 91 | this->_str = (char*)malloc(1); 92 | this->_str[0] = 0x00; 93 | } 94 | 95 | string::~string() { 96 | free(this->_str); 97 | } 98 | 99 | char* string::toCharArray() { 100 | return this->_str; 101 | } 102 | 103 | uint32_t string::length() { 104 | return strlen(this->_str); 105 | } 106 | 107 | void string::reserve(uint32_t len) { 108 | uint32_t old_len = this->length(); 109 | this->_str = (char*)realloc(this->_str, len + 1); 110 | for (uint32_t i = 0; i < len - old_len; i++) { 111 | this->_str[old_len] = 0x00; 112 | } 113 | } 114 | 115 | string string::operator+(string str) { 116 | string ret; 117 | ret.reserve(this->length() + str.length()); 118 | memmove(ret.toCharArray(), this->toCharArray(), this->length()); 119 | memmove(ret.toCharArray() + this->length(), str.toCharArray(), str.length() + 1); 120 | return ret; 121 | } 122 | 123 | string string::operator+(char c) { 124 | string ret; 125 | ret.reserve(this->length() + 1); 126 | memmove(ret.toCharArray(), this->toCharArray(), this->length()); 127 | ret.toCharArray()[this->length()] = c; 128 | return ret; 129 | } 130 | 131 | void string::operator+=(string str) { 132 | this->reserve(this->length() + str.length()); 133 | memmove(this->toCharArray() + this->length(), str.toCharArray(), str.length() + 1); 134 | } 135 | 136 | void string::operator+=(char c) { 137 | this->reserve(this->length() + 1); 138 | this->toCharArray()[this->length()] = c; 139 | } 140 | 141 | bool string::operator==(string str) { 142 | return strcmp(this->_str, str.toCharArray()); 143 | } 144 | 145 | bool string::operator!=(string str) { 146 | return !strcmp(this->_str, str.toCharArray()); 147 | } 148 | 149 | bool string::operator==(char* str) { 150 | return strcmp(this->_str, str); 151 | } 152 | 153 | bool string::operator!=(char* str) { 154 | return !strcmp(this->_str, str); 155 | } 156 | 157 | char string::operator[](uint32_t i) { 158 | return this->_str[i]; 159 | } 160 | 161 | string string::substring(uint32_t index) { 162 | string ret; 163 | ret.reserve(this->length() - index); 164 | memmove(ret.toCharArray(), this->toCharArray() + index, this->length() - index); 165 | return ret; 166 | } 167 | 168 | string string::substring(uint32_t index, uint32_t length) { 169 | string ret; 170 | ret.reserve(this->length() - index - (this->length() - index - length)); 171 | memmove(ret.toCharArray(), this->toCharArray() + index, this->length() - index - (this->length() - index - length)); 172 | return ret; 173 | } 174 | 175 | bool string::startsWith(string str) { 176 | for (uint32_t i = 0; i < str.length(); i++) { 177 | if (str[i] != this->_str[i]) { 178 | return false; 179 | } 180 | } 181 | return true; 182 | } 183 | 184 | bool string::endWith(string str) { 185 | for (int i = str.length() - 1; i > -1; i--) { 186 | if (str[i] != this->_str[this->length() - str.length() + i]) { 187 | return false; 188 | } 189 | } 190 | return true; 191 | } 192 | 193 | string string::toUpper() { 194 | string ret; 195 | ret.reserve(this->length()); 196 | char* ptr = ret.toCharArray(); 197 | for (uint32_t i = 0; i < this->length(); i++) { 198 | char c = this->_str[i]; 199 | if (c >= 97 && c <= 122) { 200 | c &= 0b11011111; 201 | } 202 | ptr[i] = c; 203 | } 204 | return ret; 205 | } 206 | 207 | string string::toLower() { 208 | string ret; 209 | ret.reserve(this->length()); 210 | char* ptr = ret.toCharArray(); 211 | for (uint32_t i = 0; i < this->length(); i++) { 212 | char c = this->_str[i]; 213 | if (c >= 65 && c <= 90) { 214 | c |= 0b00100000; 215 | } 216 | ptr[i] = c; 217 | } 218 | return ret; 219 | } -------------------------------------------------------------------------------- /libs/kernel/src/asm_isr.asm: -------------------------------------------------------------------------------- 1 | .align 4 2 | .global _isr0 3 | .global _isr1 4 | .global _isr2 5 | .global _isr3 6 | .global _isr4 7 | .global _isr5 8 | .global _isr6 9 | .global _isr7 10 | .global _isr8 11 | .global _isr9 12 | .global _isr10 13 | .global _isr11 14 | .global _isr12 15 | .global _isr13 16 | .global _isr14 17 | .global _isr15 18 | .global _isr16 19 | .global _isr17 20 | .global _isr18 21 | .global _isr19 22 | .global _isr20 23 | .global _isr21 24 | .global _isr22 25 | .global _isr23 26 | .global _isr24 27 | .global _isr25 28 | .global _isr26 29 | .global _isr27 30 | .global _isr28 31 | .global _isr29 32 | .global _isr30 33 | .global _isr31 34 | 35 | _isr0: 36 | cli 37 | push $0 38 | push $0 39 | jmp isr_common_stub 40 | 41 | _isr1: 42 | cli 43 | push $0 44 | push $1 45 | jmp isr_common_stub 46 | 47 | _isr2: 48 | cli 49 | push $0 50 | push $2 51 | jmp isr_common_stub 52 | 53 | _isr3: 54 | cli 55 | push $0 56 | push $3 57 | jmp isr_common_stub 58 | 59 | _isr4: 60 | cli 61 | push $0 62 | push $4 63 | jmp isr_common_stub 64 | 65 | _isr5: 66 | cli 67 | push $0 68 | push $5 69 | jmp isr_common_stub 70 | 71 | _isr6: 72 | cli 73 | push $0 74 | push $6 75 | jmp isr_common_stub 76 | 77 | _isr7: 78 | cli 79 | push $0 80 | push $7 81 | jmp isr_common_stub 82 | 83 | _isr8: 84 | cli 85 | push $8 86 | jmp isr_common_stub 87 | 88 | _isr9: 89 | cli 90 | push $9 91 | jmp isr_common_stub 92 | 93 | _isr10: 94 | cli 95 | push $10 96 | jmp isr_common_stub 97 | 98 | _isr11: 99 | cli 100 | push $11 101 | jmp isr_common_stub 102 | 103 | _isr12: 104 | cli 105 | push $12 106 | jmp isr_common_stub 107 | 108 | _isr13: 109 | cli 110 | push $13 111 | jmp isr_common_stub 112 | 113 | _isr14: 114 | cli 115 | push $14 116 | jmp isr_common_stub 117 | 118 | _isr15: 119 | cli 120 | push $15 121 | jmp isr_common_stub 122 | 123 | _isr16: 124 | cli 125 | push $16 126 | jmp isr_common_stub 127 | 128 | _isr17: 129 | cli 130 | push $17 131 | jmp isr_common_stub 132 | 133 | _isr18: 134 | cli 135 | push $18 136 | jmp isr_common_stub 137 | 138 | _isr19: 139 | cli 140 | push $19 141 | jmp isr_common_stub 142 | 143 | _isr20: 144 | cli 145 | push $20 146 | jmp isr_common_stub 147 | 148 | _isr21: 149 | cli 150 | push $21 151 | jmp isr_common_stub 152 | 153 | _isr22: 154 | cli 155 | push $22 156 | jmp isr_common_stub 157 | 158 | _isr23: 159 | cli 160 | push $23 161 | jmp isr_common_stub 162 | 163 | _isr24: 164 | cli 165 | push $24 166 | jmp isr_common_stub 167 | 168 | _isr25: 169 | cli 170 | push $25 171 | jmp isr_common_stub 172 | 173 | _isr26: 174 | cli 175 | push $26 176 | jmp isr_common_stub 177 | 178 | _isr27: 179 | cli 180 | push $27 181 | jmp isr_common_stub 182 | 183 | _isr28: 184 | cli 185 | push 28 186 | jmp isr_common_stub 187 | 188 | _isr29: 189 | cli 190 | push $29 191 | jmp isr_common_stub 192 | 193 | _isr30: 194 | cli 195 | push $30 196 | jmp isr_common_stub 197 | 198 | _isr31: 199 | cli 200 | push $31 201 | jmp isr_common_stub 202 | 203 | .extern _fault_handler 204 | 205 | isr_common_stub: 206 | pusha 207 | push %ds 208 | push %es 209 | push %fs 210 | push %gs 211 | movw $0x10,%ax 212 | movw %ax,%ds 213 | movw %ax,%es 214 | movw %ax,%fs 215 | movw %ax,%gs 216 | movl %esp,%eax 217 | pushl %eax 218 | call _fault_handler 219 | popl %eax 220 | popl %gs 221 | popl %fs 222 | popl %es 223 | popl %ds 224 | popa 225 | addl $8,%esp 226 | iret 227 | 228 | .global ASM_ISR_0 229 | ASM_ISR_0: 230 | pushal 231 | pushw %ds 232 | pushw %es 233 | pushw %fs 234 | pushw %gs 235 | pushl %ebx 236 | movw $0x10,%bx 237 | movw %bx,%ds 238 | popl %ebx 239 | 240 | cld /* C code following the sysV ABI requires DF to be clear on function entry */ 241 | call ISR_0 242 | 243 | popw %gs 244 | popw %fs 245 | popw %es 246 | popw %ds 247 | popal 248 | iret 249 | 250 | .global ASM_ISR_PIT 251 | ASM_ISR_PIT: 252 | pushal 253 | pushw %ds 254 | pushw %es 255 | pushw %fs 256 | pushw %gs 257 | pushl %ebx 258 | movw $0x10,%bx 259 | movw %bx,%ds 260 | popl %ebx 261 | 262 | cld /* C code following the sysV ABI requires DF to be clear on function entry */ 263 | call ISR_PIT 264 | 265 | popw %gs 266 | popw %fs 267 | popw %es 268 | popw %ds 269 | popal 270 | iret 271 | 272 | .global ASM_ISR_KBD 273 | ASM_ISR_KBD: 274 | pushal 275 | pushw %ds 276 | pushw %es 277 | pushw %fs 278 | pushw %gs 279 | pushl %ebx 280 | movw $0x10,%bx 281 | movw %bx,%ds 282 | popl %ebx 283 | 284 | cld /* C code following the sysV ABI requires DF to be clear on function entry */ 285 | call ISR_KBD 286 | 287 | popw %gs 288 | popw %fs 289 | popw %es 290 | popw %ds 291 | popal 292 | iret 293 | 294 | .global ASM_ISR_FLOPPY 295 | ASM_ISR_FLOPPY: 296 | pushal 297 | pushw %ds 298 | pushw %es 299 | pushw %fs 300 | pushw %gs 301 | pushl %ebx 302 | movw $0x10,%bx 303 | movw %bx,%ds 304 | popl %ebx 305 | 306 | cld /* C code following the sysV ABI requires DF to be clear on function entry */ 307 | call ISR_FLOPPY 308 | 309 | popw %gs 310 | popw %fs 311 | popw %es 312 | popw %ds 313 | popal 314 | iret 315 | 316 | .global ASM_ISR_SYSCALL 317 | ASM_ISR_SYSCALL: 318 | pushal 319 | pushw %ds 320 | pushw %es 321 | pushw %fs 322 | pushw %gs 323 | pushl %ebx 324 | movw $0x10,%bx 325 | movw %bx,%ds 326 | popl %ebx 327 | 328 | cld /* C code following the sysV ABI requires DF to be clear on function entry */ 329 | push %edx 330 | push %ecx 331 | push %ebx 332 | push %eax 333 | call ISR_SYSCALL 334 | pop %eax 335 | pop %ebx 336 | pop %ecx 337 | pop %edx 338 | 339 | popw %gs 340 | popw %fs 341 | popw %es 342 | popw %ds 343 | popal 344 | iret 345 | -------------------------------------------------------------------------------- /libs/std/src/string.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | uint32_t strlen(char* str){ 7 | uint32_t len = 0; 8 | while (str[len]) 9 | len++; 10 | return len; 11 | } 12 | 13 | bool strcmp(char* str_a, char* str_b) { 14 | uint32_t len_a = strlen(str_a); 15 | uint32_t len_b = strlen(str_b); 16 | if (len_a != len_b) { 17 | return false; 18 | } 19 | for (uint32_t i = 0; i < len_a; i++) { 20 | if (str_a[i] != str_b[i]) { 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | 27 | void* memmove(void* dstptr, void* srcptr, uint64_t size) { 28 | uint8_t* dst = (uint8_t*) dstptr; 29 | uint8_t* src = (uint8_t*) srcptr; 30 | if (dst < src) { 31 | for (uint64_t i = 0; i < size; i++) 32 | dst[i] = src[i]; 33 | } else { 34 | for (uint64_t i = size; i != 0; i--) 35 | dst[i-1] = src[i-1]; 36 | } 37 | return dstptr; 38 | } 39 | 40 | bool memcmp(void* aptr, void* bptr, uint64_t size) { 41 | uint8_t* a = (uint8_t*) aptr; 42 | uint8_t* b = (uint8_t*) bptr; 43 | for (uint32_t i = 0; i < size; i++) { 44 | if (a[i] != b[i]) { 45 | return false; 46 | } 47 | } 48 | return true; 49 | } 50 | 51 | void* memset(void* bufptr, uint8_t value, uint64_t size) { 52 | uint8_t* buf = (uint8_t*) bufptr; 53 | for (uint64_t i = 0; i < size; i++) { 54 | buf[i] = value; 55 | } 56 | return bufptr; 57 | } 58 | 59 | char HEX_ALPHABET[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 60 | 61 | char* dumpHexByte(uint8_t n) { 62 | char* rtn = "00"; 63 | rtn[1] = HEX_ALPHABET[n & 0x0F]; 64 | rtn[0] = HEX_ALPHABET[(n & 0xF0) >> 4]; 65 | return rtn; 66 | } 67 | 68 | string itoa(uint32_t _n, uint8_t base) { 69 | uint32_t n = _n; 70 | if (n == 0) { 71 | return "0"; 72 | } 73 | string ret; 74 | while (n > 0) { 75 | uint32_t digit = n % base; 76 | string str = ""; 77 | str += HEX_ALPHABET[digit]; 78 | str += ret; 79 | ret = str; 80 | n -= digit; 81 | n /= base; 82 | } 83 | return ret; 84 | } 85 | 86 | uint32_t strcnt(char* str, char c) { 87 | uint32_t count = 0; 88 | uint32_t len = strlen(str); 89 | for (uint32_t i = 0; i < len; i++) { 90 | if (str[i] == c) { 91 | count++; 92 | } 93 | } 94 | return count; 95 | } 96 | 97 | int strfio(char* str, char c) { 98 | uint32_t index = 0; 99 | uint32_t len = strlen(str); 100 | for (uint32_t i = 0; i < len; i++) { 101 | if (str[i] == c) { 102 | return i; 103 | } 104 | } 105 | return -1; 106 | } 107 | 108 | char* substr(char* str, uint32_t index) { 109 | return str + index; 110 | } 111 | 112 | // <=============================== STRING CLASS ===============================> 113 | 114 | string::string(char* str) { 115 | this->_length = strlen(str); 116 | this->_str = (char*)malloc(this->_length + 1); 117 | memmove(this->_str, str, this->_length); 118 | this->_str[this->_length] = 0x00; 119 | } 120 | 121 | string::string() { 122 | this->_length = 0; 123 | this->_str = (char*)malloc(1); 124 | this->_str[0] = 0x00; 125 | } 126 | 127 | string::~string() { 128 | this->_length = 0; 129 | free(this->_str); 130 | } 131 | 132 | string string::operator+(string str) { 133 | string ret; 134 | ret = this->_str; 135 | ret += str; 136 | return ret; 137 | } 138 | 139 | string string::operator+(char c) { 140 | string ret; 141 | ret = this->toCharArray(); 142 | ret += c; 143 | return ret; 144 | } 145 | 146 | void string::operator+=(string str) { 147 | this->_str = (char*)realloc(this->_str, this->_length + str.length() + 1); 148 | memmove(this->_str + this->_length, str.toCharArray(), str.length()); 149 | this->_str[this->_length + str.length()] = 0x00; 150 | this->_length += str.length(); 151 | } 152 | 153 | void string::operator+=(char c) { 154 | this->_str = (char*)realloc(this->_str, this->_length + 2); 155 | this->_str[this->_length] = c; 156 | this->_str[this->_length + 1] = 0x00; 157 | this->_length++; 158 | } 159 | 160 | char string::operator[](uint32_t i) { 161 | if (i < this->_length) { 162 | return this->_str[i]; 163 | } 164 | kernel_panic(0xC0FEFE, "Array out of bounds"); 165 | return 0x00; 166 | } 167 | 168 | bool string::operator==(string str) { 169 | return strcmp(this->_str, str.toCharArray()); 170 | } 171 | 172 | bool string::operator!=(string str) { 173 | return !strcmp(this->_str, str.toCharArray()); 174 | } 175 | 176 | bool string::operator==(char* str) { 177 | return strcmp(this->_str, str); 178 | } 179 | 180 | bool string::operator!=(char* str) { 181 | return !strcmp(this->_str, str); 182 | } 183 | 184 | void string::operator=(string str) { 185 | this->_length = str.length(); 186 | this->_str = (char*)malloc(this->_length + 1); 187 | memmove(this->_str, str.toCharArray(), this->_length); 188 | this->_str[this->_length] = 0x00; 189 | } 190 | 191 | void string::operator=(char* str) { 192 | this->_length = strlen(str); 193 | this->_str = (char*)malloc(this->_length + 1); 194 | memmove(this->_str, str, this->_length); 195 | this->_str[this->_length] = 0x00; 196 | } 197 | 198 | uint32_t string::length() { 199 | return this->_length; 200 | } 201 | 202 | char* string::toCharArray() { 203 | return this->_str; 204 | } 205 | 206 | void string::reserve(uint32_t len) { 207 | if (len > this->_length) { 208 | this->_str = (char*)realloc(this->_str, len + 1); 209 | } 210 | } 211 | 212 | string string::substring(uint32_t index) { 213 | string ret; 214 | if (index < this->_length) { 215 | ret = (this->toCharArray() + index); 216 | } 217 | return ret; 218 | } 219 | 220 | string string::substring(uint32_t index, uint32_t length) { 221 | string ret; 222 | if (index + length <= this->_length) { 223 | for (uint32_t i = index; i < index + length; i++) { 224 | ret += this->_str[i]; 225 | } 226 | } 227 | return ret; 228 | } 229 | 230 | bool string::startsWith(string str) { 231 | if (str.length() > this->_length) { 232 | return false; 233 | } 234 | uint32_t len = str.length(); 235 | for (uint32_t i = 0; i < len; i++) { 236 | if (this->_str[i] != str[i]) { 237 | return false; 238 | } 239 | } 240 | return true; 241 | } 242 | 243 | bool string::endWith(string str) { 244 | if (str.length() > this->_length) { 245 | return false; 246 | } 247 | uint32_t len = str.length(); 248 | for (uint32_t i = 0; i < len; i++) { 249 | if (this->_str[this->_length - len + i] != str[i]) { 250 | return false; 251 | } 252 | } 253 | return true; 254 | } 255 | 256 | string string::toUpper() { 257 | string ret; 258 | for (uint32_t i = 0; i < this->_length; i++) { 259 | char c = this->_str[i]; 260 | if (c >= 97 && c <= 122) { 261 | c &= 0b11011111; 262 | } 263 | ret += c; 264 | } 265 | return ret; 266 | } 267 | 268 | string string::toLower() { 269 | string ret; 270 | for (uint32_t i = 0; i < this->_length; i++) { 271 | char c = this->_str[i]; 272 | if (c >= 65 && c <= 90) { 273 | c |= 0b00100000; 274 | } 275 | ret += c; 276 | } 277 | return ret; 278 | } 279 | 280 | char* string::c_str() { 281 | return this->_str; 282 | } 283 | 284 | // <=============================== STRING CLASS ===============================> -------------------------------------------------------------------------------- /drivers/text_term/src/terminal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | Terminal_Class Terminal; 9 | 10 | char text_color = 0x0F; 11 | uint16_t* frame_buffer = (uint16_t*)0xB8000; 12 | uint8_t cursor_x = 0; 13 | uint8_t cursor_y = 0; 14 | uint8_t terminal_width = 0; 15 | uint8_t terminal_height = 0; 16 | uint8_t last_clear_color = 0x00; 17 | 18 | void Terminal_Class::Init(uint8_t width, uint8_t height) { 19 | terminal_width = width; 20 | terminal_height = height; 21 | outStream = stream(_streamHandler, this); 22 | } 23 | 24 | void Terminal_Class::setColor(char color) { 25 | text_color = color; 26 | } 27 | 28 | void Terminal_Class::putcar(char c, uint8_t x, uint8_t y) { 29 | frame_buffer[x + (terminal_width * y)] = c | (text_color << 8); 30 | } 31 | 32 | void Terminal_Class::print(char* str) { 33 | for (uint32_t i = 0; i < strlen(str); i++) { 34 | if (str[i] == '\n'){ 35 | newLine(); 36 | } 37 | else if (cursor_x == terminal_width) { 38 | newLine(); 39 | } 40 | else { 41 | frame_buffer[cursor_x + (terminal_width * cursor_y)] = str[i] | (text_color << 8); 42 | cursor_x++; 43 | } 44 | } 45 | setCursor(cursor_x, cursor_y); 46 | } 47 | 48 | void Terminal_Class::println(char* str) { 49 | for (uint32_t i = 0; i < strlen(str); i++) { 50 | if (str[i] == '\n'){ 51 | newLine(); 52 | } 53 | else if (cursor_x == terminal_width) { 54 | newLine(); 55 | } 56 | else { 57 | frame_buffer[cursor_x + (terminal_width * cursor_y)] = str[i] | (text_color << 8); 58 | cursor_x++; 59 | } 60 | } 61 | newLine(); 62 | setCursor(cursor_x, cursor_y); 63 | } 64 | 65 | void Terminal_Class::print(string str) { 66 | for (uint32_t i = 0; i < str.length(); i++) { 67 | if (str[i] == '\n'){ 68 | newLine(); 69 | } 70 | else if (cursor_x == terminal_width) { 71 | newLine(); 72 | } 73 | else { 74 | frame_buffer[cursor_x + (terminal_width * cursor_y)] = str[i] | (text_color << 8); 75 | cursor_x++; 76 | } 77 | } 78 | setCursor(cursor_x, cursor_y); 79 | } 80 | 81 | void Terminal_Class::println(string str) { 82 | for (uint32_t i = 0; i < str.length(); i++) { 83 | if (str[i] == '\n'){ 84 | newLine(); 85 | } 86 | else if (cursor_x == terminal_width) { 87 | newLine(); 88 | } 89 | else { 90 | frame_buffer[cursor_x + (terminal_width * cursor_y)] = str[i] | (text_color << 8); 91 | cursor_x++; 92 | } 93 | } 94 | newLine(); 95 | setCursor(cursor_x, cursor_y); 96 | } 97 | 98 | void Terminal_Class::setCursor(uint8_t x, uint8_t y) { 99 | frame_buffer[x + (terminal_width * y)] = (frame_buffer[x + (terminal_width * y)] & 0x00FF) | (text_color << 8); 100 | cursor_x = x; 101 | cursor_y = y; 102 | uint16_t pos = x + (terminal_width * y); 103 | outb(0x3D4, 0x0F); 104 | outb(0x3D5, (uint8_t) (pos & 0xFF)); 105 | outb(0x3D4, 0x0E); 106 | outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF)); 107 | } 108 | 109 | void Terminal_Class::clear() { 110 | for (uint8_t y = 0; y < terminal_height; y++) { 111 | for (uint8_t x = 0; x < terminal_width; x++) { 112 | frame_buffer[x + (terminal_width * y)] = ' ' | (text_color << 8); 113 | } 114 | } 115 | cursor_x = 0; 116 | cursor_y = 0; 117 | setCursor(0, 0); 118 | } 119 | 120 | void Terminal_Class::scrollUp(uint8_t n) { 121 | for (uint8_t i = 0; i < n; i++) { 122 | memmove(&frame_buffer[0], &frame_buffer[terminal_width], terminal_width * (terminal_height - 1) * 2); 123 | for (uint8_t x = 0; x < terminal_width; x++) { 124 | frame_buffer[x + ((terminal_height - 1) * terminal_width)] = ' ' | (text_color << 8); 125 | } 126 | } 127 | } 128 | 129 | void Terminal_Class::scrollDown(uint8_t n) { 130 | for (int i = 0; i < n; i++) { 131 | memmove(&frame_buffer[terminal_width], &frame_buffer[0], (terminal_width * (terminal_height - 1)) * 2); 132 | for (int x = 0; x < terminal_width; x++) { 133 | frame_buffer[x] = ' ' | (text_color << 8); 134 | } 135 | } 136 | } 137 | 138 | void Terminal_Class::newLine() { 139 | if (cursor_y == 24) { 140 | scrollUp(1); 141 | cursor_x = 0; 142 | } 143 | else { 144 | cursor_y++; 145 | cursor_x = 0; 146 | } 147 | } 148 | 149 | void Terminal_Class::showCursor(uint8_t thickness) { 150 | 151 | outb(0x3D4, 0x09); 152 | uint8_t end = inb(0x3D5) & 0b00011111; // Get the max scanline 153 | uint8_t start = end - thickness; 154 | 155 | outb(0x3D4, 0x0A); 156 | outb(0x3D5, (inb(0x3D5) & 0xC0) | start); 157 | outb(0x3D4, 0x0B); 158 | outb(0x3D5, (inb(0x3D5) & 0xE0) | end); 159 | } 160 | 161 | void Terminal_Class::hideCursor() { 162 | outb(0x3D4, 0x0A); 163 | outb(0x3D5, 0x20); 164 | } 165 | 166 | void Terminal_Class::OK(bool newLine) { 167 | print("[ "); 168 | char old_color = text_color; 169 | text_color = (text_color & 0xF0) | 0x0A; 170 | print("OK"); 171 | text_color = old_color; 172 | if (newLine) { 173 | println(" ]"); 174 | } 175 | else { 176 | print(" ]"); 177 | } 178 | } 179 | 180 | void Terminal_Class::WARN(bool newLine) { 181 | print("[ "); 182 | char old_color = text_color; 183 | text_color = (text_color & 0xF0) | 0x06; 184 | print("WARN"); 185 | text_color = old_color; 186 | if (newLine) { 187 | println(" ]"); 188 | } 189 | else { 190 | print(" ]"); 191 | } 192 | } 193 | 194 | void Terminal_Class::FAILED(bool newLine) { 195 | print("[ "); 196 | char old_color = text_color; 197 | text_color = (text_color & 0xF0) | 0x04; 198 | print("FAILED"); 199 | text_color = old_color; 200 | if (newLine) { 201 | println(" ]"); 202 | } 203 | else { 204 | print(" ]"); 205 | } 206 | } 207 | 208 | uint8_t Terminal_Class::getWidth() { 209 | return terminal_width; 210 | } 211 | 212 | uint8_t Terminal_Class::getHeight() { 213 | return terminal_height; 214 | } 215 | 216 | uint8_t Terminal_Class::getCursorX() { 217 | return cursor_x; 218 | } 219 | 220 | uint8_t Terminal_Class::getCursorY() { 221 | return cursor_y; 222 | } 223 | 224 | string Terminal_Class::readLine() { 225 | string str; 226 | int backspaceXmax = Terminal.getCursorX(); 227 | int backspaceYmax = Terminal.getCursorY(); 228 | KeyboardEvent_t event = Keyboard.readEvent(true); 229 | bool shift = 0; 230 | while (event.keycode != Keyboard.KEYCODES.ENTER || event.type != Keyboard.EVENTTYPES.PRESSED) { 231 | if (event.keycode == Keyboard.KEYCODES.BACKSPACE && event.type == Keyboard.EVENTTYPES.PRESSED) { 232 | if (Terminal.getCursorX() > backspaceXmax) { 233 | int cx = Terminal.getCursorX(); 234 | int cy = Terminal.getCursorY(); 235 | cx--; 236 | Terminal.putcar(' ', cx, cy); 237 | Terminal.setCursor(cx, cy); 238 | str = str.substring(0, str.length() - 1); 239 | } 240 | } 241 | else if (event.type == Keyboard.EVENTTYPES.PRESSED) { 242 | char c = Keyboard.getKeyChar(event.keycode); 243 | if (c > 0) { 244 | char* cc = " "; 245 | cc[0] = c; 246 | Terminal.print(cc); 247 | str += c; 248 | } 249 | } 250 | event = Keyboard.readEvent(true); 251 | } 252 | return str; 253 | } 254 | 255 | void Terminal_Class::_streamHandler(char* str, int size, Terminal_Class* terminal) { 256 | char* dummy = " "; 257 | for (int i = 0; i < size; i++) { 258 | dummy[0] = str[i]; 259 | terminal->print(dummy); 260 | } 261 | } -------------------------------------------------------------------------------- /libs/_old/ahci.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define FIS_TYPE_REG_H2D 0x27 // Register FIS - host to device 5 | #define FIS_TYPE_REG_D2H 0x34 // Register FIS - device to host 6 | #define FIS_TYPE_DMA_ACT 0x39 // DMA activate FIS - device to host 7 | #define FIS_TYPE_DMA_SETUP 0x41 // DMA setup FIS - bidirectional 8 | #define FIS_TYPE_DATA 0x46 // Data FIS - bidirectional 9 | #define FIS_TYPE_BIST 0x58 // BIST activate FIS - bidirectional 10 | #define FIS_TYPE_PIO_SETUP 0x5F // PIO setup FIS - device to host 11 | #define FIS_TYPE_DEV_BITS 0xA1 // Set device bits FIS - device to host 12 | 13 | #define SATA_SIG_ATA 0x00000101 // SATA drive 14 | #define SATA_SIG_ATAPI 0xEB140101 // SATAPI drive 15 | #define SATA_SIG_SEMB 0xC33C0101 // Enclosure management bridge 16 | #define SATA_SIG_PM 0x96690101 // Port multiplier 17 | 18 | #define AHCI_DEV_NULL 0 19 | #define AHCI_DEV_SATA 1 20 | #define AHCI_DEV_SEMB 2 21 | #define AHCI_DEV_PM 3 22 | #define AHCI_DEV_SATAPI 4 23 | 24 | #define HBA_PORT_IPM_ACTIVE 1 25 | #define HBA_PORT_DET_PRESENT 3 26 | 27 | #define ATA_DEV_BUSY 0x80 28 | #define ATA_DEV_DRQ 0x08 29 | 30 | struct FIS_REG_H2D_t { 31 | // DWORD 0 32 | uint8_t fis_type; // FIS_TYPE_REG_H2D 33 | 34 | uint8_t pmport:4; // Port multiplier 35 | uint8_t rsv0:3; // Reserved 36 | uint8_t c:1; // 1: Command, 0: Control 37 | 38 | uint8_t command; // Command register 39 | uint8_t featurel; // Feature register, 7:0 40 | 41 | // DWORD 1 42 | uint8_t lba0; // LBA low register, 7:0 43 | uint8_t lba1; // LBA mid register, 15:8 44 | uint8_t lba2; // LBA high register, 23:16 45 | uint8_t device; // Device register 46 | 47 | // DWORD 2 48 | uint8_t lba3; // LBA register, 31:24 49 | uint8_t lba4; // LBA register, 39:32 50 | uint8_t lba5; // LBA register, 47:40 51 | uint8_t featureh; // Feature register, 15:8 52 | 53 | // DWORD 3 54 | uint8_t countl; // Count register, 7:0 55 | uint8_t counth; // Count register, 15:8 56 | uint8_t icc; // Isochronous command completion 57 | uint8_t control; // Control register 58 | 59 | // DWORD 4 60 | uint8_t rsv1[4]; // Reserved 61 | }; 62 | 63 | struct FIS_REG_D2H_t { 64 | // DWORD 0 65 | uint8_t fis_type; // FIS_TYPE_REG_D2H 66 | 67 | uint8_t pmport:4; // Port multiplier 68 | uint8_t rsv0:2; // Reserved 69 | uint8_t i:1; // Interrupt bit 70 | uint8_t rsv1:1; // Reserved 71 | 72 | uint8_t status; // Status register 73 | uint8_t error; // Error register 74 | 75 | // DWORD 1 76 | uint8_t lba0; // LBA low register, 7:0 77 | uint8_t lba1; // LBA mid register, 15:8 78 | uint8_t lba2; // LBA high register, 23:16 79 | uint8_t device; // Device register 80 | 81 | // DWORD 2 82 | uint8_t lba3; // LBA register, 31:24 83 | uint8_t lba4; // LBA register, 39:32 84 | uint8_t lba5; // LBA register, 47:40 85 | uint8_t rsv2; // Reserved 86 | 87 | // DWORD 3 88 | uint8_t countl; // Count register, 7:0 89 | uint8_t counth; // Count register, 15:8 90 | uint8_t rsv3[2]; // Reserved 91 | 92 | // DWORD 4 93 | uint8_t rsv4[4]; // Reserved 94 | }; 95 | 96 | struct FIS_DATA_t { 97 | // DWORD 0 98 | uint8_t fis_type; // FIS_TYPE_DATA 99 | 100 | uint8_t pmport:4; // Port multiplier 101 | uint8_t rsv0:4; // Reserved 102 | 103 | uint8_t rsv1[2]; // Reserved 104 | 105 | // DWORD 1 ~ N 106 | uint32_t data[1]; // Payload 107 | }; 108 | 109 | struct FIS_PIO_SETUP_t { 110 | // DWORD 0 111 | uint8_t fis_type; // FIS_TYPE_PIO_SETUP 112 | 113 | uint8_t pmport:4; // Port multiplier 114 | uint8_t rsv0:1; // Reserved 115 | uint8_t d:1; // Data transfer direction, 1 - device to host 116 | uint8_t i:1; // Interrupt bit 117 | uint8_t rsv1:1; 118 | 119 | uint8_t status; // Status register 120 | uint8_t error; // Error register 121 | 122 | // DWORD 1 123 | uint8_t lba0; // LBA low register, 7:0 124 | uint8_t lba1; // LBA mid register, 15:8 125 | uint8_t lba2; // LBA high register, 23:16 126 | uint8_t device; // Device register 127 | 128 | // DWORD 2 129 | uint8_t lba3; // LBA register, 31:24 130 | uint8_t lba4; // LBA register, 39:32 131 | uint8_t lba5; // LBA register, 47:40 132 | uint8_t rsv2; // Reserved 133 | 134 | // DWORD 3 135 | uint8_t countl; // Count register, 7:0 136 | uint8_t counth; // Count register, 15:8 137 | uint8_t rsv3; // Reserved 138 | uint8_t e_status; // New value of status register 139 | 140 | // DWORD 4 141 | uint16_t tc; // Transfer count 142 | uint8_t rsv4[2]; // Reserved 143 | }; 144 | 145 | struct FIS_DMA_SETUP_t { 146 | // DWORD 0 147 | uint8_t fis_type; // FIS_TYPE_DMA_SETUP 148 | 149 | uint8_t pmport:4; // Port multiplier 150 | uint8_t rsv0:1; // Reserved 151 | uint8_t d:1; // Data transfer direction, 1 - device to host 152 | uint8_t i:1; // Interrupt bit 153 | uint8_t a:1; // Auto-activate. Specifies if DMA Activate FIS is needed 154 | 155 | uint8_t rsved[2]; // Reserved 156 | 157 | //DWORD 1&2 158 | 159 | uint64_t DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. 160 | 161 | //DWORD 3 162 | uint32_t rsvd; //More reserved 163 | 164 | //DWORD 4 165 | uint32_t DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0 166 | 167 | //DWORD 5 168 | uint32_t TransferCount; //Number of bytes to transfer. Bit 0 must be 0 169 | 170 | //DWORD 6 171 | uint32_t resvd; //Reserved 172 | }; 173 | 174 | struct HBAPrdtEntry_t { 175 | uint32_t dba; 176 | uint32_t dbau; 177 | uint32_t res0; 178 | uint32_t dbc:22; 179 | uint32_t rsv1:9; 180 | uint32_t i:1; 181 | }; 182 | 183 | struct HBAReceivedFIS_t { 184 | FIS_DMA_SETUP_t dmaSetupFIS; 185 | uint32_t unused0; 186 | FIS_PIO_SETUP_t pioSetupFIS; 187 | uint8_t unused1[12]; 188 | FIS_REG_D2H_t registerFIS; 189 | uint32_t unused2; 190 | uint64_t setDeviceBitFIS; 191 | uint8_t uFIS[0x40]; 192 | uint8_t reserved[0x5F]; 193 | }; 194 | 195 | struct HBACommandTable_t { 196 | FIS_REG_H2D_t commandFIS; 197 | uint8_t atapiCmd[0x10]; 198 | uint8_t res0[0x20]; 199 | HBAPrdtEntry_t* prdt; 200 | }; 201 | 202 | struct HBACommand_t { 203 | uint8_t cfl:5; 204 | uint8_t a:1; 205 | uint8_t w:1; 206 | uint8_t p:1; 207 | uint8_t r:1; 208 | uint8_t b:1; 209 | uint8_t c:1; 210 | uint8_t rsv0:1; 211 | uint8_t pmp:4; 212 | uint16_t prdtl; 213 | uint32_t prdbc; 214 | uint8_t res0; 215 | uint8_t ctba0_l; 216 | uint16_t ctba0_h; 217 | uint32_t ctba_u0; 218 | uint32_t res1[0x04]; 219 | }; 220 | 221 | struct HBAPort_t { 222 | uint32_t clb; // 0x00, command list base address, 1K-byte aligned 223 | uint32_t clbu; // 0x04, command list base address upper 32 bits 224 | uint32_t fb; // 0x08, FIS base address, 256-byte aligned 225 | uint32_t fbu; // 0x0C, FIS base address upper 32 bits 226 | uint32_t is; // 0x10, interrupt status 227 | uint32_t ie; // 0x14, interrupt enable 228 | uint32_t cmd; // 0x18, command and status 229 | uint32_t rsv0; // 0x1C, Reserved 230 | uint32_t tfd; // 0x20, task file data 231 | uint32_t sig; // 0x24, signature 232 | uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) 233 | uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) 234 | uint32_t serr; // 0x30, SATA error (SCR1:SError) 235 | uint32_t sact; // 0x34, SATA active (SCR3:SActive) 236 | uint32_t ci; // 0x38, command issue 237 | uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification) 238 | uint32_t fbs; // 0x40, FIS-based switch control 239 | uint32_t rsv1[0x0B]; // 0x44 ~ 0x6F, Reserved 240 | uint32_t vendor[0x04]; // 0x70 ~ 0x7F, vendor specific 241 | }; 242 | 243 | struct HBAMem_t { 244 | // 0x00 - 0x2B, Generic Host Control 245 | uint32_t cap; // 0x00, Host capability 246 | uint32_t ghc; // 0x04, Global host control 247 | uint32_t is; // 0x08, Interrupt status 248 | uint32_t pi; // 0x0C, Port implemented 249 | uint32_t vs; // 0x10, Version 250 | uint32_t ccc_ctl; // 0x14, Command completion coalescing control 251 | uint32_t ccc_pts; // 0x18, Command completion coalescing ports 252 | uint32_t em_loc; // 0x1C, Enclosure management location 253 | uint32_t em_ctl; // 0x20, Enclosure management control 254 | uint32_t cap2; // 0x24, Host capabilities extended 255 | uint32_t bohc; // 0x28, BIOS/OS handoff control and status 256 | 257 | uint8_t _reserved[0x74]; 258 | uint8_t _vendorspc[0x60]; 259 | 260 | HBAPort_t ports[0x20]; 261 | }; 262 | 263 | struct ACHIDrive_t { 264 | uint8_t type; 265 | HBAPort_t* port; 266 | uint32_t controllerID; 267 | }; 268 | 269 | struct ACHIController_t { 270 | PCIDevice_t pciDevice; 271 | HBAMem_t* hbaMem; 272 | ACHIDrive_t* drives; 273 | uint8_t driveCount; 274 | }; 275 | 276 | class AHCI_Class { 277 | public: 278 | void scanControllers(); 279 | uint32_t getControllerCount(); 280 | ACHIController_t getController(uint32_t id); 281 | 282 | private: 283 | ACHIController_t* _ahciControllers; 284 | uint32_t _controllerCount; 285 | }; 286 | 287 | extern AHCI_Class AHCI; 288 | 289 | -------------------------------------------------------------------------------- /shell/shell.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define BochsBreak() outw(0x8A00,0x8A00); outw(0x8A00,0x08AE0); 25 | 26 | extern "C" { 27 | extern void* _END_ASM_USER_TASK; 28 | extern void* ASM_USER_TASK; 29 | } 30 | 31 | void task1(void) { 32 | printf("Beep beep letuce from userspace task"); 33 | while(1); 34 | return; 35 | } 36 | 37 | uint32_t testmap = 0; 38 | 39 | void shell_main(MultibootInfo_t* boot_info) { 40 | Terminal.setColor(0x02); 41 | Terminal.print("\nDankBASH v1.1, logged in as root, "); 42 | Terminal.print(itoa(boot_info->mem_upper / 1024, 10)); 43 | Terminal.println("Mb free.\n"); 44 | 45 | Terminal.setColor(0x07); 46 | Terminal.showCursor(2); 47 | 48 | while (true) { 49 | vector ints; 50 | ints.push_back(420); 51 | ints.pop_back(); 52 | ints.push_front(420); 53 | ints.pop_front(); 54 | Terminal.setColor(0x09); 55 | Terminal.print("MemeOS"); 56 | Terminal.setColor(0x07); 57 | Terminal.print("> "); 58 | 59 | string cmd_str = Terminal.readLine(); 60 | 61 | Terminal.println(""); 62 | 63 | if (cmd_str == "") { 64 | // Nothing 65 | } 66 | else if (cmd_str.startsWith("echo")) { 67 | if (cmd_str.length() > 5) { 68 | Terminal.println(cmd_str.substring(5)); 69 | } 70 | else { 71 | Terminal.setColor(0x04); 72 | Terminal.println("No argument !"); 73 | Terminal.setColor(0x07); 74 | } 75 | } 76 | else if (cmd_str == "memstats") { 77 | uint32_t used = Paging.getUsedPages() / 256; 78 | Terminal.print(itoa(used, 10)); 79 | Terminal.print("Mb used, "); 80 | Terminal.print(itoa((boot_info->mem_upper / 1024) - used, 10)); 81 | Terminal.print("Mb free, "); 82 | Terminal.print(itoa(boot_info->mem_upper / 1024, 10)); 83 | Terminal.print("Mb total ("); 84 | float percent = ((float)used / (float)(boot_info->mem_upper / 1024)) * 100; 85 | Terminal.print(itoa(percent, 10)); 86 | Terminal.println("%)"); 87 | } 88 | else if (cmd_str == "ping") { 89 | Terminal.println("Pong !"); 90 | } 91 | else if (cmd_str == "clear") { 92 | Terminal.clear(); 93 | } 94 | else if (cmd_str == "hddtest") { 95 | //parseFs(); 96 | ATAPIODrive_t drive(0); 97 | char* strlol = "Good evening peasants!"; 98 | drive.write(0x7FA, 22, (uint8_t*)strlol); 99 | } 100 | else if (cmd_str == "lspci") { 101 | for (uint8_t id = 0; id < PCI.getDeviceCount(); id++) { 102 | PCIDevice_t dev = PCI.getDevice(id); 103 | 104 | Terminal.print(itoa(dev.bus, 16)); 105 | Terminal.print(":"); 106 | Terminal.print(itoa(dev.slot, 16)); 107 | Terminal.print("."); 108 | Terminal.print(itoa(dev.function, 16)); 109 | Terminal.print(" - "); 110 | 111 | Terminal.print(dev.deviceChip); 112 | Terminal.print(": "); 113 | 114 | Terminal.print(dev.vendorFullName); 115 | Terminal.print(", "); 116 | Terminal.print(dev.deviceChipDesc); 117 | Terminal.print(" (rev "); 118 | Terminal.print(itoa(dev.revisionID, 10)); 119 | Terminal.println(")"); 120 | } 121 | } 122 | else if (cmd_str == "lsblk") { 123 | // for (uint8_t id = 0; id < AHCI.getControllerCount(); id++) { 124 | // ACHIController_t cnt = AHCI.getController(id); 125 | // for (uint8_t d = 0; d < cnt.driveCount; d++) { 126 | // ACHIDrive_t drv = cnt.drives[d]; 127 | // Terminal.print(itoa(drv.controllerID, 10)); 128 | // Terminal.print("."); 129 | // Terminal.print(itoa(d, 10)); 130 | // Terminal.print(": "); 131 | // if (drv.type == AHCI_DEV_SATA) { 132 | // Terminal.println("SATA"); 133 | // } 134 | // if (drv.type == AHCI_DEV_SEMB) { 135 | // Terminal.println("SEMB"); 136 | // } 137 | // if (drv.type == AHCI_DEV_PM) { 138 | // Terminal.println("PM"); 139 | // } 140 | // if (drv.type == AHCI_DEV_SATAPI) { 141 | // Terminal.println("SATAPI"); 142 | // } 143 | // } 144 | // } 145 | Terminal.println("WARNING: Unimplemented"); 146 | } 147 | else if (cmd_str == "rapemem") { 148 | for (int i = 0; i < 100; i++) { 149 | void* ptr = malloc(1024); 150 | } 151 | Terminal.println("DED xD"); 152 | } 153 | else if (cmd_str == "teststr") { 154 | string str = "Hello World!"; 155 | if (str.endWith("World!")) { 156 | Terminal.println(str.toLower()); 157 | } 158 | } 159 | else if (cmd_str == "time") { 160 | Time_t time = Time.getTime(); 161 | Terminal.print(dumpHexByte(time.hours)); 162 | Terminal.print(":"); 163 | Terminal.print(dumpHexByte(time.minutes)); 164 | Terminal.print(":"); 165 | Terminal.println(dumpHexByte(time.seconds)); 166 | Terminal.print(dumpHexByte(time.day)); 167 | Terminal.print("/"); 168 | Terminal.print(dumpHexByte(time.month)); 169 | Terminal.print("/"); 170 | Terminal.println(dumpHexByte(time.year)); 171 | } 172 | else if (cmd_str == "reboot") { 173 | uint8_t good = 0x02; 174 | while (good & 0x02) { 175 | good = inb(0x64); 176 | } 177 | outb(0x64, 0xFE); 178 | asm("hlt"); 179 | } 180 | else if (cmd_str == "syscall") { 181 | syscall(1, 2, 3, 4); 182 | } 183 | else if (cmd_str == "crash") { 184 | kernel_panic(0x4269, "Self triggered crash, no real exception here !"); 185 | } 186 | else if (cmd_str == "pagemap") { 187 | uint32_t phy = Paging.allocPages(1); 188 | Paging.mapPage(0x000F0000, phy, 0b11); 189 | Terminal.print("0x00000000 is now mapped to 0x"); 190 | Terminal.println(itoa(phy, 16)); 191 | testmap = phy; 192 | } 193 | else if (cmd_str == "checkmap") { 194 | uint8_t* ptr1 = (uint8_t*)0x000F0000; 195 | uint8_t* ptr2 = (uint8_t*)testmap; 196 | bool failed = false; 197 | for (int i = 0; i < 4096; i++) { 198 | if (ptr1[i] != ptr2[i]) { 199 | Terminal.print("Missmatch at 0x"); 200 | Terminal.println(itoa(i, 16)); 201 | failed = true; 202 | } 203 | } 204 | if (!failed) { 205 | Terminal.println("Mapping worked!"); 206 | } 207 | } 208 | else if (cmd_str == "tasktest") { 209 | Terminal.println(itoa((uint32_t)ASM_USER_TASK, 16)); 210 | Terminal.println(itoa((uint32_t)_END_ASM_USER_TASK, 16)); 211 | } 212 | else if (cmd_str == "task") { 213 | // Task map: 214 | // 0xF0000000 - 0xF0001000 => ustack 215 | // 0xF0001000 - 0xF0002000 => ucode, udata 216 | 217 | // Allocate pages 218 | Paging.setPresent(0x01000000, 1); // ustack 219 | Paging.setPresent(0x01001000, 1); // ucode 220 | 221 | Paging.setDirectoryFlags(0x01000000, 0x07); 222 | Paging.setDirectoryFlags(0x01001000, 0x07); 223 | Paging.setFlags(0x01000000, 0x07); 224 | Paging.setFlags(0x01001000, 0x07); 225 | 226 | // Define task segments 227 | // GDT.setGDTEntry(0x05, 0x01001000, 0x00000000, 0xFF); // ucode 228 | // GDT.setGDTEntry(0x06, 0x01001000, 0x00000000, 0xF3); // udata 229 | // GDT.setGDTEntry(0x07, 0x00000000, 0x00000020, 0xF7); // ustack 230 | 231 | GDT.allocEntry(0x01001000, 0x00000000, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW | GDT_ACCESS_PRIV_3, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); 232 | GDT.allocEntry(0x01001000, 0x00000000, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW | GDT_ACCESS_PRIV_3, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); 233 | GDT.allocEntry(0x00000000, 0x00000020, GDT_ACCESS_PRESENT | GDT_ACCESS_DIR_D | GDT_ACCESS_RW | GDT_ACCESS_PRIV_3, GDT_FLAG_SZ_32B); 234 | 235 | // Load task 236 | memmove((void*)0x01001000, (void*)&task1, 0xFFF); 237 | 238 | uint32_t st = (uint32_t)&ASM_STACK_TOP; 239 | 240 | asm(" cli \n \ 241 | push $0x3B \n \ 242 | push $0x01001000 \n \ 243 | pushfl \n \ 244 | popl %%eax \n \ 245 | orl $0x200, %%eax \n \ 246 | and $0xffffbfff, %%eax \n \ 247 | push %%eax \n \ 248 | push $0x2B \n \ 249 | push $0x0 \n \ 250 | movl $ASM_STACK_TOP, %0 \n \ 251 | movw $0x33, %%ax \n \ 252 | movw %%ax, %%ds \n \ 253 | iret" : "=m" (st) : ); 254 | } 255 | else { 256 | Terminal.setColor(0x04); 257 | Terminal.print("Unknown command: '"); 258 | Terminal.print(cmd_str); 259 | Terminal.println("'"); 260 | Terminal.setColor(0x07); 261 | } 262 | } 263 | } -------------------------------------------------------------------------------- /drivers/pci/src/pci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | PCI_Class PCI; 9 | 10 | uint16_t readConfig(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { 11 | uint32_t address; 12 | uint32_t lbus = (uint32_t)bus; 13 | uint32_t lslot = (uint32_t)slot; 14 | uint32_t lfunc = (uint32_t)func; 15 | uint16_t data = 0; 16 | 17 | address = (uint32_t)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); 18 | 19 | outl(PCI_CONFIG_ADDRESS, address); 20 | data = (uint16_t)((inl(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) & 0xffff); 21 | return data; 22 | } 23 | 24 | uint16_t PCI_Class::getVendorID(uint8_t bus, uint8_t slot, uint8_t function){ 25 | return readConfig(bus, slot, function, 0); 26 | } 27 | 28 | char* PCI_Class::getVendorShortName(uint16_t vendorID){ 29 | for (uint16_t i = 0; i < PCI_VENTABLE_LEN; i++) { 30 | if (PciVenTable[i].VenId == vendorID) { 31 | return PciVenTable[i].VenShort; 32 | } 33 | } 34 | return "UNKNOWN"; 35 | } 36 | 37 | char* PCI_Class::getVendorFullName(uint16_t vendorID){ 38 | for (uint16_t i = 0; i < PCI_VENTABLE_LEN; i++) { 39 | if (PciVenTable[i].VenId == vendorID) { 40 | return PciVenTable[i].VenFull; 41 | } 42 | } 43 | return "UNKNOWN"; 44 | } 45 | 46 | uint16_t PCI_Class::getDeviceID(uint8_t bus, uint8_t slot, uint8_t function){ 47 | return readConfig(bus, slot, function, 2); 48 | } 49 | 50 | char* PCI_Class::getDeviceName(uint16_t vendorID, uint16_t deviceID){ 51 | for (uint16_t i = 0; i < PCI_DEVTABLE_LEN; i++) { 52 | if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID) { 53 | return PciDevTable[i].Chip; 54 | } 55 | } 56 | return "UNKNOWN"; 57 | } 58 | 59 | char* PCI_Class::getDeviceDescription(uint16_t vendorID, uint16_t deviceID){ 60 | for (uint16_t i = 0; i < PCI_DEVTABLE_LEN; i++) { 61 | if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID) { 62 | return PciDevTable[i].ChipDesc; 63 | } 64 | } 65 | return "UNKNOWN"; 66 | } 67 | 68 | PCIDevice_t PCI_Class::getDevice(uint8_t bus, uint8_t slot, uint8_t function) { 69 | PCIDevice_t dev; 70 | dev.bus = bus; 71 | dev.slot = slot; 72 | dev.function = function; 73 | dev.vendorID = readConfig(bus, slot, function, 0x00); 74 | dev.deviceID = readConfig(bus, slot, function, 0x02); 75 | uint16_t _revid_progif = readConfig(bus, slot, function, 0x08); 76 | dev.revisionID = _revid_progif; 77 | dev.progIF = _revid_progif >> 8; 78 | uint16_t _subclass_classcode = readConfig(bus, slot, function, 0x0A); 79 | dev.subclass = _subclass_classcode; 80 | dev.classCode = _subclass_classcode >> 8; 81 | uint16_t _cls_ltm = readConfig(bus, slot, function, 0x0C); 82 | dev.cacheLineSize = _cls_ltm; 83 | dev.latencyTimer = _cls_ltm >> 8; 84 | uint16_t _hdt_bist = readConfig(bus, slot, function, 0x0E); 85 | dev.headerType = _hdt_bist; 86 | dev.bist = _hdt_bist >> 8; 87 | dev.vendorShortName = getVendorShortName(dev.vendorID); 88 | dev.vendorFullName = getVendorFullName(dev.vendorID); 89 | dev.deviceChip = getDeviceName(dev.vendorID, dev.deviceID); 90 | dev.deviceChipDesc = getDeviceDescription(dev.vendorID, dev.deviceID); 91 | if (dev.headerType == 0x00) { 92 | uint32_t _BAR0 = readConfig(bus, slot, function, 0x10); 93 | _BAR0 |= readConfig(bus, slot, function, 0x12) << 16; 94 | dev.standardHeader.BAR0 = _BAR0; 95 | uint32_t _BAR1 = readConfig(bus, slot, function, 0x14); 96 | _BAR1 |= readConfig(bus, slot, function, 0x16) << 16; 97 | dev.standardHeader.BAR1 = _BAR1; 98 | uint32_t _BAR2 = readConfig(bus, slot, function, 0x18); 99 | _BAR2 |= readConfig(bus, slot, function, 0x1A) << 16; 100 | dev.standardHeader.BAR2 = _BAR2; 101 | uint32_t _BAR3 = readConfig(bus, slot, function, 0x1C); 102 | _BAR3 |= readConfig(bus, slot, function, 0x1E) << 16; 103 | dev.standardHeader.BAR3 = _BAR3; 104 | uint32_t _BAR4 = readConfig(bus, slot, function, 0x20); 105 | _BAR4 |= readConfig(bus, slot, function, 0x22) << 16; 106 | dev.standardHeader.BAR4 = _BAR4; 107 | uint32_t _BAR5 = readConfig(bus, slot, function, 0x24); 108 | _BAR5 |= readConfig(bus, slot, function, 0x26) << 16; 109 | dev.standardHeader.BAR5 = _BAR5; 110 | uint32_t _CCP = readConfig(bus, slot, function, 0x28); 111 | _CCP |= readConfig(bus, slot, function, 0x2A) << 16; 112 | dev.standardHeader.cardbusCISPtr = _CCP; 113 | dev.standardHeader.subsysVendorID = readConfig(bus, slot, function, 0x2C); 114 | dev.standardHeader.subsysID = readConfig(bus, slot, function, 0x2E); 115 | uint32_t _ROM = readConfig(bus, slot, function, 0x30); 116 | _ROM |= readConfig(bus, slot, function, 0x32) << 16; 117 | dev.standardHeader.expROMAddr = _ROM; 118 | dev.standardHeader.capPtr = readConfig(bus, slot, function, 0x34); 119 | uint16_t _il_ip = readConfig(bus, slot, function, 0x3C); 120 | dev.standardHeader.intLine = _il_ip; 121 | dev.standardHeader.intPIN = _il_ip >> 8; 122 | uint16_t _mgr_mlt = readConfig(bus, slot, function, 0x3E); 123 | dev.standardHeader.minGrant = _mgr_mlt; 124 | dev.standardHeader.maxLantency = _mgr_mlt >> 8; 125 | } 126 | else if (dev.headerType == 0x01) { 127 | uint32_t _BAR0 = readConfig(bus, slot, function, 0x10); 128 | _BAR0 |= readConfig(bus, slot, function, 0x12) << 16; 129 | dev.pciToPciHeader.BAR0 = _BAR0; 130 | uint32_t _BAR1 = readConfig(bus, slot, function, 0x14); 131 | _BAR1 |= readConfig(bus, slot, function, 0x16) << 16; 132 | dev.pciToPciHeader.BAR1 = _BAR1; 133 | uint16_t _pbn_sbn = readConfig(bus, slot, function, 0x18); 134 | dev.pciToPciHeader.primBusNumber = _pbn_sbn; 135 | dev.pciToPciHeader.secBusNumber = _pbn_sbn >> 8; 136 | uint16_t _sbn_slt = readConfig(bus, slot, function, 0x1A); 137 | dev.pciToPciHeader.subBusNumber = _sbn_slt; 138 | dev.pciToPciHeader.secLatencyTimer = _sbn_slt >> 8; 139 | uint16_t _ib_il = readConfig(bus, slot, function, 0x1C); 140 | dev.pciToPciHeader.ioBase = _ib_il; 141 | dev.pciToPciHeader.ioLimit = _ib_il >> 8; 142 | dev.pciToPciHeader.secStatus = readConfig(bus, slot, function, 0x1E); 143 | dev.pciToPciHeader.memBase = readConfig(bus, slot, function, 0x20); 144 | dev.pciToPciHeader.memLimit = readConfig(bus, slot, function, 0x22); 145 | dev.pciToPciHeader.prefetchMemBase = readConfig(bus, slot, function, 0x24); 146 | dev.pciToPciHeader.prefetchMemLimit = readConfig(bus, slot, function, 0x26); 147 | uint32_t _PBU = readConfig(bus, slot, function, 0x28); 148 | _PBU |= readConfig(bus, slot, function, 0x2A) << 16; 149 | dev.pciToPciHeader.prefetchBaseUpper = _PBU; 150 | uint32_t _PLU = readConfig(bus, slot, function, 0x2C); 151 | _PLU |= readConfig(bus, slot, function, 0x2E) << 16; 152 | dev.pciToPciHeader.prefetchLimitUpper = _PLU; 153 | dev.pciToPciHeader.ioBaseUpper = readConfig(bus, slot, function, 0x30); 154 | dev.pciToPciHeader.ioLimitUpper = readConfig(bus, slot, function, 0x32); 155 | dev.pciToPciHeader.capPtr = readConfig(bus, slot, function, 0x34); 156 | uint16_t _il_ip = readConfig(bus, slot, function, 0x3C); 157 | dev.pciToPciHeader.intLine = _il_ip; 158 | dev.pciToPciHeader.intPIN = _il_ip >> 8; 159 | } 160 | else if (dev.headerType == 0x02) { // IMPORTANT !!!! FIX THIS NEXT !!!!!!! (replace signe byte reads by one with shift) 161 | uint32_t _CBA = readConfig(bus, slot, function, 0x10); 162 | _CBA |= readConfig(bus, slot, function, 0x12) << 16; 163 | dev.pciToCardbusHeader.cardbusBaseAddr = _CBA; 164 | dev.pciToCardbusHeader.capListOffset = readConfig(bus, slot, function, 0x14); 165 | dev.pciToCardbusHeader.secStatus = readConfig(bus, slot, function, 0x16); 166 | dev.pciToCardbusHeader.pciBusNumber = readConfig(bus, slot, function, 0x18); 167 | dev.pciToCardbusHeader.cardbusBusNuber = readConfig(bus, slot, function, 0x19); 168 | dev.pciToCardbusHeader.subBusNumber = readConfig(bus, slot, function, 0x1A); 169 | dev.pciToCardbusHeader.cardbusLatTimer = readConfig(bus, slot, function, 0x1B); 170 | uint32_t _MBA0 = readConfig(bus, slot, function, 0x1c); 171 | _MBA0 |= readConfig(bus, slot, function, 0x1E) << 16; 172 | dev.pciToCardbusHeader.cardbusBaseAddr = _MBA0; 173 | uint32_t _ML0 = readConfig(bus, slot, function, 0x20); 174 | _ML0 |= readConfig(bus, slot, function, 0x22) << 16; 175 | dev.pciToCardbusHeader.cardbusBaseAddr = _ML0; 176 | uint32_t _MBA1 = readConfig(bus, slot, function, 0x24); 177 | _MBA1 |= readConfig(bus, slot, function, 0x26) << 16; 178 | dev.pciToCardbusHeader.cardbusBaseAddr = _MBA1; 179 | uint32_t _ML1 = readConfig(bus, slot, function, 0x28); 180 | _ML1 |= readConfig(bus, slot, function, 0x2A) << 16; 181 | dev.pciToCardbusHeader.cardbusBaseAddr = _ML1; 182 | uint32_t _IBA0 = readConfig(bus, slot, function, 0x2C); 183 | _IBA0 |= readConfig(bus, slot, function, 0x2E) << 16; 184 | dev.pciToCardbusHeader.cardbusBaseAddr = _IBA0; 185 | uint32_t _IL0 = readConfig(bus, slot, function, 0x30); 186 | _IL0 |= readConfig(bus, slot, function, 0x32) << 16; 187 | dev.pciToCardbusHeader.cardbusBaseAddr = _IL0; 188 | uint32_t _IBA1 = readConfig(bus, slot, function, 0x34); 189 | _IBA1 |= readConfig(bus, slot, function, 0x36) << 16; 190 | dev.pciToCardbusHeader.cardbusBaseAddr = _IBA1; 191 | uint32_t _IL1 = readConfig(bus, slot, function, 0x38); 192 | _IL1 |= readConfig(bus, slot, function, 0x3A) << 16; 193 | dev.pciToCardbusHeader.cardbusBaseAddr = _IL1; 194 | dev.pciToCardbusHeader.intLine = readConfig(bus, slot, function, 0x3C); 195 | dev.pciToCardbusHeader.intPIN = readConfig(bus, slot, function, 0x3D); 196 | dev.pciToCardbusHeader.subsysDeviceID = readConfig(bus, slot, function, 0x40); 197 | dev.pciToCardbusHeader.intPIN = readConfig(bus, slot, function, 0x42); 198 | uint32_t _LBA = readConfig(bus, slot, function, 0x38); 199 | _LBA |= readConfig(bus, slot, function, 0x3A) << 16; 200 | dev.pciToCardbusHeader.cardbusBaseAddr = _LBA; 201 | } 202 | return dev; 203 | } 204 | 205 | void PCI_Class::scanDevices() { 206 | for (uint8_t bus = 0; bus < 16; bus++) { 207 | for (uint8_t slot = 0; slot < 32; slot++) { 208 | for (uint8_t function = 0; function < 8; function++) { 209 | uint16_t vendorID = PCI.getVendorID(bus, slot, function); 210 | if (vendorID != 0xFFFF) { 211 | _devices.push_back(PCI.getDevice(bus, slot, function)); 212 | } 213 | } 214 | } 215 | } 216 | } 217 | 218 | PCIDevice_t PCI_Class::getDevice(uint32_t id) { 219 | return _devices[id]; 220 | } 221 | 222 | uint32_t PCI_Class::getDeviceCount() { 223 | return _devices.size(); 224 | } -------------------------------------------------------------------------------- /libs/_old/pci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | PCI_Class PCI; 9 | 10 | uint16_t readConfig(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { 11 | uint32_t address; 12 | uint32_t lbus = (uint32_t)bus; 13 | uint32_t lslot = (uint32_t)slot; 14 | uint32_t lfunc = (uint32_t)func; 15 | uint16_t data = 0; 16 | 17 | address = (uint32_t)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); 18 | 19 | outl(PCI_CONFIG_ADDRESS, address); 20 | data = (uint16_t)((inl(PCI_CONFIG_DATA) >> ((offset & 2) * 8)) & 0xffff); 21 | return data; 22 | } 23 | 24 | uint16_t PCI_Class::getVendorID(uint8_t bus, uint8_t slot, uint8_t function){ 25 | return readConfig(bus, slot, function, 0); 26 | } 27 | 28 | char* PCI_Class::getVendorShortName(uint16_t vendorID){ 29 | for (uint16_t i = 0; i < PCI_VENTABLE_LEN; i++) { 30 | if (PciVenTable[i].VenId == vendorID) { 31 | return PciVenTable[i].VenShort; 32 | } 33 | } 34 | return "UNKNOWN"; 35 | } 36 | 37 | char* PCI_Class::getVendorFullName(uint16_t vendorID){ 38 | for (uint16_t i = 0; i < PCI_VENTABLE_LEN; i++) { 39 | if (PciVenTable[i].VenId == vendorID) { 40 | return PciVenTable[i].VenFull; 41 | } 42 | } 43 | return "UNKNOWN"; 44 | } 45 | 46 | uint16_t PCI_Class::getDeviceID(uint8_t bus, uint8_t slot, uint8_t function){ 47 | return readConfig(bus, slot, function, 2); 48 | } 49 | 50 | char* PCI_Class::getDeviceName(uint16_t vendorID, uint16_t deviceID){ 51 | for (uint16_t i = 0; i < PCI_DEVTABLE_LEN; i++) { 52 | if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID) { 53 | return PciDevTable[i].Chip; 54 | } 55 | } 56 | return "UNKNOWN"; 57 | } 58 | 59 | char* PCI_Class::getDeviceDescription(uint16_t vendorID, uint16_t deviceID){ 60 | for (uint16_t i = 0; i < PCI_DEVTABLE_LEN; i++) { 61 | if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID) { 62 | return PciDevTable[i].ChipDesc; 63 | } 64 | } 65 | return "UNKNOWN"; 66 | } 67 | 68 | PCIDevice_t PCI_Class::getDevice(uint8_t bus, uint8_t slot, uint8_t function) { 69 | PCIDevice_t dev; 70 | dev.bus = bus; 71 | dev.slot = slot; 72 | dev.function = function; 73 | dev.vendorID = readConfig(bus, slot, function, 0x00); 74 | dev.deviceID = readConfig(bus, slot, function, 0x02); 75 | uint16_t _revid_progif = readConfig(bus, slot, function, 0x08); 76 | dev.revisionID = _revid_progif; 77 | dev.progIF = _revid_progif >> 8; 78 | uint16_t _subclass_classcode = readConfig(bus, slot, function, 0x0A); 79 | dev.subclass = _subclass_classcode; 80 | dev.classCode = _subclass_classcode >> 8; 81 | uint16_t _cls_ltm = readConfig(bus, slot, function, 0x0C); 82 | dev.cacheLineSize = _cls_ltm; 83 | dev.latencyTimer = _cls_ltm >> 8; 84 | uint16_t _hdt_bist = readConfig(bus, slot, function, 0x0E); 85 | dev.headerType = _hdt_bist; 86 | dev.bist = _hdt_bist >> 8; 87 | dev.vendorShortName = getVendorShortName(dev.vendorID); 88 | dev.vendorFullName = getVendorFullName(dev.vendorID); 89 | dev.deviceChip = getDeviceName(dev.vendorID, dev.deviceID); 90 | dev.deviceChipDesc = getDeviceDescription(dev.vendorID, dev.deviceID); 91 | if (dev.headerType == 0x00) { 92 | uint32_t _BAR0 = readConfig(bus, slot, function, 0x10); 93 | _BAR0 |= readConfig(bus, slot, function, 0x12) << 16; 94 | dev.standardHeader.BAR0 = _BAR0; 95 | uint32_t _BAR1 = readConfig(bus, slot, function, 0x14); 96 | _BAR1 |= readConfig(bus, slot, function, 0x16) << 16; 97 | dev.standardHeader.BAR1 = _BAR1; 98 | uint32_t _BAR2 = readConfig(bus, slot, function, 0x18); 99 | _BAR2 |= readConfig(bus, slot, function, 0x1A) << 16; 100 | dev.standardHeader.BAR2 = _BAR2; 101 | uint32_t _BAR3 = readConfig(bus, slot, function, 0x1C); 102 | _BAR3 |= readConfig(bus, slot, function, 0x1E) << 16; 103 | dev.standardHeader.BAR3 = _BAR3; 104 | uint32_t _BAR4 = readConfig(bus, slot, function, 0x20); 105 | _BAR4 |= readConfig(bus, slot, function, 0x22) << 16; 106 | dev.standardHeader.BAR4 = _BAR4; 107 | uint32_t _BAR5 = readConfig(bus, slot, function, 0x24); 108 | _BAR5 |= readConfig(bus, slot, function, 0x26) << 16; 109 | dev.standardHeader.BAR5 = _BAR5; 110 | uint32_t _CCP = readConfig(bus, slot, function, 0x28); 111 | _CCP |= readConfig(bus, slot, function, 0x2A) << 16; 112 | dev.standardHeader.cardbusCISPtr = _CCP; 113 | dev.standardHeader.subsysVendorID = readConfig(bus, slot, function, 0x2C); 114 | dev.standardHeader.subsysID = readConfig(bus, slot, function, 0x2E); 115 | uint32_t _ROM = readConfig(bus, slot, function, 0x30); 116 | _ROM |= readConfig(bus, slot, function, 0x32) << 16; 117 | dev.standardHeader.expROMAddr = _ROM; 118 | dev.standardHeader.capPtr = readConfig(bus, slot, function, 0x34); 119 | uint16_t _il_ip = readConfig(bus, slot, function, 0x3C); 120 | dev.standardHeader.intLine = _il_ip; 121 | dev.standardHeader.intPIN = _il_ip >> 8; 122 | uint16_t _mgr_mlt = readConfig(bus, slot, function, 0x3E); 123 | dev.standardHeader.minGrant = _mgr_mlt; 124 | dev.standardHeader.maxLantency = _mgr_mlt >> 8; 125 | } 126 | else if (dev.headerType == 0x01) { 127 | uint32_t _BAR0 = readConfig(bus, slot, function, 0x10); 128 | _BAR0 |= readConfig(bus, slot, function, 0x12) << 16; 129 | dev.pciToPciHeader.BAR0 = _BAR0; 130 | uint32_t _BAR1 = readConfig(bus, slot, function, 0x14); 131 | _BAR1 |= readConfig(bus, slot, function, 0x16) << 16; 132 | dev.pciToPciHeader.BAR1 = _BAR1; 133 | uint16_t _pbn_sbn = readConfig(bus, slot, function, 0x18); 134 | dev.pciToPciHeader.primBusNumber = _pbn_sbn; 135 | dev.pciToPciHeader.secBusNumber = _pbn_sbn >> 8; 136 | uint16_t _sbn_slt = readConfig(bus, slot, function, 0x1A); 137 | dev.pciToPciHeader.subBusNumber = _sbn_slt; 138 | dev.pciToPciHeader.secLatencyTimer = _sbn_slt >> 8; 139 | uint16_t _ib_il = readConfig(bus, slot, function, 0x1C); 140 | dev.pciToPciHeader.ioBase = _ib_il; 141 | dev.pciToPciHeader.ioLimit = _ib_il >> 8; 142 | dev.pciToPciHeader.secStatus = readConfig(bus, slot, function, 0x1E); 143 | dev.pciToPciHeader.memBase = readConfig(bus, slot, function, 0x20); 144 | dev.pciToPciHeader.memLimit = readConfig(bus, slot, function, 0x22); 145 | dev.pciToPciHeader.prefetchMemBase = readConfig(bus, slot, function, 0x24); 146 | dev.pciToPciHeader.prefetchMemLimit = readConfig(bus, slot, function, 0x26); 147 | uint32_t _PBU = readConfig(bus, slot, function, 0x28); 148 | _PBU |= readConfig(bus, slot, function, 0x2A) << 16; 149 | dev.pciToPciHeader.prefetchBaseUpper = _PBU; 150 | uint32_t _PLU = readConfig(bus, slot, function, 0x2C); 151 | _PLU |= readConfig(bus, slot, function, 0x2E) << 16; 152 | dev.pciToPciHeader.prefetchLimitUpper = _PLU; 153 | dev.pciToPciHeader.ioBaseUpper = readConfig(bus, slot, function, 0x30); 154 | dev.pciToPciHeader.ioLimitUpper = readConfig(bus, slot, function, 0x32); 155 | dev.pciToPciHeader.capPtr = readConfig(bus, slot, function, 0x34); 156 | uint16_t _il_ip = readConfig(bus, slot, function, 0x3C); 157 | dev.pciToPciHeader.intLine = _il_ip; 158 | dev.pciToPciHeader.intPIN = _il_ip >> 8; 159 | } 160 | else if (dev.headerType == 0x02) { // IMPORTANT !!!! FIX THIS NEXT !!!!!!! (replace signe byte reads by one with shift) 161 | uint32_t _CBA = readConfig(bus, slot, function, 0x10); 162 | _CBA |= readConfig(bus, slot, function, 0x12) << 16; 163 | dev.pciToCardbusHeader.cardbusBaseAddr = _CBA; 164 | dev.pciToCardbusHeader.capListOffset = readConfig(bus, slot, function, 0x14); 165 | dev.pciToCardbusHeader.secStatus = readConfig(bus, slot, function, 0x16); 166 | dev.pciToCardbusHeader.pciBusNumber = readConfig(bus, slot, function, 0x18); 167 | dev.pciToCardbusHeader.cardbusBusNuber = readConfig(bus, slot, function, 0x19); 168 | dev.pciToCardbusHeader.subBusNumber = readConfig(bus, slot, function, 0x1A); 169 | dev.pciToCardbusHeader.cardbusLatTimer = readConfig(bus, slot, function, 0x1B); 170 | uint32_t _MBA0 = readConfig(bus, slot, function, 0x1c); 171 | _MBA0 |= readConfig(bus, slot, function, 0x1E) << 16; 172 | dev.pciToCardbusHeader.cardbusBaseAddr = _MBA0; 173 | uint32_t _ML0 = readConfig(bus, slot, function, 0x20); 174 | _ML0 |= readConfig(bus, slot, function, 0x22) << 16; 175 | dev.pciToCardbusHeader.cardbusBaseAddr = _ML0; 176 | uint32_t _MBA1 = readConfig(bus, slot, function, 0x24); 177 | _MBA1 |= readConfig(bus, slot, function, 0x26) << 16; 178 | dev.pciToCardbusHeader.cardbusBaseAddr = _MBA1; 179 | uint32_t _ML1 = readConfig(bus, slot, function, 0x28); 180 | _ML1 |= readConfig(bus, slot, function, 0x2A) << 16; 181 | dev.pciToCardbusHeader.cardbusBaseAddr = _ML1; 182 | uint32_t _IBA0 = readConfig(bus, slot, function, 0x2C); 183 | _IBA0 |= readConfig(bus, slot, function, 0x2E) << 16; 184 | dev.pciToCardbusHeader.cardbusBaseAddr = _IBA0; 185 | uint32_t _IL0 = readConfig(bus, slot, function, 0x30); 186 | _IL0 |= readConfig(bus, slot, function, 0x32) << 16; 187 | dev.pciToCardbusHeader.cardbusBaseAddr = _IL0; 188 | uint32_t _IBA1 = readConfig(bus, slot, function, 0x34); 189 | _IBA1 |= readConfig(bus, slot, function, 0x36) << 16; 190 | dev.pciToCardbusHeader.cardbusBaseAddr = _IBA1; 191 | uint32_t _IL1 = readConfig(bus, slot, function, 0x38); 192 | _IL1 |= readConfig(bus, slot, function, 0x3A) << 16; 193 | dev.pciToCardbusHeader.cardbusBaseAddr = _IL1; 194 | dev.pciToCardbusHeader.intLine = readConfig(bus, slot, function, 0x3C); 195 | dev.pciToCardbusHeader.intPIN = readConfig(bus, slot, function, 0x3D); 196 | dev.pciToCardbusHeader.subsysDeviceID = readConfig(bus, slot, function, 0x40); 197 | dev.pciToCardbusHeader.intPIN = readConfig(bus, slot, function, 0x42); 198 | uint32_t _LBA = readConfig(bus, slot, function, 0x38); 199 | _LBA |= readConfig(bus, slot, function, 0x3A) << 16; 200 | dev.pciToCardbusHeader.cardbusBaseAddr = _LBA; 201 | } 202 | return dev; 203 | } 204 | 205 | void PCI_Class::scanDevices() { 206 | _devices = (PCIDevice_t*)malloc(sizeof(PCIDevice_t)); 207 | for (uint8_t bus = 0; bus < 16; bus++) { 208 | for (uint8_t slot = 0; slot < 32; slot++) { 209 | for (uint8_t function = 0; function < 8; function++) { 210 | uint16_t vendorID = PCI.getVendorID(bus, slot, function); 211 | if (vendorID != 0xFFFF) { 212 | PCIDevice_t dev = PCI.getDevice(bus, slot, function); 213 | _deviceCount++; 214 | _devices = (PCIDevice_t*)realloc((void*)_devices, sizeof(PCIDevice_t) * _deviceCount); 215 | _devices[_deviceCount - 1] = dev; 216 | } 217 | } 218 | } 219 | } 220 | } 221 | 222 | PCIDevice_t PCI_Class::getDevice(uint32_t id) { 223 | if (id < _deviceCount) { 224 | return _devices[id]; 225 | } 226 | else { 227 | PCIDevice_t invalid; 228 | invalid.vendorID = 0xFFFF; 229 | return invalid; 230 | } 231 | } 232 | 233 | uint32_t PCI_Class::getDeviceCount() { 234 | return _deviceCount; 235 | } -------------------------------------------------------------------------------- /libs/kernel/src/liballoc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // =============================== MY PART =============================== 7 | 8 | int liballoc_lock() { 9 | return 0; 10 | } 11 | 12 | int liballoc_unlock() { 13 | return 0; 14 | } 15 | 16 | void* liballoc_alloc(int p) { 17 | uint32_t ptr = Paging.allocPages(p); 18 | return (void*)ptr; 19 | } 20 | 21 | int liballoc_free(void* ptr,int p) { 22 | Paging.setAbsent((uint32_t)ptr, p); 23 | return 0; 24 | } 25 | 26 | // =============================== MY PART =============================== 27 | 28 | /** Durand's Ridiculously Amazing Super Duper Memory functions. */ 29 | 30 | //#define DEBUG 31 | 32 | #define LIBALLOC_MAGIC 0xc001c0de 33 | #define MAXCOMPLETE 5 34 | #define MAXEXP 32 35 | #define MINEXP 8 36 | 37 | #define MODE_BEST 0 38 | #define MODE_INSTANT 1 39 | 40 | #define MODE MODE_BEST 41 | 42 | #ifdef DEBUG 43 | #include 44 | #endif 45 | 46 | 47 | struct boundary_tag* l_freePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks 48 | int l_completePages[MAXEXP]; //< Allowing for 2^MAXEXP blocks 49 | 50 | 51 | #ifdef DEBUG 52 | unsigned int l_allocated = 0; //< The real amount of memory allocated. 53 | unsigned int l_inuse = 0; //< The amount of memory in use (malloc'ed). 54 | #endif 55 | 56 | 57 | static int l_initialized = 0; //< Flag to indicate initialization. 58 | static int l_pageSize = 4096; //< Individual page size 59 | static int l_pageCount = 16; //< Minimum number of pages to allocate. 60 | 61 | 62 | // *********** HELPER FUNCTIONS ******************************* 63 | 64 | /** Returns the exponent required to manage 'size' amount of memory. 65 | * 66 | * Returns n where 2^n <= size < 2^(n+1) 67 | */ 68 | static inline int getexp( unsigned int size ) 69 | { 70 | if ( size < (1< size ) break; 84 | shift += 1; 85 | } 86 | 87 | #ifdef DEBUG 88 | printf("getexp returns %i (%i bytes) for %i size\n", shift - 1, (1<<(shift -1)), size ); 89 | #endif 90 | 91 | return shift - 1; 92 | } 93 | 94 | 95 | static void* liballoc_memset(void* s, int c, size_t n) 96 | { 97 | int i; 98 | for ( i = 0; i < n ; i++) 99 | ((char*)s)[i] = c; 100 | 101 | return s; 102 | } 103 | 104 | static void* liballoc_memcpy(void* s1, const void* s2, size_t n) 105 | { 106 | char *cdest; 107 | char *csrc; 108 | unsigned int *ldest = (unsigned int*)s1; 109 | unsigned int *lsrc = (unsigned int*)s2; 110 | 111 | while ( n >= sizeof(unsigned int) ) 112 | { 113 | *ldest++ = *lsrc++; 114 | n -= sizeof(unsigned int); 115 | } 116 | 117 | cdest = (char*)ldest; 118 | csrc = (char*)lsrc; 119 | 120 | while ( n > 0 ) 121 | { 122 | *cdest++ = *csrc++; 123 | n -= 1; 124 | } 125 | 126 | return s1; 127 | } 128 | 129 | 130 | 131 | #ifdef DEBUG 132 | static void dump_array() 133 | { 134 | int i = 0; 135 | struct boundary_tag *tag = NULL; 136 | 137 | printf("------ Free pages array ---------\n"); 138 | printf("System memory allocated: %i\n", l_allocated ); 139 | printf("Memory in used (malloc'ed): %i\n", l_inuse ); 140 | 141 | for ( i = 0; i < MAXEXP; i++ ) 142 | { 143 | printf("%.2i(%i): ",i, l_completePages[i] ); 144 | 145 | tag = l_freePages[ i ]; 146 | while ( tag != NULL ) 147 | { 148 | if ( tag->split_left != NULL ) printf("*"); 149 | printf("%i", tag->real_size ); 150 | if ( tag->split_right != NULL ) printf("*"); 151 | 152 | printf(" "); 153 | tag = tag->next; 154 | } 155 | printf("\n"); 156 | } 157 | 158 | printf("'*' denotes a split to the left/right of a tag\n"); 159 | fflush( stdout ); 160 | } 161 | #endif 162 | 163 | 164 | 165 | static inline void insert_tag( struct boundary_tag *tag, int index ) 166 | { 167 | int realIndex; 168 | 169 | if ( index < 0 ) 170 | { 171 | realIndex = getexp( tag->real_size - sizeof(struct boundary_tag) ); 172 | if ( realIndex < MINEXP ) realIndex = MINEXP; 173 | } 174 | else 175 | realIndex = index; 176 | 177 | tag->index = realIndex; 178 | 179 | if ( l_freePages[ realIndex ] != NULL ) 180 | { 181 | l_freePages[ realIndex ]->prev = tag; 182 | tag->next = l_freePages[ realIndex ]; 183 | } 184 | 185 | l_freePages[ realIndex ] = tag; 186 | } 187 | 188 | static inline void remove_tag( struct boundary_tag *tag ) 189 | { 190 | if ( l_freePages[ tag->index ] == tag ) l_freePages[ tag->index ] = tag->next; 191 | 192 | if ( tag->prev != NULL ) tag->prev->next = tag->next; 193 | if ( tag->next != NULL ) tag->next->prev = tag->prev; 194 | 195 | tag->next = NULL; 196 | tag->prev = NULL; 197 | tag->index = -1; 198 | } 199 | 200 | 201 | static inline struct boundary_tag* melt_left( struct boundary_tag *tag ) 202 | { 203 | struct boundary_tag *left = tag->split_left; 204 | 205 | left->real_size += tag->real_size; 206 | left->split_right = tag->split_right; 207 | 208 | if ( tag->split_right != NULL ) tag->split_right->split_left = left; 209 | 210 | return left; 211 | } 212 | 213 | 214 | static inline struct boundary_tag* absorb_right( struct boundary_tag *tag ) 215 | { 216 | struct boundary_tag *right = tag->split_right; 217 | 218 | remove_tag( right ); // Remove right from free pages. 219 | 220 | tag->real_size += right->real_size; 221 | 222 | tag->split_right = right->split_right; 223 | if ( right->split_right != NULL ) 224 | right->split_right->split_left = tag; 225 | 226 | return tag; 227 | } 228 | 229 | static inline struct boundary_tag* split_tag( struct boundary_tag* tag ) 230 | { 231 | unsigned int remainder = tag->real_size - sizeof(struct boundary_tag) - tag->size; 232 | 233 | struct boundary_tag *new_tag = 234 | (struct boundary_tag*)((unsigned int)tag + sizeof(struct boundary_tag) + tag->size); 235 | 236 | new_tag->magic = LIBALLOC_MAGIC; 237 | new_tag->real_size = remainder; 238 | 239 | new_tag->next = NULL; 240 | new_tag->prev = NULL; 241 | 242 | new_tag->split_left = tag; 243 | new_tag->split_right = tag->split_right; 244 | 245 | if (new_tag->split_right != NULL) new_tag->split_right->split_left = new_tag; 246 | tag->split_right = new_tag; 247 | 248 | tag->real_size -= new_tag->real_size; 249 | 250 | insert_tag( new_tag, -1 ); 251 | 252 | return new_tag; 253 | } 254 | 255 | 256 | // *************************************************************** 257 | 258 | 259 | 260 | 261 | static struct boundary_tag* allocate_new_tag( unsigned int size ) 262 | { 263 | unsigned int pages; 264 | unsigned int usage; 265 | struct boundary_tag *tag; 266 | 267 | // This is how much space is required. 268 | usage = size + sizeof(struct boundary_tag); 269 | 270 | // Perfect amount of space 271 | pages = usage / l_pageSize; 272 | if ( (usage % l_pageSize) != 0 ) pages += 1; 273 | 274 | // Make sure it's >= the minimum size. 275 | if ( pages < l_pageCount ) pages = l_pageCount; 276 | 277 | tag = (struct boundary_tag*)liballoc_alloc( pages ); 278 | 279 | if ( tag == NULL ) return NULL; // uh oh, we ran out of memory. 280 | 281 | tag->magic = LIBALLOC_MAGIC; 282 | tag->size = size; 283 | tag->real_size = pages * l_pageSize; 284 | tag->index = -1; 285 | 286 | tag->next = NULL; 287 | tag->prev = NULL; 288 | tag->split_left = NULL; 289 | tag->split_right = NULL; 290 | 291 | 292 | #ifdef DEBUG 293 | printf("Resource allocated %x of %i pages (%i bytes) for %i size.\n", tag, pages, pages * l_pageSize, size ); 294 | 295 | l_allocated += pages * l_pageSize; 296 | 297 | printf("Total memory usage = %i KB\n", (int)((l_allocated / (1024))) ); 298 | #endif 299 | 300 | return tag; 301 | } 302 | 303 | 304 | 305 | void *malloc(size_t size) 306 | { 307 | int index; 308 | void *ptr; 309 | struct boundary_tag *tag = NULL; 310 | 311 | liballoc_lock(); 312 | 313 | if ( l_initialized == 0 ) 314 | { 315 | #ifdef DEBUG 316 | printf("%s\n","liballoc initializing."); 317 | #endif 318 | for ( index = 0; index < MAXEXP; index++ ) 319 | { 320 | l_freePages[index] = NULL; 321 | l_completePages[index] = 0; 322 | } 323 | l_initialized = 1; 324 | } 325 | 326 | index = getexp( size ) + MODE; 327 | if ( index < MINEXP ) index = MINEXP; 328 | 329 | 330 | // Find one big enough. 331 | tag = l_freePages[ index ]; // Start at the front of the list. 332 | while ( tag != NULL ) 333 | { 334 | // If there's enough space in this tag. 335 | if ( (tag->real_size - sizeof(struct boundary_tag)) 336 | >= (size + sizeof(struct boundary_tag) ) ) 337 | { 338 | #ifdef DEBUG 339 | printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) ); 340 | #endif 341 | break; 342 | } 343 | 344 | tag = tag->next; 345 | } 346 | 347 | 348 | // No page found. Make one. 349 | if ( tag == NULL ) 350 | { 351 | if ( (tag = allocate_new_tag( size )) == NULL ) 352 | { 353 | liballoc_unlock(); 354 | return NULL; 355 | } 356 | 357 | index = getexp( tag->real_size - sizeof(struct boundary_tag) ); 358 | } 359 | else 360 | { 361 | remove_tag( tag ); 362 | 363 | if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) 364 | l_completePages[ index ] -= 1; 365 | } 366 | 367 | // We have a free page. Remove it from the free pages list. 368 | 369 | tag->size = size; 370 | 371 | // Removed... see if we can re-use the excess space. 372 | 373 | #ifdef DEBUG 374 | printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder 378 | 379 | if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<= 0 ) 384 | { 385 | #ifdef DEBUG 386 | printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<real_size, new_tag->real_size, new_tag->index ); 395 | #endif 396 | } 397 | } 398 | 399 | 400 | 401 | ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) ); 402 | 403 | 404 | 405 | #ifdef DEBUG 406 | l_inuse += size; 407 | printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 ); 408 | dump_array(); 409 | #endif 410 | 411 | 412 | liballoc_unlock(); 413 | return ptr; 414 | } 415 | 416 | 417 | 418 | 419 | 420 | void free(void *ptr) 421 | { 422 | int index; 423 | struct boundary_tag *tag; 424 | 425 | if ( ptr == NULL ) return; 426 | 427 | liballoc_lock(); 428 | 429 | 430 | tag = (struct boundary_tag*)((unsigned int)ptr - sizeof( struct boundary_tag )); 431 | 432 | if ( tag->magic != LIBALLOC_MAGIC ) 433 | { 434 | liballoc_unlock(); // release the lock 435 | return; 436 | } 437 | 438 | 439 | 440 | #ifdef DEBUG 441 | l_inuse -= tag->size; 442 | printf("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 ); 443 | #endif 444 | 445 | 446 | // MELT LEFT... 447 | while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) ) 448 | { 449 | #ifdef DEBUG 450 | printf("Melting tag left into available memory. Left was %i, becomes %i (%i)\n", tag->split_left->real_size, tag->split_left->real_size + tag->real_size, tag->split_left->real_size ); 451 | #endif 452 | tag = melt_left( tag ); 453 | remove_tag( tag ); 454 | } 455 | 456 | // MELT RIGHT... 457 | while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) ) 458 | { 459 | #ifdef DEBUG 460 | printf("Melting tag right into available memory. This was was %i, becomes %i (%i)\n", tag->real_size, tag->split_right->real_size + tag->real_size, tag->split_right->real_size ); 461 | #endif 462 | tag = absorb_right( tag ); 463 | } 464 | 465 | 466 | // Where is it going back to? 467 | index = getexp( tag->real_size - sizeof(struct boundary_tag) ); 468 | if ( index < MINEXP ) index = MINEXP; 469 | 470 | // A whole, empty block? 471 | if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) 472 | { 473 | 474 | if ( l_completePages[ index ] == MAXCOMPLETE ) 475 | { 476 | // Too many standing by to keep. Free this one. 477 | unsigned int pages = tag->real_size / l_pageSize; 478 | 479 | if ( (tag->real_size % l_pageSize) != 0 ) pages += 1; 480 | if ( pages < l_pageCount ) pages = l_pageCount; 481 | 482 | liballoc_free( tag, pages ); 483 | 484 | #ifdef DEBUG 485 | l_allocated -= pages * l_pageSize; 486 | printf("Resource freeing %x of %i pages\n", tag, pages ); 487 | dump_array(); 488 | #endif 489 | 490 | liballoc_unlock(); 491 | return; 492 | } 493 | 494 | 495 | l_completePages[ index ] += 1; // Increase the count of complete pages. 496 | } 497 | 498 | 499 | // .......... 500 | 501 | 502 | insert_tag( tag, index ); 503 | 504 | #ifdef DEBUG 505 | printf("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n", tag->real_size, tag->size, index ); 506 | dump_array(); 507 | #endif 508 | 509 | liballoc_unlock(); 510 | } 511 | 512 | 513 | 514 | 515 | void* calloc(size_t nobj, size_t size) 516 | { 517 | int real_size; 518 | void *p; 519 | 520 | real_size = nobj * size; 521 | 522 | p = malloc( real_size ); 523 | 524 | liballoc_memset( p, 0, real_size ); 525 | 526 | return p; 527 | } 528 | 529 | 530 | 531 | void* realloc(void *p, size_t size) 532 | { 533 | void *ptr; 534 | struct boundary_tag *tag; 535 | int real_size; 536 | 537 | if ( size == 0 ) 538 | { 539 | free( p ); 540 | return NULL; 541 | } 542 | if ( p == NULL ) return malloc( size ); 543 | 544 | if ( liballoc_lock != NULL ) liballoc_lock(); // lockit 545 | tag = (struct boundary_tag*)((unsigned int)p - sizeof( struct boundary_tag )); 546 | real_size = tag->size; 547 | if ( liballoc_unlock != NULL ) liballoc_unlock(); 548 | 549 | if ( real_size > size ) real_size = size; 550 | 551 | ptr = malloc( size ); 552 | liballoc_memcpy( ptr, p, real_size ); 553 | free( p ); 554 | 555 | return ptr; 556 | } --------------------------------------------------------------------------------