diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 63819cf..f92e4c6 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -9,20 +9,24 @@ on: jobs: build: - runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Build the Docker image - run: docker build buildenv -t bill-buildenv + - name: Docker env + run: docker build . -t bill-buildenv + + - name: List files and permissions + run: | + ls -l + chmod +x build.sh - - name: Build + - name: Build iso run: | - docker run --rm -v "$(pwd):/root/env" bill-buildenv make build-x86_64 - + docker run --rm -v "$(pwd):/root/env" bill-buildenv /bin/bash -c "./build.sh" + - name: Upload artifacts uses: actions/upload-artifact@v3 with: - name: "BILL-nightly" - path: "dist/" + name: "BILL-barebones" + path: "." diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..52c8b48 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM billywonthappen/gcc-cross-x86_64-elf:latest + +RUN apt-get update +RUN apt-get upgrade -y +RUN apt-get install -y nasm +RUN apt-get install -y git sudo +RUN apt-get install -y xorriso build-essential + +VOLUME /root/env +WORKDIR /root/env +RUN echo "hii" +RUN echo "$PWD" + +CMD ["/bin/bash"] diff --git a/Makefile b/Makefile deleted file mode 100644 index 8b7029c..0000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -kernel_source_files := $(shell find src/impl/kernel -name *.c) -kernel_object_files := $(patsubst src/impl/kernel/%.c, build/kernel/%.o, $(kernel_source_files)) - -x86_64_c_source_files := $(shell find src/impl/x86_64 -name *.c) -x86_64_c_object_files := $(patsubst src/impl/x86_64/%.c, build/x86_64/%.o, $(x86_64_c_source_files)) - -x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm) -x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files)) - -x86_64_object_files := $(x86_64_c_object_files) $(x86_64_asm_object_files) - -$(kernel_object_files): build/kernel/%.o : src/impl/kernel/%.c - mkdir -p $(dir $@) && \ - x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/kernel/%.o, src/impl/kernel/%.c, $@) -o $@ - - -$(x86_64_c_object_files): build/x86_64/%.o : src/impl/x86_64/%.c - mkdir -p $(dir $@) && \ - x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/x86_64/%.o, src/impl/x86_64/%.c, $@) -o $@ - -$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm - mkdir -p $(dir $@) && \ - nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $@) -o $@ - -.PHONY: build-x86_64 -build-x86_64: $(kernel_object_files) $(x86_64_object_files) - mkdir -p dist/x86_64 && \ - x86_64-elf-ld -n -o dist/x86_64/kernel.bin -T targets/x86_64/linker.ld $(kernel_object_files) $(x86_64_object_files) && \ - cp dist/x86_64/kernel.bin targets/x86_64/iso/boot/kernel.bin && \ - grub-mkrescue /usr/lib/grub/i386-pc -o dist/x86_64/kernel.iso targets/x86_64/iso diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..cf91e2f --- /dev/null +++ b/build.sh @@ -0,0 +1,25 @@ +pwd +cd kernel +pwd + +make + +cd .. +pwd + +git clone https://github.com/limine-bootloader/limine.git --branch=v5.x-branch-binary --depth=1 +make -C limine + +mkdir -p iso_root +cp -v kernel/bill.elf limine.cfg limine/limine-bios.sys \ + limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/ +mkdir -p iso_root/EFI/BOOT +cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ +cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/ + +xorriso -as mkisofs -b limine-bios-cd.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + --efi-boot limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o image.iso +./limine/limine bios-install image.iso diff --git a/buildenv/Dockerfile b/buildenv/Dockerfile deleted file mode 100644 index 589ad5e..0000000 --- a/buildenv/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM billywonthappen/gcc-cross-x86_64-elf:latest - -RUN apt-get update -RUN apt-get upgrade -y -RUN apt-get install -y nasm -RUN apt-get install -y grub-pc-bin -RUN apt-get install -y grub-common -RUN apt-get install -y xorriso - -VOLUME /root/env -WORKDIR /root/env \ No newline at end of file diff --git a/kernel/kernel.c b/kernel/kernel.c new file mode 100644 index 0000000..d72337f --- /dev/null +++ b/kernel/kernel.c @@ -0,0 +1,87 @@ +#include +#include +#include + +static volatile struct limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST, + .revision = 0 +}; + +void *memcpy(void *dest, const void *src, size_t n) { + uint8_t *pdest = (uint8_t *)dest; + const uint8_t *psrc = (const uint8_t *)src; + + for (size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + + return dest; +} + +void *memset(void *s, int c, size_t n) { + uint8_t *p = (uint8_t *)s; + + for (size_t i = 0; i < n; i++) { + p[i] = (uint8_t)c; + } + + return s; +} + +void *memmove(void *dest, const void *src, size_t n) { + uint8_t *pdest = (uint8_t *)dest; + const uint8_t *psrc = (const uint8_t *)src; + + if (src > dest) { + for (size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + } else if (src < dest) { + for (size_t i = n; i > 0; i--) { + pdest[i-1] = psrc[i-1]; + } + } + + return dest; +} + +int memcmp(const void *s1, const void *s2, size_t n) { + const uint8_t *p1 = (const uint8_t *)s1; + const uint8_t *p2 = (const uint8_t *)s2; + + for (size_t i = 0; i < n; i++) { + if (p1[i] != p2[i]) { + return p1[i] < p2[i] ? -1 : 1; + } + } + + return 0; +} + +// Halt and catch fire function. +static void hcf(void) { + asm ("cli"); + for (;;) { + asm ("hlt"); + } +} + +void _start(void) { + // Ensure we got a framebuffer. + if (framebuffer_request.response == NULL + || framebuffer_request.response->framebuffer_count < 1) { + hcf(); + } + + // Fetch the first framebuffer. + struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; + + // Note: we assume the framebuffer model is RGB with 32-bit pixels. + for (size_t i = 0; i < 100; i++) { + uint32_t *fb_ptr = framebuffer->address; + fb_ptr[i * (framebuffer->pitch / 4) + i] = 0xffffff; + } + + // We're done, just hang... + hcf(); +} diff --git a/kernel/linker.ld b/kernel/linker.ld new file mode 100644 index 0000000..9c91dfa --- /dev/null +++ b/kernel/linker.ld @@ -0,0 +1,46 @@ +OUTPUT_FORMAT(elf64-x86-64) + +ENTRY(_start) + +PHDRS +{ + text PT_LOAD FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */ + rodata PT_LOAD FLAGS((1 << 2)) ; /* Read only */ + data PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */ + dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)) ; /* Dynamic PHDR for relocations */ +} + +SECTIONS +{ + . = 0xffffffff80000000; + + .text : { + *(.text .text.*) + } :text + + . += CONSTANT(MAXPAGESIZE); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + . += CONSTANT(MAXPAGESIZE); + + .data : { + *(.data .data.*) + } :data + + .dynamic : { + *(.dynamic) + } :data :dynamic + + .bss : { + *(.bss .bss.*) + *(COMMON) + } :data + + /DISCARD/ : { + *(.eh_frame) + *(.note .note.*) + } +} diff --git a/kernel/makefile b/kernel/makefile new file mode 100644 index 0000000..e006f09 --- /dev/null +++ b/kernel/makefile @@ -0,0 +1,100 @@ +override MAKEFLAGS += -rR +override KERNEL := bill.elf + +define DEFAULT_VAR = + ifeq ($(origin $1),default) + override $(1) := $(2) + endif + ifeq ($(origin $1),undefined) + override $(1) := $(2) + endif +endef +override DEFAULT_CC := x86_64-elf-gcc +$(eval $(call DEFAULT_VAR,CC,$(DEFAULT_CC))) + +override DEFAULT_LD := x86_64-elf-ld +$(eval $(call DEFAULT_VAR,LD,$(DEFAULT_LD))) + +override DEFAULT_CFLAGS := -g -O2 -pipe +$(eval $(call DEFAULT_VAR,CFLAGS,$(DEFAULT_CFLAGS))) + +override DEFAULT_CPPFLAGS := +$(eval $(call DEFAULT_VAR,CPPFLAGS,$(DEFAULT_CPPFLAGS))) + +override DEFAULT_NASMFLAGS := -F dwarf -g +$(eval $(call DEFAULT_VAR,NASMFLAGS,$(DEFAULT_NASMFLAGS))) + +override DEFAULT_LDFLAGS := +$(eval $(call DEFAULT_VAR,LDFLAGS,$(DEFAULT_LDFLAGS))) + +override CFLAGS += \ + -Wall \ + -Wextra \ + -std=gnu11 \ + -ffreestanding \ + -fno-stack-protector \ + -fno-stack-check \ + -fno-lto \ + -fPIE \ + -m64 \ + -march=x86-64 \ + -mabi=sysv \ + -mno-80387 \ + -mno-mmx \ + -mno-sse \ + -mno-sse2 \ + -mno-red-zone + +override CPPFLAGS := \ + -I. \ + $(CPPFLAGS) \ + -MMD \ + -MP + +override LDFLAGS += \ + -m elf_x86_64 \ + -nostdlib \ + -static \ + -pie \ + --no-dynamic-linker \ + -z text \ + -z max-page-size=0x1000 \ + -T linker.ld + +override NASMFLAGS += \ + -Wall \ + -f elf64 + +override CFILES := $(shell find -L . -type f -name '*.c') +override ASFILES := $(shell find -L . -type f -name '*.S') +override NASMFILES := $(shell find -L . -type f -name '*.asm') +override OBJ := $(CFILES:.c=.c.o) $(ASFILES:.S=.S.o) $(NASMFILES:.asm=.asm.o) +override HEADER_DEPS := $(CFILES:.c=.c.d) $(ASFILES:.S=.S.d) + +.PHONY: all +all: $(KERNEL) + +limine.h: + curl -Lo $@ https://github.com/limine-bootloader/limine/raw/trunk/limine.h + +$(KERNEL): $(OBJ) + $(LD) $(OBJ) $(LDFLAGS) -o $@ + +-include $(HEADER_DEPS) + +%.c.o: %.c limine.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +%.S.o: %.S limine.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +%.asm.o: %.asm + nasm $(NASMFLAGS) $< -o $@ + +.PHONY: clean +clean: + rm -rf $(KERNEL) $(OBJ) $(HEADER_DEPS) + +.PHONY: distclean +distclean: clean + rm -f limine.h \ No newline at end of file diff --git a/limine.cfg b/limine.cfg new file mode 100644 index 0000000..f9f3061 --- /dev/null +++ b/limine.cfg @@ -0,0 +1,12 @@ +TIMEOUT=5 + + +:BILLOS (KASLR on) + PROTOCOL=limine + KERNEL_PATH=boot:///bill.elf + +:BILLOS (KASLR off) + PROTOCOL=limine + KASLR=no + KERNEL_PATH=boot:///bill.elf + diff --git a/src/impl/kernel/main.c b/src/impl/kernel/main.c deleted file mode 100644 index 405b573..0000000 --- a/src/impl/kernel/main.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "print.h" -#include - -void kernel_main(){ - print_clear(); - print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK); - print_str("Hello, world!"); - panic(); -} diff --git a/src/impl/kernel/panic.c b/src/impl/kernel/panic.c deleted file mode 100644 index f16fbef..0000000 --- a/src/impl/kernel/panic.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - - -void panic(){ - print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); - print_clear(); - print_str("\nPlease restart your machine"); -} diff --git a/src/impl/x86_64/boot/header.asm b/src/impl/x86_64/boot/header.asm deleted file mode 100644 index a6046fd..0000000 --- a/src/impl/x86_64/boot/header.asm +++ /dev/null @@ -1,16 +0,0 @@ -section .multiboot_header -header_start: - ; magic number - dd 0xe85250d6 ; multiboot2 - ; architecture - dd 0 ; protected mode i386 - ; header length - dd header_end - header_start - ; checksum - dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) - - ; end tag - dw 0 - dw 0 - dd 8 -header_end: diff --git a/src/impl/x86_64/boot/main.asm b/src/impl/x86_64/boot/main.asm deleted file mode 100644 index 56ddbd8..0000000 --- a/src/impl/x86_64/boot/main.asm +++ /dev/null @@ -1,138 +0,0 @@ -global start -extern long_mode_start - -section .text -bits 32 -start: - mov esp, stack_top - - call check_multiboot - call check_cpuid - call check_long_mode - - call setup_page_tables - call enable_paging - - lgdt [gdt64.pointer] - jmp gdt64.code_segment:long_mode_start - - hlt - -check_multiboot: - cmp eax, 0x36d76289 - jne .no_multiboot - ret -.no_multiboot: - mov al, "M" - jmp error - -check_cpuid: - pushfd - pop eax - mov ecx, eax - xor eax, 1 << 21 - push eax - popfd - pushfd - pop eax - push ecx - popfd - cmp eax, ecx - je .no_cpuid - ret -.no_cpuid: - mov al, "C" - jmp error - -check_long_mode: - mov eax, 0x80000000 - cpuid - cmp eax, 0x80000001 - jb .no_long_mode - - mov eax, 0x80000001 - cpuid - test edx, 1 << 29 - jz .no_long_mode - - ret -.no_long_mode: - mov al, "L" - jmp error - -setup_page_tables: - mov eax, page_table_l3 - or eax, 0b11 ; present, writable - mov [page_table_l4], eax - - mov eax, page_table_l2 - or eax, 0b11 ; present, writable - mov [page_table_l3], eax - - mov ecx, 0 ; counter -.loop: - - mov eax, 0x200000 ; 2MiB - mul ecx - or eax, 0b10000011 ; present, writable, huge page - mov [page_table_l2 + ecx * 8], eax - - - inc ecx ; increment counter - cmp ecx, 512 ; checks if the whole table is mapped - jne .loop ; if not, continue - - ret - -enable_paging: - ; pass page table location to 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, 0xC0000080 - rdmsr - or eax, 1 << 8 - wrmsr - - ; enable paging - mov eax, cr0 - or eax, 1 << 31 - mov cr0, eax - - ret - -error: - ; print "ERR: X" where X is the error code - mov dword [0xb8000], 0x4f524f45 - mov dword [0xb8004], 0x4f3a4f52 - mov dword [0xb8008], 0x4f204f20 - mov byte [0xb800a], al - hlt - -section .bss -align 4096 -page_table_l4: - resb 4096 -page_table_l3: - resb 4096 -page_table_l2: - resb 4096 -stack_bottom: - resb 4096 * 4 -stack_top: - -section .rodata -gdt64: - dq 0 ; zero entry -.code_segment: equ $ - gdt64 - dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment -.pointer: - dw $ - gdt64 - 1 ; length - dq gdt64 ; address - diff --git a/src/impl/x86_64/boot/main64.asm b/src/impl/x86_64/boot/main64.asm deleted file mode 100644 index f3ad7cc..0000000 --- a/src/impl/x86_64/boot/main64.asm +++ /dev/null @@ -1,16 +0,0 @@ -global long_mode_start -extern kernel_main - -section .text -bits 64 -long_mode_start: - ; load null into all data segment registers - mov ax, 0 - mov ss, ax - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - call kernel_main - hlt diff --git a/src/impl/x86_64/print.c b/src/impl/x86_64/print.c deleted file mode 100644 index 4935bf2..0000000 --- a/src/impl/x86_64/print.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "print.h" - -const static size_t NUM_COLS = 80; -const static size_t NUM_ROWS = 25; - -struct Char { - uint8_t character; - uint8_t color; -}; - -struct Char* buffer = (struct Char*) 0xb8000; -size_t col = 0; -size_t row = 0; -uint8_t color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4; - -void clear_row(size_t row) { - struct Char empty = (struct Char) { - character: ' ', - color: color, - }; - - for (size_t col = 0; col < NUM_COLS; col++) - { - buffer[col + NUM_COLS * row] = empty; - } -} - -void print_clear() { - for (size_t i = 0; i < NUM_ROWS; i++) { - clear_row(i); - } -} - -void print_newline() { - col = 0; - - if (row == NUM_ROWS - 1) { - row++; - return; - } - - for (size_t row = 1; row < NUM_ROWS; row++) { - for (size_t col = 0; col < NUM_COLS; col++) { - struct Char character = buffer[col + NUM_COLS * row]; - buffer[col + NUM_COLS * (row - 1)] = character; - } - } - - clear_row(NUM_ROWS - 1); -} - -void print_char(char character) { - if (character == '\n') { - print_newline(); - return; - } - - if (col > NUM_COLS) { - print_newline(); - } - - buffer[col + NUM_COLS * row] = (struct Char) { - character: (uint8_t) character, - color: color, - }; - - col++; -} - -void print_str(char* str) { - for (size_t i = 0; 1; i++) { - char character = (uint8_t) str[i]; - - if (character == '\0') { - return; - } - - print_char(character); - } -} - -void print_set_color(uint8_t foreground, uint8_t background) { - color = foreground + (background << 4); -} \ No newline at end of file diff --git a/src/intf/panic.h b/src/intf/panic.h deleted file mode 100644 index 40de982..0000000 --- a/src/intf/panic.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include -#include - -void panic(); diff --git a/src/intf/print.h b/src/intf/print.h deleted file mode 100644 index b44b182..0000000 --- a/src/intf/print.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -enum { - PRINT_COLOR_BLACK = 0, - PRINT_COLOR_BLUE = 1, - PRINT_COLOR_GREEN = 2, - PRINT_COLOR_CYAN = 3, - PRINT_COLOR_RED = 4, - PRINT_COLOR_MAGENTA = 5, - PRINT_COLOR_BROWN = 6, - PRINT_COLOR_LIGHT_GREY = 7, - PRINT_COLOR_DARK_GREY = 8, - PRINT_COLOR_LIGHT_BLUE = 9, - PRINT_COLOR_LIGHT_GREEN = 10, - PRINT_COLOR_LIGHT_CYAN = 11, - PRINT_COLOR_LIGHT_RED = 12, - PRINT_COLOR_PINK = 13, - PRINT_COLOR_YELLOW = 14, - PRINT_COLOR_WHITE = 15, -}; - -void print_clear(); -void print_char(char character); -void print_str(char* string); -void print_set_color(uint8_t foreground, uint8_t background); \ No newline at end of file diff --git a/targets/x86_64/iso/boot/grub/grub.cfg b/targets/x86_64/iso/boot/grub/grub.cfg deleted file mode 100644 index 3b7a0c4..0000000 --- a/targets/x86_64/iso/boot/grub/grub.cfg +++ /dev/null @@ -1,7 +0,0 @@ -set timeout=0 -set default=0 - -menuentry "bill" { - multiboot2 /boot/kernel.bin - boot -} \ No newline at end of file diff --git a/targets/x86_64/linker.ld b/targets/x86_64/linker.ld deleted file mode 100644 index 5d60e11..0000000 --- a/targets/x86_64/linker.ld +++ /dev/null @@ -1,16 +0,0 @@ -ENTRY(start) - -SECTIONS -{ - . = 1M; - - .boot : - { - KEEP(*(.multiboot_header)) - } - - .text : - { - *(.text) - } -} \ No newline at end of file