I think it’s 2003 or 2004 that I made this very simple booting code to demonstrate how OS starts. I paste the output here for the future reference.
bootsec.asm
ORG 0x7c00 jmp begin_boot bootmesg1 db "Press any to boot KERNEL....." mesglen equ $ - bootmesg1 drive db 0 [BITS 16] print_mesg: mov ah, 0x13 mov al, 0x00 mov bx, 0x0007 mov cx, mesglen mov dx, 0x0000 int 0x10 ret clrscr: mov ax, 0x0600 mov cx, 0x0000 mov dx, 0x174f mov bh, 0 int 0x10 ret get_key: mov ah, 0x00 int 0x16 ret begin_boot: mov [drive], dl xor ax, ax mov ds, ax call clrscr mov bp, bootmesg1 call print_mesg call get_key reset_floppy: mov ax, 0x00 mov dl, [drive] int 13h jc reset_floppy read_floppy: mov bx, 9000h mov ah, 0x02 mov al, 17 mov ch, 0 mov cl, 2 mov dh, 0 mov dl, [drive] int 13h jc read_floppy read_floppy2: mov al, 17 inc dh int 13h jc read_floppy2 [BITS 16] call clrscr cli lgdt[gdtr] mov eax, cr0 or al, 0x01 mov cr0, eax jmp codesel:go_pm [BITS 32] go_pm: mov ax, datasel mov ds, ax mov es, ax mov ax, videosel mov gs, ax mov ax, 0x10 mov ss, ax mov esp, 0xFFFF mov dl, [drive] mov edx, 0x3f2 mov al, 0x0c out dx, al call 9000h halt ret [BITS 16] gdtr: dw gdt_end - gdt - 1 dd gdt gdt nullsel equ $ - gdt gdt0 dd 0 dd 0 codesel equ $ - gdt code_gdt dw 0x0ffff dw 0x0000 db 0x00 db 0x09a db 0x0cf db 0x00 datasel equ $ - gdt data_gdt dw 0x0ffff dw 0x0000 db 0x00 db 0x092 db 0x0cf db 0x00 videosel equ $ - gdt dw 3999 dw 0x8000 db 0x0b db 0x92 db 0x00 db 0x00 gdt_end times 510 - ($ - $$) db 0 dw 0xaa55
kernel_start.asm
[BITS 32] [global start] [extern kernel_main] start: call kernel_main cli hlt
kernel.c
/* kernel.c */ #define BLACK 0x00 #define BLUE 0x01 #define GREEN 0x02 #define CYAN 0x03 #define RED 0x04 #define MAGENTA 0x05 #define BROWN 0x06 #define WHITE 0x07 #define GRAY 0x08 #define YELLOW 0x0e #define set_text_color(i) (color_text=i) #define set_bk_color(i) (color_bk=i< (MHZ * 1000)) { msec--; cnt=i; } } while (msec > 0); } void print(char *str) { int p; for ( ; *str; str++) { if (xpos > 80) { xpos = 0; ypos++; } if (ypos > 25) ypos = 0; if (*str == 'n') { ypos++; xpos=0; continue; } p = ypos * 80 * 2 + xpos * 2; vidmem[p] = (char)*str; vidmem[p + 1] = (char)color_text | color_bk; xpos++; } } void real_job() { set_cur(3,1); print("My Own New Kernel...!!!"); set_text_color(YELLOW); set_bk_color(BLUE); sleep(1000); set_cur(3, 2); print("will shutdown soon."); sleep(3000); set_cur(3, 5); print("BOOOM..."); }
link.ld
OUTPUT_FORMAT("binary") ENTRY(start) SECTIONS { .text 0x09000 : { code = .; _code = .; __code = .; *(.text) } .data : { data = .; _data = .; __data = .; *(.data) } .bss : { bss = .; _bss = .; __bss = .; *(.bss) } end = .; _end = .; __end = .; }
Makefile
MHZ=`cat /proc/cpuinfo | grep MHz | cut -d : -f 2 | cut -d . -f 1 | cut -d ' ' -f 2` all: bins bins: nasm -f bin bootsec.asm -o bootsec.bin gcc -c -nostdinc -nostdlib -Wall -DMHZ=$(MHZ) -o kernel.o kernel.c nasm -f aout kernel_start.asm -o kernel_start.o ld -T link.ld -o kernel.bin kernel_start.o kernel.o clean: rm -f *.o rm -f bootsec.bin rm -f kernel.bin rm -f floppy.img floppy: image dd if=floppy.img of=/dev/fd0 image: bins dd if=bootsec.bin of=floppy.img dd if=kernel.bin of=floppy.img seek=1
Leave a Reply