I decided to try and write a C Hello world protected mode Kernel, and although directly accessing the video memory works to print characters manually, I decided to try to write a string, and there are no warnings or errors but it boots to a blinking cursor, but after about half a millisecond it black screens. Here is the code:
#include <stdint.h>
void kmain() {
// Startup
int i = 0;
uint16_t* vidmem = (uint16_t*) 0xB8000;
char string[] = "Hello, kernel world!";
while (string[i]) {
vidmem[i] = string[i];
vidmem[i+1] = 0;
i+=2;
}
// Hang the system
for (;;) {
}
}
Compiled with: gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O1 -Wall -Wextra
And then linked with a generic boot.o and then made into an ISO with grub
I tested it in qemu on linux, any help would be appreciated!
Before I attempted the printstring funciton, this was able to print characters:
vidmem[0] = "C";
vidmem[1] = 1;
Which would print the letter C. Nothing fancy though.
After trying to fix some erros I came up with this:
#include <stdint.h>
void kmain() {
// Startup
int i = 0;
int j = 0;
uint16_t* vidmem = (uint16_t*) 0xB8000;
char string[] = "Hello, kernel world!";
while (string[i]) {
vidmem[i] = string[i];
vidmem[j] = 0;
i+=1;
j=i*2;
}
// Hang the system
for (;;) {
}
}
Which still blackscreens.
uint16_t* vidmem
how many bytes are written byvidmem[i] = string[i];
and how many bytes are added byvidmem[i+1]
, and how many bytes advanced byi+=2;
?uint16_t
is 2 bytes and sovidmem[i]
writes to 2 bytes, andvidmem[i+1]
is 2 bytes further on.i+=2
used as an index advances by 4 bytes in the video memory and 2 bytes in your source string.string
? You can easily miss the\0
this way.