diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..55c20eb --- /dev/null +++ b/Makefile @@ -0,0 +1,60 @@ +# Copyright (C) 2018 Ortega Froysa, Nicolás +# Author: Ortega Froysa, Nicolás +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# General options +TARGET=i686 +ARCH=$(shell echo $(TARGET) | sed s/i.86/x86/) +# Assembly options +AS=i686-elf-as +AFLAGS= +# C options +CC=i686-elf-gcc +CFLAGS?=-O0 -g +CFLAGS:=$(CFLAGS) -std=gnu99 -ffreestanding -Wall -Wextra -Isrc/ +# Linker options +LDFLAGS?=-O0 +LDFLAGS:=$(LDFLAGS) -ffreestanding -nostdlib +LIBS=-lgcc + +# Binary variables +OBJS=src/kernel/arch/$(ARCH)/boot.o src/kernel/kernel.o src/kernel/arch/$(ARCH)/tty.o + +colonel.bin: $(OBJS) + $(CC) -T src/kernel/arch/$(ARCH)/linker.ld -o $@ $(LDFLAGS) $^ $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: %.s + $(AS) $(AFLAGS) $< -o $@ + +.PHONY: all build-iso clean clean-all +all: colonel.bin + +build-iso: colonel.iso + +clean: + rm -f $(OBJS) + rm -rf isodir + +clean-all: clean + rm -f *.iso *.bin + +colonel.iso: colonel.bin + mkdir -p isodir/boot/grub/ + cp configs/grub.cfg isodir/boot/grub/ + cp $< isodir/boot/ + grub-mkrescue -o $@ isodir diff --git a/README b/README index 66f5178..a082d3b 100644 --- a/README +++ b/README @@ -1,17 +1,17 @@ =============== *** Colonel *** =============== -Colonel (pronounced as it is spelt) is a small hobby kernel project -that I'm working on. It currently supports the following architectures: - +This is a small OS project I'm working on. It's slow progress and +probably shouldn't be run anywhere except in an emulator. It currently +supports the following architectures: - x86 # Compiling ----------- -This project uses Clang (https://clang.llvm.org/) and NASM -(http://www.nasm.us/) for building. You will also require GNU Make -(https://www.gnu.org/software/make/), unless you want to manually go -through and compile the files. +You'll want to setup a cross-compilation toolchain with GCC +(https://gcc.gnu.org/) for your target architecture, along with +GNU Make (https://www.gnu.org/software/make/) (I'll switch to the +GNU autotools as soon as I can get them to work properly). To compile a full image you can run `make build-iso`, which will use GNU GRUB (https://www.gnu.org/software/grub/) as the bootloader. Else, diff --git a/src/kernel/arch/x86/boot.s b/src/kernel/arch/x86/boot.s index 46705ac..cbb2926 100644 --- a/src/kernel/arch/x86/boot.s +++ b/src/kernel/arch/x86/boot.s @@ -1,65 +1,139 @@ -; Copyright (C) 2018 Ortega Froysa, Nicolás -; Author: Ortega Froysa, Nicolás -; -; This program is free software: you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation, either version 3 of the License, or -; (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this program. If not, see . +/* + * Copyright (C) 2018 Ortega Froysa, Nicolás + * Author: Ortega Froysa, Nicolás + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ -MBALIGN equ 1<<0 ; align loaded modules on page boundaries -MEMINFO equ 1<<1 ; provide memory map -FLAGS equ MBALIGN | MEMINFO ; multiboot flag field -MAGIC equ 0x1BADB002 ; magic number to help bootloader find the header -CHECKSUM equ -(MAGIC + FLAGS) ; checksum of the above data +# declare constants for the multiboot header +.set ALIGN, 1 << 0 # align loaded modules on page boundaries +.set MEMINFO, 1 << 1 # provide memory map +.set FLAGS, ALIGN | MEMINFO # the multiboot `FLAG' field +.set MAGIC, 0x1BADB002 # 'magic number' letting the boot loader know we're here +.set CHECKSUM , -(MAGIC + FLAGS) # checksum of the above to prove we're multiboot -section .multiboot -align 4 - dd MAGIC - dd FLAGS - dd CHECKSUM +/* + * Declare the multiboot header marking this program as a kernel. The bootloader + * will search for these values in the first 8 KiB of the kernel file aligned at + * 32-bit boundaries (4 bytes). We put the signature in its own section to force + * it within the first 8 KiB of the kernel file. + */ +.section .multiboot +.align 4 +.long MAGIC +.long FLAGS +.long CHECKSUM -section .bss -align 16 +/* + * Create a 16 byte aligned stack with 16 KiB of size. We create labels at the + * bottom and top of the stack. + */ +.section .bss +.align 16 stack_bottom: - resb 16384 ; 16KiB +.skip 16384 # 16 KiB stack_top: -section .data -%include "gdt.s" +/* + * Create the GDT + */ +.section .data +gdt_start: +gdt_null: +.long 0x0 +.long 0x0 -section .text -global _start:function (_start.end - _start) +gdt_kcode: +.word 0xFFFF # limit +.word 0x0 # base +.byte 0x0 # base +.byte 0b10011010 # 1st flags | type flags +.byte 0b11001111 # 2nd flags | limit +.byte 0x0 # base + +gdt_kdata: +.word 0xFFFF # limit +.word 0x0 # base +.byte 0x0 # base +.byte 0b10010010 # 1st flags | type flags +.byte 0b11001111 # 2nd flags | limit +.byte 0x0 # base + +gdt_ucode: +.word 0xFFFF # limit +.word 0x0 # base +.byte 0x0 # base +.byte 0b11111010 # 1st flags | type flags +.byte 0b11001111 # 2nd flags | limit +.byte 0x0 # base + +gdt_udata: +.word 0xFFFF # limit +.word 0x0 # base +.byte 0x0 # base +.byte 0b11110010 # 1st flags | type flags +.byte 0b11001111 # 2nd flags | limit +.byte 0x0 # base + +# TODO: setup the TSS +gdt_tss: +.word 0x0 # size of TSS (set later) +.word 0x0 # address of TSS (set later) +.byte 0x0 # address of TSS (set later) +.byte 0b10010001 # 1st flags | type flags +.byte 0b01000000 # 2nd flags | size of TSS (set later +.byte 0x0 # address of TSS (set later) + +gdt_end: + +gdtr: +.word (gdt_end - gdt_start - 1) +.long gdt_start + +/* + * The linker script specifies the `_start' label as the entry point to the kernel + * and the bootloader will jump to this position. That is, this is where the kernel + * starts. + */ +.section .text +.global _start +.type _start, @function _start: - ; setup the stack - mov esp, stack_top + # set the position of `%esp' to the top of the stack + mov $stack_top, %esp - ; TODO: setup GDT, IDT, paging, etc. here + # GDT, paging, and other features +flush_gdt: cli - lgdt [gdtr] - jmp 0x08:.reload_segs -.reload_segs: - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax + lgdt (gdtr) + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + ljmp $0x08, $flush_end +flush_end: - ; call the kernel - extern kernel_main +boot_kernel: + # enter high-level kernel (C) call kernel_main - ; hang - cli -.hang: - hlt - jmp .hang -.end: + # put computer into infinite loop + cli # disable interrupts by clearing the interrupt flag in `eflags' +end_loop: + hlt # wait for next interrupt + jmp end_loop # jump to the `hlt' instruction if it ever leaves it + +.size _start, . - _start diff --git a/src/kernel/arch/x86/gdt.s b/src/kernel/arch/x86/gdt.s deleted file mode 100644 index c420b90..0000000 --- a/src/kernel/arch/x86/gdt.s +++ /dev/null @@ -1,68 +0,0 @@ -; Copyright (C) 2018 Ortega Froysa, Nicolás -; Author: Ortega Froysa, Nicolás -; -; This program is free software: you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation, either version 3 of the License, or -; (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this program. If not, see . - -gdt_start: - -gdt_null: - dd 0x0 - dd 0x0 - -gdt_kcode: - dw 0xFFFF ; limit (bits 0-15) - dw 0x0 ; base (bits 0-15) - - db 0x0 ; base (bits 16-23) - db 10011010b ; 1st flags | type flags - db 11001111b ; 2nd flags | limit (bits 16-19) - db 0x0 ; base (bits 24-31) - -gdt_kdata: - dw 0xFFFF - dw 0x0 - - db 0x0 - db 10010010b - db 11001111b - db 0x0 - -gdt_ucode: - dw 0xFFFF - dw 0x0 - - db 0x0 - db 11111010b - db 11001111b - db 0x0 - -gdt_udata: - dw 0xFFFF - dw 0x0 - - db 0x0 - db 11110010b - db 11001111b - db 0x0 - -; TODO: fill this in later -gdt_tss: - dd 0x0 - dd 0x0 - -gdt_end: - -gdtr: - dw gdt_end - gdt_start - 1 - dd gdt_start diff --git a/src/kernel/arch/x86/tss.h b/src/kernel/arch/x86/tss.h index ab65b58..c3e8d45 100644 --- a/src/kernel/arch/x86/tss.h +++ b/src/kernel/arch/x86/tss.h @@ -18,7 +18,7 @@ #pragma once -struct tss { +volatile struct tss { uint16_t link; uint16_t link_r; // reserved