From f2899b62b997aafc25666f21ea3a754030a8de71 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Mon, 28 Sep 2026 21:08:07 -0700 Subject: Upload from https://github.com/TheHuddle/pr-practice/pull/10/changes --- .gitignore | 5 +++++ Makefile | 30 ++++++++++++++++++++++++++++++ boot.asm | 29 +++++++++++++++++++++++++++++ kernel.c | 36 ++++++++++++++++++++++++++++++++++++ linker.ld | 43 +++++++++++++++++++++++++++++++++++++++++++ readme.org | 15 +++++++++++++++ 6 files changed, 158 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 boot.asm create mode 100644 kernel.c create mode 100644 linker.ld create mode 100644 readme.org diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5acb32e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +iso/* +*.o +*.bin +*.iso + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c06ff32 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +.DEFAULT_GOAL := os.iso +.PHONY: demo + +OBJECTS=entry.o kernel.o +KERNEL_BUILD_FLAGS=-std=c99 -ffreestanding -O0 -Wall -Wextra +OS_BUILD_FLAGS=-ffreestanding -O2 -nostdlib -lgcc + +entry.o: boot.asm + nasm -felf32 boot.asm -o entry.o + +kernel.o: kernel.c + i386-elf-gcc -c kernel.c -o kernel.o $(KERNEL_BUILD_FLAGS) + +os.bin: kernel.o entry.o + i386-elf-gcc -T linker.ld -o os.bin $(OS_BUILD_FLAGS) $(OBJECTS) + +os.iso: os.bin + mkdir -p iso/boot/grub + cp os.bin iso/boot/os.bin + printf "menuentry 'HelloOS' {\n multiboot /boot/os.bin\n set gfxpayload=text\n}" > iso/boot/grub/grub.cfg + grub-mkrescue -o os.iso iso + +demo: + qemu-system-i386 demo/os.iso + +run: os.iso + qemu-system-i386 os.iso + +clean: + rm -rf iso os.iso *.o *.bin diff --git a/boot.asm b/boot.asm new file mode 100644 index 0000000..1627135 --- /dev/null +++ b/boot.asm @@ -0,0 +1,29 @@ +MBALIGN equ 1 << 0 +MEMINFO equ 1 << 1 +FLAGS equ MBALIGN | MEMINFO +MAGIC equ 0x1BADB002 +CHECKSUM equ -(MAGIC + FLAGS) + +section .multiboot +align 4 + dd MAGIC + dd FLAGS + dd CHECKSUM + +section .bss +align 16 +stack_bottom: +resb 16384 +stack_top: + +section .text +global _start:function (_start.end - _start) +_start: + mov esp, stack_top + extern kernel + call kernel + cli + +jmp $ + +.end: diff --git a/kernel.c b/kernel.c new file mode 100644 index 0000000..190d36e --- /dev/null +++ b/kernel.c @@ -0,0 +1,36 @@ +#include +#include + +#define WIDTH 80 +#define HEIGHT 25 + +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define RED 4 +#define MAGENTA 13 +#define WHITE 15 + +int strlen(char* s) { + int n = 0; + char* s_ptr = s; + while (*(s_ptr++)) { + n++; + } + return n; +} + +void kernel(void) { + uint16_t* vgamem = (uint16_t*) 0xB8000; + uint16_t vgacolors[6] = {WHITE | RED << 4, WHITE | GREEN << 4, WHITE | BLUE << 4, BLACK | RED << 4, BLACK | GREEN << 4, BLACK | BLUE << 4}; + char* s = "Hello world!"; + int i,j,k; + for (k = 0; k >= 0; ++k) { + k = (k % 5); + j = 0; + while (j < 100000000) { j++; } // Since we don't have an interrupt descriptor table we can't use the PIC; this emulates "sleeping" + for (i = 0; i < WIDTH*HEIGHT; i++) { + vgamem[i] = s[i % strlen(s)] | vgacolors[(i+k) % 6] << 8; + } + } +} diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..38ddd94 --- /dev/null +++ b/linker.ld @@ -0,0 +1,43 @@ +/* The bootloader will look at this image and start execution at the symbol + designated as the entry point. */ +ENTRY(_start) + +/* Tell where the various sections of the object files will be put in the final + kernel image. */ +SECTIONS +{ + /* Begin putting sections at 1 MiB, a conventional place for kernels to be + loaded at by the bootloader. */ + . = 1M; + + /* First put the multiboot header, as it is required to be put very early + early in the image or the bootloader won't recognize the file format. + Next we'll put the .text section. */ + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } + + /* Read-only data. */ + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + /* Read-write data (initialized) */ + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + /* Read-write data (uninitialized) and stack */ + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } + + /* The compiler may produce other sections, by default it will put them in + a segment with the same name. Simply add stuff here as needed. */ +} diff --git a/readme.org b/readme.org new file mode 100644 index 0000000..161a39f --- /dev/null +++ b/readme.org @@ -0,0 +1,15 @@ +* HelloOS +This is a simple 32 bit protected mode operating system that runs in VGA mode. It outputs "Hello world" with some cool christmas lights. + +#+ATTR_HTML: :style margin-left: auto; margin-right: auto; +[[https://s10.gifyu.com/images/demo45e010936937dd16.gif]] + +** Building +In order to build this program you must have the ~i386~ GCC cross-compiled on your system. Instructions can be found on the [[https://wiki.osdev.org/GCC_Cross-Compiler][OSDev Wiki]]. You will also need ~grub~ and ~nasm~. + +Then, a simple ~make~ will generate the iso. You can run the iso by ~dd~'ing it to a usb stick or by running it with ~qemu-system-i386~. If you are running on native hardware make sure to boot it with BIOS (some PC's call it Legacy Support). + +** Using pre-compiled image +This project contains a pre-compiled iso file in ~demo~. Simply ~cd demo~ and ~qemu-system-i386 os.iso~ or run ~make demo~. + + -- cgit v1.3