diff --git a/.gitignore b/.gitignore index e92c619..2f31296 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Object files *.o +*.o_asm *.ko *.obj *.elf diff --git a/Makefile b/Makefile index c14cf79..4831902 100644 --- a/Makefile +++ b/Makefile @@ -1,48 +1,74 @@ -LD = x86_64-elf-ld +LD = i686-elf-ld LFLAGS = -melf_i386 -nostdlib -O2 -T link.ld all: prepare cpu kernel_code drivers libc userspace mem link iso prepare: - mkdir -p obj/ - mkdir -p isodir/boot/grub/ - cp grub.cfg isodir/boot/grub/grub.cfg + @mkdir -p obj/ + @mkdir -p isodir/boot/grub/ + @echo [MKDIR] obj/ + @echo [MKDIR] isodir/boot/grub + @cp grub.cfg isodir/boot/grub/grub.cfg + @echo [CP] grub.cfg isodir/boot/grub.cfg cpu: - make -C kernel/cpu - cp kernel/cpu/*.o obj/ + @echo [DIR] kernel/cpu + @make -sC kernel/cpu + @cp kernel/cpu/*.o_asm obj/ + @echo [CP] kernel/cpu/*.o obj/ kernel_code: - make -C kernel - cp kernel/*.o obj/ + @echo [DIR] kernel/ + @make -sC kernel + @cp kernel/*.o obj/ + @echo [CP] kernel/*.o obj/ drivers: - make -C kernel/drivers/ - cp kernel/drivers/*.o obj/ + @echo [DIR] kernel/drivers/ + @make -sC kernel/drivers + @cp kernel/drivers/*.o obj/ + @echo [CP] kernel/drivers/*.o obj/ libc: - make -C kernel/libc - cp kernel/libc/*.o obj/ + @echo [DIR] kernel/libc/ + @make -sC kernel/libc + @cp kernel/libc/*.o obj/ + @echo [CP] kernel/libc/*.o obj/ userspace: - make -C kernel/userspace - cp kernel/userspace/*.o obj/ + @echo [DIR] kernel/userspace/ + @make -sC kernel/userspace + @cp kernel/userspace/*.o obj/ + @echo [CP] kernel/userspace/*.o obj/ mem: - make -C kernel/mem - cp kernel/mem/*.o obj/ + @echo [DIR] kernel/mem + @make -sC kernel/mem + @cp kernel/mem/*.o obj/ + @echo [CP] kernel/mem/*.o obj/ link: - $(LD) $(LFLAGS) -o isodir/boot/vulcanos.bin obj/*.o + @$(LD) $(LFLAGS) -o isodir/boot/vulcanos.bin obj/*.o obj/*.o_asm + @echo [LD] Linking blob... iso: - grub-mkrescue isodir -o vulcanos.iso + @echo [ISO] Creating ISO file... + @grub-mkrescue isodir -o vulcanos.iso > /dev/null 2>&1 clean: - rm -rf obj/ kernel/*.o kernel/cpu/*.o - rm -rf kernel/userspace/*.o kernel/mem/*.o - rm -rf kernel/drivers/*.o kernel/libc/*.o - rm -rf vulcanos.iso bochslog.txt commands isodir + @rm -rf obj/ kernel/*.o kernel/cpu/*.o_asm + @echo [RM] obj + @echo [RM] kernel/*.o + @echo [RM] kernel/cpu/*.o_asm + @rm -rf kernel/userspace/*.o kernel/mem/*.o + @echo [RM] kernel/userspace/*.o + @echo [RM] kernel/mem/*.o + @rm -rf kernel/drivers/*.o kernel/libc/*.o + @echo [RM] kernel/drivers/*.o + @echo [RM] kernel/libc/*.o + @rm -rf vulcanos.iso bochslog.txt commands isodir + @echo [RM] vulcanos.iso + @echo [RM] isodir bochs: bochs -f bochs_cfg -q diff --git a/README.md b/README.md index 99e70b3..b6f1072 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ After that, you can build VulcanOS just by running the commands below: 2. Type `make run` to start it in QEMU or `make bochs` to start it with bochs. You can also find an ISO file -[here](https://github.com/ice-bit/vulcanos/raw/master/imgs/vulcanos.iso)(md5sum: `a706cdfeea573e08550e599717d3f519`) +[here](https://github.com/ice-bit/vulcanos/raw/master/imgs/vulcanos.iso)(md5sum: `11375e1e169069b85c14d3cb6c5a4f06`) ## Features Right now, VulcanOS supports the following features: diff --git a/imgs/vulcanos.iso b/imgs/vulcanos.iso index b503130..89a998f 100644 Binary files a/imgs/vulcanos.iso and b/imgs/vulcanos.iso differ diff --git a/kernel/Makefile b/kernel/Makefile index 018ced4..eaf2b27 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,10 +1,11 @@ OBJS = kernel_main.o -CC = x86_64-elf-gcc # cross-compiler +CC = i686-elf-gcc # cross-compiler CFLAGS = -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c all: ${OBJS} %.o: %.c - $(CC) $(CFLAGS) $< -o $@ \ No newline at end of file + @$(CC) $(CFLAGS) $< -o $@ + @echo [CC] Compiling $<... \ No newline at end of file diff --git a/kernel/cpu/Makefile b/kernel/cpu/Makefile index 417471d..4349411 100644 --- a/kernel/cpu/Makefile +++ b/kernel/cpu/Makefile @@ -1,9 +1,12 @@ -OBJS = main.asm.o main64.asm.o ports.asm.o \ - gdt.asm.o idt.asm.o \ - interrupts.asm.o header.asm.o - +SOURCES = main.asm ports.asm \ + gdt.asm idt.asm \ + interrupts.asm header.asm +OBJS = $(SOURCES:.asm=.o_asm) ASM = nasm ASMFLAGS = -f elf32 + all: $(OBJS) -%.asm.o: %.asm - $(ASM) $(ASMFLAGS) $< -o $@ + +%.o_asm: %.asm + @$(ASM) $(ASMFLAGS) $< -o $@ + @echo [ASM] compiling $<... \ No newline at end of file diff --git a/kernel/cpu/main.asm b/kernel/cpu/main.asm index f03547b..d107ace 100644 --- a/kernel/cpu/main.asm +++ b/kernel/cpu/main.asm @@ -5,169 +5,23 @@ ; Released under GPLv3 ; ; https://github.com/ice-bit/vulcanos ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -EXTERN long_mode_start +GLOBAL kernel_loader +EXTERN kernel_main [BITS 32] ; Ensure we are in protected mode section .text kernel_loader: mov esp, kernel_stack + KERNEL_STACK_SZ ; Define stack pointer - ; Now we need to switch to Long Mode(i.e., 64bit mode) - ; to do that, we first need to check if we actually are - ; being loaded by a multiboot compliant bootloader. Then, - ; we will execute CPUID instruction in order to obtain details - ; about out CPU(i.e., if the CPU supports long mode). - call check_multiboot - call check_cpuid - call check_long_mode - - ; After that, we need to setup paging - call setup_page_tables - call enable_paging - - ; We also need to load a GDT - lgdt[gdt64.pointer] - jmp gdt64.code_segment:long_mode_start push eax ; Set multiboot header register - - -check_multiboot: - ; To prove that we are being loaded by a multiboot - ; bootloader, we can read the EAX register to see if - ; it contains the magic number - cmp eax, 0xE85250D6 - jne .multiboot_panic - ret - -.multiboot_panic: - ; We handle this error by showing a special code - mov al, "M" - jmp error ; Call print routine - -check_cpuid: - ; To check if CPUID is available we need to flip - ; ID bit of the flag register, if this is possibile - ; then CPUID instruction is available. In order to achieve - pushfd ; Push flag register into the stack - pop eax ; Pop the stack - mov ecx, eax ; Make a copy of the stack - xor eax, 1 << 21 ; Flip ID bit(21th) from the eax register - push eax - popfd ; Restore flag register into the stack - pushfd - pop eax - push ecx - popfd - cmp eax, ecx ; If values are the same, then CPUID is not available - je .cpuid_panic - ret ; Otherwise return - -.cpuid_panic: - mov al, "C" - jmp error ; Call print routine - - -check_long_mode: - ; Check if CPU supports extended processor info - mov eax, 0x80000000 ; Store magic number - cpuid ; CPUID instruction takes EAX by default - ; CPUID will set EAX a value greater than the magic number - ; if the processor supports extended processor info - cmp eax, 0x80000001 ; Magic number + 1 - jb .long_mode_panic - ; Otherwise we can use extended processor info - ; to check if long mode is available - mov eax, 0x80000001 - cpuid - ; CPUID, with this magic number, will set LM bit(29th) - ; if and only if long mode is available - test edx, 1 << 29 - jz .long_mode_panic - ret - -.long_mode_panic: - mov al, "L" - jmp error ; Call print routine - - -setup_page_tables: - mov eax, page_table_l3 - or eax, 0b11 - mov [page_table_l4], eax - - mov eax, page_table_l2 - or eax, 0b11 - mov [page_table_l3], eax - + call kernel_main ; Call kernel's main function .loop: - mov eax, 0x200000 ; 2MiB - mul ecx - or eax, 0b10000011 - mov [page_table_l2 + ecx * 8], eax - - mov ecx, 0 ; Counter - inc ecx ; Increment counter - cmp ecx, 512 ; Check if whole table is being mapped - jne .loop ; if not, repeat - ret - -enable_paging: - ; Pass page table location to the cpu - mov eax, page_table_l4 - mov cr3, eax - ; Enable PAE - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax; - ; Enable long mode - mov ecx, 0xC0000000 - rdmsr - or eax, 1 << 8 - wrmsr - ; Enable paging - mov eax, cr0 - or eax, 1 << 31 - mov cr0, eax - - ret - -error: ; Prints "ERR: X" where X stands ofr the given error code - ; This routine will just print the error code in video memory - ; Let's understand what those hex codes actually mean: - ; 0xB8000 is the begin of the VGA text buffer, each byte will - ; contain one character. 0x4F is the color code; it means - ; white text on read background. 0x52 is the ASCII code for - ; the letter 'R', while 0x45 stands for the letter 'E', - ; 0x3A stands for the symbol ':' and 0x20 is just a space. - ; Do note that addressing is in little endian ordering and - ; that one space is begin overwritten by the ASCII byte. - ; previous NEW CONTENT - mov dword [0xB8000], 0x4F524F45 ; [] ER - mov dword [0xB8004], 0x4F3A4F52 ; [ER] R: - mov dword [0xB8008], 0x4F204F20 ; [ERR:] - mov byte [0xB800a], al ; Print the error code - hlt ; Halt the CPU + jmp .loop ; If the kernel returns, go into an endless loop + ; This will prevent the CPU to execure any non-kernel + ; instructions. KERNEL_STACK_SZ equ 4096 ; Stack size(4KiB) section .bss -align 4096 -page_table_l4: - resb 4096 -page_table_l3: - resb 4096 -page_table_l2: - resb 4096 +align 4 kernel_stack: - resb KERNEL_STACK_SZ ; Reserver 4KiB for kernel's stack - - -section .rodata -gdt64: - dq 0 ; zero entry -.code_segment: equ $ - gdt64 - dq (1 << 4) | (1 << 44) | (1 << 47) | (1 << 53) ; Code segment - ; executable, descriptor, present 64bit flags -.pointer: - dw $ - gdt64 - 1 - dd gdt64 \ No newline at end of file + resb KERNEL_STACK_SZ ; Reserver 4KiB for kernel's stack \ No newline at end of file diff --git a/kernel/cpu/main64.asm b/kernel/cpu/main64.asm deleted file mode 100644 index c0695a7..0000000 --- a/kernel/cpu/main64.asm +++ /dev/null @@ -1,27 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; vulcanOS Kernel ; -; Developed by Marco 'icebit' Cetica ; -; (c) 2019-2021 ; -; Released under GPLv3 ; -; https://github.com/ice-bit/vulcanos ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -GLOBAL long_mode_start -GLOBAL kernel_loader -EXTERN kernel_main -section .text -[BITS 64] ; Ensure we are in long mode - -long_mode_start: - xor ax, ax - mov ss, ax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Call the kernel's main method - call kernel_main ; Call kernel's main function - .loop: - jmp .loop ; If the kernel returns, go into an endless loop - ; This will prevent the CPU to execure any non-kernel - ; instructions. \ No newline at end of file diff --git a/kernel/drivers/Makefile b/kernel/drivers/Makefile index cc6734f..e731821 100644 --- a/kernel/drivers/Makefile +++ b/kernel/drivers/Makefile @@ -1,11 +1,12 @@ OBJS = tty.o gdt.o idt.o isr.o timer.o keyboard.o \ fs.o cpuid.o -CC = x86_64-elf-gcc # cross-compiler +CC = i686-elf-gcc # cross-compiler CFLAGS = -m32 -fno-stack-protector -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -ffreestanding -Wall -Wextra -Werror -g -c all:${OBJS} %.o: %.c - $(CC) $(CFLAGS) $< -o $@ + @$(CC) $(CFLAGS) $< -o $@ + @echo [CC] Compiling $<... \ No newline at end of file diff --git a/kernel/kernel_main.c b/kernel/kernel_main.c index 4d66dad..597a9dd 100644 --- a/kernel/kernel_main.c +++ b/kernel/kernel_main.c @@ -6,7 +6,7 @@ * https://github.com/ice-bit/vulcanos * *****************************************/ #include "drivers/tty.h" -//#include "drivers/gdt.h" +#include "drivers/gdt.h" #include "drivers/idt.h" #include "drivers/timer.h" #include "drivers/keyboard.h" @@ -41,9 +41,9 @@ void kernel_main(unsigned long magic, uint32_t addr) { printf("Loading kernel, wait please..."); - // gdt_setup(); // Setup Global Descriptor Table - // PRTOK - // printf(" - Loaded GDT"); + gdt_setup(); // Setup Global Descriptor Table + PRTOK + printf(" - Loaded GDT"); idt_setup(); // Setup Interrupt Descriptor Table PRTOK diff --git a/kernel/libc/Makefile b/kernel/libc/Makefile index 5babad3..1747cdb 100644 --- a/kernel/libc/Makefile +++ b/kernel/libc/Makefile @@ -1,11 +1,12 @@ OBJS = stdio.o string.o panic.o time.o VER := $(shell git rev-parse --short HEAD) -CC = x86_64-elf-gcc # cross-compiler -CFLAGS = -DVULCAN_VERSION=$(VER) -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c +CC = i686-elf-gcc # cross-compiler +CFLAGS = -m32 -DVULCAN_VERSION=$(VER) -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c all:${OBJS} %.o: %.c - $(CC) $(CFLAGS) $< -o $@ + @$(CC) $(CFLAGS) $< -o $@ + @echo [CC] Compiling $<... \ No newline at end of file diff --git a/kernel/mem/Makefile b/kernel/mem/Makefile index b24ebf2..8c780c3 100644 --- a/kernel/mem/Makefile +++ b/kernel/mem/Makefile @@ -1,9 +1,10 @@ OBJS = paging.o kheap.o ordered_array.o -CC = x86_64-elf-gcc # cross-compiler +CC = i686-elf-gcc # cross-compiler CFLAGS = -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c all:${OBJS} %.o: %.c - ${CC} ${CFLAGS} $< -o $@ \ No newline at end of file + @${CC} ${CFLAGS} $< -o $@ + @echo [CC] Compiling $<... \ No newline at end of file diff --git a/kernel/userspace/Makefile b/kernel/userspace/Makefile index 7bd0439..820df05 100644 --- a/kernel/userspace/Makefile +++ b/kernel/userspace/Makefile @@ -1,10 +1,11 @@ OBJS = shell.o fetch.o VER := $(shell git rev-parse --short HEAD) -CC = x86_64-elf-gcc # cross-compiler -CFLAGS = -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -DVULCAN_VERSION=$(VER) -m32 -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c +CC = i686-elf-gcc # cross-compiler +CFLAGS = -m32 -DDEFAULT_USER=root -DDEFAULT_HOSTNAME=vulcan -DVULCAN_VERSION=$(VER) -fno-stack-protector -ffreestanding -Wall -Wextra -Werror -g -c all:${OBJS} %.o: %.c - $(CC) $(CFLAGS) $< -o $@ + @$(CC) $(CFLAGS) $< -o $@ + @echo [CC] Compiling $<... \ No newline at end of file diff --git a/kernel/userspace/shell.c b/kernel/userspace/shell.c index f01234f..c591aec 100644 --- a/kernel/userspace/shell.c +++ b/kernel/userspace/shell.c @@ -10,7 +10,6 @@ void helper() { puts("\nList of available commands:\n" "\nhelp - Print this helper" "\nint - Test some interrupts" - "\nbanner - Show banner" "\nclear, cls - Clear the screen" "\nregs - Prints register dump" "\ntimer - Prints timer tick" @@ -27,23 +26,34 @@ void test_interrupts() { } void about() { - printf_color("\n====== IceOS v0.0.1 (c) 2019 Marco 'icebit' Cetica ======\n\n", - LIGHT_CYAN, BLACK); - printf_color( - "iceOS is a x86 monolithic kernel written in C from scratch.\n" - "This project doesn't aim to be a fully functional operating system\n" - "with tons of drivers and graphical applications,\nit's just a learning tool " - "to teach myself concepts like\nOperating Systems, Computer Architecture and Digital Electronics.\n" - "\n\n" - "iceOS comes with the following features:\n" - "- Bare metal booting;\n" - "- VGA driver;\n" - "- Interrupts implementation;\n" - "- PIC & PIT implementation;\n" - "- PS2 driver;\n" - "- Support for x86 architecture;\n" - "- GRUB as bootloader;\n", - LIGHT_GREEN, BLACK); + printf_color("\n \\ /,\n", LIGHT_RED, BLACK); + printf_color(" _________)) ((__________\n", LIGHT_RED, BLACK); + printf_color(" /.-------./\\\\ \\ / //\\.--------.\\", LIGHT_RED, BLACK); + printf_color(" Vulcan", LIGHT_MAGENTA, BLACK); + printf_color("OS ", LIGHT_BROWN, BLACK); + printf_color("is x86 monolithic \n", LIGHT_GREEN, BLACK); + printf_color(" //#######//##\\\\ )) (( //##\\\\########\\\\", LIGHT_RED, BLACK); + printf_color(" kernel written from scratch \n", LIGHT_GREEN, BLACK); + printf_color(" //#######//###(( (( )) ))###\\\\########\\\\", LIGHT_RED, BLACK); + printf_color(" in C following the UNIX \n", LIGHT_GREEN, BLACK); + printf_color("((#######((#####\\\\ \\\\ // //#####))########))", LIGHT_RED, BLACK); + printf_color(" philosophy. \n", LIGHT_GREEN, BLACK); + printf_color(" \\##' `###\\######\\\\ \\)(/ //######/####' `##/", LIGHT_RED, BLACK); + printf_color(" By Marco Cetica 2019-2021 \n", LIGHT_GREEN, BLACK); + printf_color(" )' ``#)' `##\\`->oo<-'/##' `(#'' `(", LIGHT_RED, BLACK); + printf_color(" https://git.io/JtzuAs\n", WHITE, BLACK); + printf_color(" ( ``\\`..'/'' )\n", LIGHT_RED, BLACK); + printf_color(" \\''(\n", LIGHT_RED, BLACK); + printf_color(" `- )\n", LIGHT_RED, BLACK); + printf_color(" / /\n", LIGHT_RED, BLACK); + printf_color(" ( /\\\n", LIGHT_RED, BLACK); + printf_color(" /\\| \\\n", LIGHT_RED, BLACK); + printf_color(" ( \\\n", LIGHT_RED, BLACK); + printf_color(" )\n", LIGHT_RED, BLACK); + printf_color(" /\n", LIGHT_RED, BLACK); + printf_color(" (\n", LIGHT_RED, BLACK); + printf_color(" `\n", LIGHT_RED, BLACK); + } void register_dump() { diff --git a/kernel/userspace/shell.h b/kernel/userspace/shell.h index 4581295..c73f3c3 100644 --- a/kernel/userspace/shell.h +++ b/kernel/userspace/shell.h @@ -1,10 +1,10 @@ -/************************************** - * VulcanOS Kernel * - * Developed by Marco 'icebit' Cetica * - * (c) 2019-2021 * - * Released under GPLv3 * - * https://github.com/ice-bit/iceOS * - ***************************************/ +/***************************************** + * VulcanOS Kernel * + * Developed by Marco 'icebit' Cetica * + * (c) 2019-2021 * + * Released under GPLv3 * + * https://github.com/ice-bit/vulcanos * + *****************************************/ #ifndef _SHELL_H_ #define _SHELL_H_