sos

[unmaintained] experimenting with low level OS development
Log | Files | Refs | README | LICENSE

commit 70a0e7557c5fdcda0d9047a42a7a034b95d77cf1
parent 4e464a4dab52b685b9b90bd12507eb85209e00bc
Author: Stefan <misc@stefan-koch.name>
Date:   Sun, 18 Oct 2015 18:45:46 +0200

switch to GRUB and start C kernel with multiboot

Diffstat:
MMakefile | 39+++++++++++++++++++++++++++++++--------
Da20.asm | 132-------------------------------------------------------------------------------
Mbochsrc | 4++--
Mboot.asm | 50++++++++++++++++++++++----------------------------
Agrub/grub.cfg | 7+++++++
Dkernel.asm | 58----------------------------------------------------------
Akernel.c | 18++++++++++++++++++
Akernel.ld | 38++++++++++++++++++++++++++++++++++++++
Asos.img.layout | 6++++++
9 files changed, 124 insertions(+), 228 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,15 +1,38 @@ ASM = nasm ASMFLAGS = +GCC = $(HOME)/opt/cross/bin/i586-elf-gcc +GCCFLAGS = -std=gnu99 -ffreestanding -O2 -Wall -Wextra -all: $(ASM_FILES) - $(ASM) $(ASMFLAGS) boot.asm -o boot.bin - $(ASM) $(ASMFLAGS) kernel.asm -o kernel.bin +all: image kernel kernel-install + +kernel: + $(ASM) boot.asm -o boot.o -f elf + $(GCC) -c kernel.c -o kernel.o $(GCCFLAGS) + $(GCC) -T kernel.ld -o sos-kernel.img -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc + +kernel-install: + sudo losetup /dev/loop1 sos.img -o 1048576 + sudo mount /dev/loop1 /mnt + sudo cp sos-kernel.img /mnt/boot/ + sudo umount /mnt + sudo losetup -d /dev/loop1 + +image: + dd if=/dev/zero of=sos.img bs=512 count=131072 + sfdisk sos.img < sos.img.layout - dd if=/dev/zero of=sos.img bs=1k count=1440 - cat boot.bin kernel.bin > /tmp/sos.bin - dd status=noxfer conv=notrunc if=/tmp/sos.bin of=sos.img + sudo losetup /dev/loop0 sos.img + sudo losetup /dev/loop1 sos.img -o 1048576 + sudo mke2fs /dev/loop1 + sudo mount /dev/loop1 /mnt + sudo grub-install --root-directory=/mnt --no-floppy --modules="normal ext2 part_msdos multiboot" /dev/loop0 + sudo cp sos-kernel.img /mnt/boot/ + sudo cp grub/* /mnt/boot/grub/ + sudo losetup -d /dev/loop0 + sudo umount /mnt + sudo losetup -d /dev/loop1 clean: - rm boot.bin - rm kernel.bin + rm *.o + rm sos-kernel.img rm sos.img diff --git a/a20.asm b/a20.asm @@ -1,132 +0,0 @@ -a20_enable: - call a20_stop_if_active - -a20_bios: - mov ax, 2401h - int 15h - - call a20_stop_if_active - -a20_keyboard: - call a20_wait_inbuf ; disable the keyboard - mov al, 0adh - out 64h, al - - call a20_wait_inbuf ; tell the controller we want to read data - mov al, 0d0h - out 64h, al - - call a20_wait_outbuf ; read the P2 port provided by the controller - in al, 60h - push ax - - call a20_wait_inbuf ; tell the controller we want to write data - mov al, 0d1h - out 64h, al - - call a20_wait_inbuf ; write the new P2 port with A20 line active - pop ax - or al, 2 - out 60h, al - - call a20_wait_inbuf ; re-enable the keyboard - mov al, 0aeh - out 64h, al - - call a20_wait_inbuf - - call a20_stop_if_active_loop - -a20_fast: - in al, 92h - test al, 2 - jnz a20_done ; A20 Fast Gate is already activated - or al, 2 - and al, 0feh - out 92h, al - - call a20_stop_if_active_loop - - jmp a20_done ; give up, no other methods there - ; could jump to another location and display an error - -a20_wait_inbuf: - in al, 64h - test al, 2 - jnz a20_wait_inbuf - ret - -a20_wait_outbuf: - in al, 64h, - test al, 1 - jz a20_wait_outbuf - ret - -a20_active: - pushf - push ds - push es - push di - push si - - xor ax, ax ; ax = 0 - mov es, ax - - not ax; ax = 0xffff - mov ds, ax - - mov di, 0500h - mov si, 0510h - - mov al, byte [es:di] ; save the old values from memory - push ax - - mov al, byte [ds:si] - push ax - - mov byte [es:di], 00h ; write 0x00 to one and 0xff to the other location - mov byte [ds:si], 0ffh - - cmp byte [es:di], 0ffh ; check if the address we set to 0x00 was - ; set to 0xff later, then we have only 20 bit - ; addresses - - pop ax ; restore the bytes we set before - mov byte [ds:si], al - - pop ax - mov byte [es:di], al - - mov ax, 0 - je a20_active_end - mov ax, 1 - -a20_active_end: - pop si - pop di - pop es - pop ds - popf - ret - -a20_stop_if_active: - call a20_active - test ax, ax ; check if all bits are 0, then ZF = 1 - jnz a20_done - ret - -a20_stop_if_active_loop: ; try in a loop if a20 is active for k times - mov bx, 0ffh -a20_stop_if_active_loop_iterator: - dec bx - call a20_stop_if_active - test ax, ax - jnz a20_done - - test bx, bx ; check if bx 0 - jnz a20_stop_if_active_loop_iterator - - ret - - -a20_done: diff --git a/bochsrc b/bochsrc @@ -1,6 +1,6 @@ romimage: file="$HOME/opt/bochs/share/bochs/BIOS-bochs-latest" vgaromimage: file="$HOME/opt/bochs/share/bochs/VGABIOS-elpin-2.40" -boot: floppy -floppya: 1_44="sos.img", status=inserted +boot: disk +ata0-master: type=disk, path="sos.img", mode=flat cpu: count=1, ips=4000000, reset_on_triple_fault=0 magic_break: enabled=1 diff --git a/boot.asm b/boot.asm @@ -1,28 +1,22 @@ -[BITS 16] -[ORG 0x7C00] - -xor ax, ax ; set ax to 0 = first segment -mov ss, ax -mov ds, ax -mov es, ax - -disk_reset: - xor ah, ah ; ah=0, reset drive head - int 13h - jc disk_reset - -disk_read: - mov ah, 0x02 ; with interrupt 3h: reading! - mov al, 10 ; read 10 sectors - mov cl, 2 ; from sector 2 - mov bx, 0x8000 ; save data to location 0x8000 - - mov ch, 0 - mov dh, 0 - int 13h - jc disk_read - - jmp 0x0000:0x8000 ; jump to the new program, hooray - -times 510-($-$$) db 0 -dw 0xaa55 +section .multiboot +align 4 + dd 1BADB002h + dd 0003h ; set align boot modules to page boundaries, supply memory map + dd -(1BADB002h + 0003h) + +section .bootstrap_stack +stack_bottom: + resb 16384 ; 16 KiB +stack_top: + +section .text +extern kernel_main +global _start +_start: + mov esp, stack_top + call kernel_main + + cli + hlt +.lhang: + jmp .lhang diff --git a/grub/grub.cfg b/grub/grub.cfg @@ -0,0 +1,7 @@ +set timeout=15 +set default=0 + +menuentry "SOS" { + multiboot /boot/sos-kernel.img + boot +} diff --git a/kernel.asm b/kernel.asm @@ -1,58 +0,0 @@ -[BITS 16] -[ORG 0x8000] - -xor ax, ax ; set ax to 0 = first segment -mov ss, ax -mov ds, ax -mov es, ax - -cli - -%include "a20.asm" - -enter_pmode: - lgdt [gdtr] - mov eax, cr0 - or eax, 1 - mov cr0, eax - - jmp 08h:far_jump - -[BITS 32] -far_jump: - mov ax, 10h - mov ds, ax - mov ss, ax - mov esp, 090000h - mov byte [ds:0B8000h], 'P' - mov byte [ds:0B8001h], 1Bh - -hang: - jmp hang - -gdt_null: ; the first element is the so called null descriptor - dd 0 ; it is not referenced by the processor - dd 0 - -gdt_code: ; usually we want at least one segment descriptor for code - dw 0ffffh ; segment length bits 0-15 - dw 0 ; segment base byte 0,1 - db 0 ; segment base byte 2 - db 10011010b ; access rights - db 11001111b ; bit 7-4: 4 flag bits: granularity, default operation - ; size bit, 2 bits available for OS - ; bit 3-0: segment length bits 16-19 - db 0 ; segment base byte 3 - -gdt_data: ; usually we want at least one segment descriptor for data - dw 0ffffh - dw 0 - db 0 - db 10010010b - db 11001111b - db 0 -gdt_end: - -gdtr: - dw gdt_end - gdt_null - 1 ; 2 bytes are the size of the GDT in bytes - 1 - dd gdt_null ; 4 bytes are the address of the GDT start diff --git a/kernel.c b/kernel.c @@ -0,0 +1,18 @@ +void kernel_main() +{ + char *vidmem = (char*) 0xb8000; + vidmem[0] = 'H'; + vidmem[2] = 'e'; + vidmem[4] = 'l'; + vidmem[6] = 'l'; + vidmem[8] = 'o'; + vidmem[10] = ' '; + vidmem[12] = 'W'; + vidmem[14] = 'o'; + vidmem[16] = 'r'; + vidmem[18] = 'l'; + vidmem[20] = 'd'; + + while (1) { + } +} diff --git a/kernel.ld b/kernel.ld @@ -0,0 +1,38 @@ +ENTRY(_start) +OUTPUT_FORMAT(elf32-i386) + +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) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + + /* 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/sos.img.layout b/sos.img.layout @@ -0,0 +1,6 @@ +label: dos +label-id: 0x8e648a50 +device: sos.img +unit: sectors + +sos.img1 : start= 2048, size= 129024, type=83, bootable