summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/bootloader/Makefile29
-rw-r--r--examples/bootloader/boot.S84
-rw-r--r--examples/bootloader/kernel.zc28
-rw-r--r--examples/bootloader/linker.ld20
4 files changed, 161 insertions, 0 deletions
diff --git a/examples/bootloader/Makefile b/examples/bootloader/Makefile
new file mode 100644
index 0000000..5ee3da9
--- /dev/null
+++ b/examples/bootloader/Makefile
@@ -0,0 +1,29 @@
+
+CC = gcc
+ZC = ../../zc
+LD = ld
+OBJCOPY = objcopy
+
+CFLAGS = -m32 -ffreestanding -fno-pie -fno-stack-protector -nostdlib -O2 -Wall
+LDFLAGS = -m elf_i386 -T linker.ld
+
+all: boot.bin
+
+boot.bin: boot.o kernel.o
+ $(LD) $(LDFLAGS) -o boot.elf boot.o kernel.o
+ $(OBJCOPY) -O binary boot.elf boot.bin
+ truncate -s 1024 boot.bin
+ @echo "Bootloader built: boot.bin (Size: $$(stat -c %s boot.bin) bytes)"
+
+boot.o: boot.S
+ $(CC) $(CFLAGS) -c boot.S -o boot.o
+
+kernel.o: kernel.c
+ $(CC) $(CFLAGS) -c kernel.c -o kernel.o
+
+kernel.c: kernel.zc
+ $(ZC) transpile --freestanding kernel.zc
+ mv out.c kernel.c
+
+clean:
+ rm -f *.o *.bin *.elf kernel.c
diff --git a/examples/bootloader/boot.S b/examples/bootloader/boot.S
new file mode 100644
index 0000000..4938689
--- /dev/null
+++ b/examples/bootloader/boot.S
@@ -0,0 +1,84 @@
+
+.code16
+.global start
+.extern kmain
+
+start:
+ cli
+ mov $0, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %ss
+ mov $0x7c00, %sp
+
+ # Read sectors from disk
+ mov $0x02, %ah # BIOS read sector function
+ mov $1, %al # Number of sectors to read (Load 1 sector/512 bytes)
+ mov $0, %ch # Cylinder 0
+ mov $0, %dh # Head 0
+ mov $2, %cl # Start from sector 2
+ # dl already contains the boot drive number
+ mov $0, %bx # Segment 0
+ mov %bx, %es
+ mov $0x7e00, %bx # Destination buffer
+ int $0x13 # BIOS interrupt
+ jc disk_error
+
+ # Load GDT
+ lgdt gdt_descriptor
+
+ # Switch to Protected Mode
+ mov %cr0, %eax
+ or $1, %eax
+ mov %eax, %cr0
+
+ # Jump to 32-bit code segment
+ ljmp $0x08, $protected_mode
+
+disk_error:
+ jmp .
+
+.code32
+protected_mode:
+ # Set up 32-bit data segments
+ mov $0x10, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+ mov %ax, %ss
+
+ # Set up stack
+ mov $0x7c00, %esp
+
+ call kmain
+ hlt
+
+gdt_start:
+ .quad 0 # Null descriptor
+
+ # Code Segment (Offset 0x08)
+ .word 0xffff # Limit (low)
+ .word 0x0 # Base (low)
+ .byte 0x0 # Base (middle)
+ .byte 0x9a # Access (exec, read)
+ .byte 0xcf # Granularity
+ .byte 0x0 # Base (high)
+
+ # Data Segment (Offset 0x10)
+ .word 0xffff # Limit (low)
+ .word 0x0 # Base (low)
+ .byte 0x0 # Base (middle)
+ .byte 0x92 # Access (read/write)
+ .byte 0xcf # Granularity
+ .byte 0x0 # Base (high)
+
+gdt_end:
+
+gdt_descriptor:
+ .word gdt_end - gdt_start - 1
+ .long gdt_start
+
+.fill 510-(.-start), 1, 0
+.word 0xaa55
+
diff --git a/examples/bootloader/kernel.zc b/examples/bootloader/kernel.zc
new file mode 100644
index 0000000..d39e91c
--- /dev/null
+++ b/examples/bootloader/kernel.zc
@@ -0,0 +1,28 @@
+
+def VGA_BUFFER = 0xb8000;
+def VGA_WIDTH = 80;
+def VGA_HEIGHT = 25;
+
+@packed
+struct VGAEntry {
+ val: u8;
+ color: u8;
+}
+
+fn kmain() {
+ let vga = (VGAEntry*)VGA_BUFFER;
+
+ let msg = "Hello from Zen C!";
+ let color = 0x0f; // White on Black
+
+ let i = 0;
+ while msg[i] != 0 {
+ vga[i] = VGAEntry {
+ val: msg[i],
+ color: color
+ };
+ i += 1;
+ }
+
+ loop {}
+}
diff --git a/examples/bootloader/linker.ld b/examples/bootloader/linker.ld
new file mode 100644
index 0000000..76ae116
--- /dev/null
+++ b/examples/bootloader/linker.ld
@@ -0,0 +1,20 @@
+
+ENTRY(start)
+
+SECTIONS {
+ . = 0x7c00;
+ .text : {
+ *(.text)
+ *(.rodata*)
+ }
+ .data : {
+ *(.data)
+ }
+ .bss : {
+ *(.bss)
+ }
+ /DISCARD/ : {
+ *(.eh_frame)
+ *(.note*)
+ }
+}