CLOSE
Updated on 17 Jun, 20259 mins read 25 views

At this point we have loaded kernel.asm which does the entering into protected mode by setting up gdt tables, enabling protected mode bit (PE bit).

Now we proceed a step further by linking C with asm and calling C function which would be our kernel.

products/kernel.bin: products/kernel_entry.o products/kernel.o
	ld -o $@ -Ttext 0x1000 $^ --oformat binary
// kernel.c
#include <stddef.h>
#include <stdint.h>

// VGA text buffer constants
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
static uint16_t* const VGA_BUFFER = (uint16_t*) 0xB8000;

// VGA color constants
enum vga_color {
    VGA_COLOR_BLACK = 0,
    VGA_COLOR_BLUE = 1,
    VGA_COLOR_GREEN = 2,
    VGA_COLOR_CYAN = 3,
    VGA_COLOR_RED = 4,
    VGA_COLOR_MAGENTA = 5,
    VGA_COLOR_BROWN = 6,
    VGA_COLOR_LIGHT_GREY = 7,
    VGA_COLOR_DARK_GREY = 8,
    VGA_COLOR_LIGHT_BLUE = 9,
    VGA_COLOR_LIGHT_GREEN = 10,
    VGA_COLOR_LIGHT_CYAN = 11,
    VGA_COLOR_LIGHT_RED = 12,
    VGA_COLOR_LIGHT_MAGENTA = 13,
    VGA_COLOR_LIGHT_BROWN = 14,
    VGA_COLOR_WHITE = 15,
};

// Function to create a VGA color attribute byte
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) {
    return fg | bg << 4;
}

// Function to create a VGA text entry
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) {
    return (uint16_t) uc | (uint16_t) color << 8;
}

// Kernel main function
void kernel_main() {
    uint8_t color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
    VGA_BUFFER[0] = vga_entry('A', color);  // Print 'A' at the top-left corner
}

 

enable_a20:
    in al, 0x92
    or al, 2
    out 0x92, al
    ret

 

 

print_string:
    ; Print a string pointed by DS:BX
    mov ah, 0x0E        ; Teletype output function
.next_char:
    lodsb               ; Load next character from DS:SI into AL
    cmp al, 0
    je .done
    int 0x10            ; BIOS video interrupt
    jmp .next_char
.done:
    ret
    
    
    msg_error db 'Error loading kernel', 0

 

load_error:
    ; Print error message (simplified, could be extended)
    mov bx, msg_error
    call print_string

 

// kernel.c
void kmain(void) {
    char *video_memory = (char *)0xB8000;
    *video_memory = 'j';
    *(video_memory + 1) = 0x07;  // Light grey on black background

    // Infinite loop to prevent exiting
    while (1) {}
}
dd if=/dev/zero of=floppy.img bs=512 count=2880
dd if=stage1boot.bin of=floppy.img bs=512 count=1 conv=notrunc
dd if=stage2boot.bin of=floppy.img bs=512 seek=1 count=1 conv=notrunc
dd if=kernel.bin of=floppy.img bs=512 seek=2 conv=notrunc