#include "k_defines.h" inline void outportb(unsigned int port,unsigned char value); unsigned int panic(char *message); void k_clear_screen(); unsigned int k_printf(char *message, unsigned int line); void update_cursor(int row, int col); k_main() // like main { k_clear_screen(); k_printf("Welcome to Simplified OS.", 0); update_cursor(1, 0); k_printf("Right now the kernel is loaded at 1MB physical,/nbut mapped at FF800000 hex.", 3); update_cursor(5, 0); }; void k_clear_screen() // clear the entire text screen { char *vidmem = (char *) 0xb8000; unsigned int i=0; while(i<(80*2*25)) { vidmem[i]=' '; i++; vidmem[i]=WHITE_TXT; i++; }; }; unsigned int k_printf(char *message, unsigned int line) { char *vidmem = (char *) 0xb8000; unsigned int i=0; i=(line*80*2); while(*message!=0) // 24h { if(*message==0x2F) { *message++; if(*message==0x6e) { line++; i=(line*80*2); *message++; if(*message==0) { return(1); }; }; }; vidmem[i]=*message; *message++; i++; vidmem[i]=0x7; i++; }; return(1); }; /* ============== */ inline void outportb(unsigned int port,unsigned char value) // Output a byte to a port { asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value)); }; /* ============== */ /* by DF */ void update_cursor(int row, int col) { USHORT position=(row*80) + col; // cursor LOW port to vga INDEX register outportb(0x3D4, 0x0F); outportb(0x3D5, (UCHAR)(position&0xFF)); // cursor HIGH port to vga INDEX register outportb(0x3D4, 0x0E); outportb(0x3D5, (UCHAR)((position>>8)&0xFF)); }; unsigned int panic(char *message) // just a modified version of k_printf { char *vidmem = (char *) 0xb8000; unsigned int i=0; unsigned int line=0; i=(line*80*2); while(*message!=0) // 24h { if(*message==0x2F) { *message++; if(*message==0x6e) { line++; i=(line*80*2); *message++; if(*message==0) { return(1); }; }; }; vidmem[i]=*message; *message++; i++; vidmem[i]=0x9; // use blue text i++; }; return(1); }; kernel.c #define WHITE_TXT 0x7 #define BLUE_TXT 0x09 #define UCHAR unsigned char #define USHORT unsigned short k_defines.h [BITS 32] [global start] [extern _k_main] ; this is in the c file start: ; stop using bootloader GDT, and load new GDT lgdt [gdt_ptr] mov ax,LINEAR_DATA_SEL mov ds,ax mov es,ax mov ss,ax mov fs,ax mov gs,ax call _k_main jmp $ ; crash ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SECTION .data gdt: ; NULL descriptor dw 0 ; limit 15:0 dw 0 ; base 15:0 db 0 ; base 23:16 db 0 ; type db 0 ; limit 19:16, flags db 0 ; base 31:24 ; unused descriptor dw 0 dw 0 db 0 db 0 db 0 db 0 LINEAR_DATA_SEL equ $-gdt dw 0FFFFh dw 0 db 0 db 92h ; present, ring 0, data, expand-up, writable db 0CFh ; page-granular (4 gig limit), 32-bit db 0 LINEAR_CODE_SEL equ $-gdt dw 0FFFFh dw 0 db 0 db 9Ah ; present,ring 0,code,non-conforming,readable db 0CFh ; page-granular (4 gig limit), 32-bit db 0 gdt_end: gdt_ptr: dw gdt_end - gdt - 1 dd gdt K_entry.asm OUTPUT_FORMAT("binary") ENTRY(start) SECTIONS { .text 0xFF800000 : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } } kernel.ld gcc -c kernel.c -o kernel.o nasmw -f aout k_entry.asm -o k_entry.o ld -T kernel.ld kernel.o k_entry.o rename a.out kernel.bin build.bat