Results 1 to 3 of 3

Thread: Making a Simple C kernel with Basic printf and clearscreen Functions

  1. #1

    Making a Simple C kernel with Basic printf and clearscreen Functions

    This tutorial has the purpose of showing a simple kernel. Let's start with the entry of the kernel which is in our example in a file called kernel_start.asm.


    [BITS 32]
    [global start]
    [extern _k_main] ; this is in the c file

    start:
    call _k_main

    cli ; stop interrupts
    hlt ; halt the CPU


    Okay, this code is 32-bit code(the [BITS 32] does that) and calls a function called k_main, which is defined in a C file called kernel.c. Now you're probably wondering why it's called k_main in the C file, but _k_main in the assembly file. This is because C/C++ compilers add an underscore( _ ) in front of all C/C++ functions... Unless you link this to an ELF file. ELF does not need the underscore. Once k_main is called, the instruction cli is executed. cli turns off interrupts(though they were never on in this example). Then, hlt is executed which tells the CPU to stop executing. We could do jmp $ instead of hlt, but that eats up tons of CPU time and could cause the CPU to overheat. Note that interrupts can awake the CPU from a hlt instruction. That is why we disable interrupts before doing hlt as we want this to be a complete stop.

    Now, let's move on to the definitions and function prototypes defined at the start of kernel.c.


    #define WHITE_TXT 0x07 // white on black text

    void k_clear_screen();
    unsigned int k_printf(char *message, unsigned int line);
    void update_cursor(int row, int col);

    Nothing real special here except for the #define WHITE_TXT 0x07. We'll come back to that define in a little bit, for now, just remember that it's there.

    Now, let's move on to the k_main function.


    k_main() // like main in a normal C program
    {
    k_clear_screen();
    k_printf("Hi!\nHow's this for a starter OS?", 0);
    };


    k_main is the entry point to our kernel. We call this function in the kernel_start.asm file.
    k_clear_screen does what you would expect... clear the screen. k_printf("Hi!\nHow's this for a starter OS?", 0); prints the text:

    Hi!
    How's this for a starter OS?

    Starting on the first line of video memory(0 is the first line, 1 is the second, 2 is the third, etc). The \n specifies a newline just like it would in the C/C++ printf function.

    In protected mode, you can't call BIOS Interrupts to clear the screen, we have to do this ourselves by writing directly to the Video Memory.


    void k_clear_screen() // clear the entire text screen
    {
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;
    while(i < (80*25*2))
    {
    vidmem[i]=' ';
    i++;
    vidmem[i]=WHITE_TXT;
    i++;
    };
    };


    In the above function(k_clear_screen), the pointer vidmem points to 0xb8000 which is the start of video memory in protected mode. We declare the pointer as a char so we can write a byte at a time to the video memory. The text mode on an x86 is 80 x 25 charactors. Each charactor needs 2 bytes. The first byte is the charactor, the second byte is the attribute byte which controlls color and blinking. So, we take 80*25(the amount of charactors that can be displayed on the screen) and multiply it by 2 since we access video memory a byte at a time. The loop is pretty much self explanitory. The vidmem[i]=' '; writes a space to the video memory(i points to the exact spot). We add 1 to i, i++; to get to the next byte of video memory(the attribute byte) and put 0x07 there. 0x07 specifies a black background with white, non-blinking, text.

    Now on to the k_printf function!


    unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
    {
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;

    i=(line*80*2);

    while(*message!=0)
    {
    if(*message=='\n') // check for a new line
    {
    line++;
    i=(line*80*2);
    *message++;
    } else {
    vidmem[i]=*message;
    *message++;
    i++;
    vidmem[i]=WHITE_TXT;
    i++;
    };
    };

    return(1);
    };


    The k_printf function works much like the k_clear_screen function. while(*message!=0) loops until we reach the end of the string of text that is passed to the function. if(*message=='\n') checks to see if the next charactor of the string is for a newline.. If it is, we we add 1 to line so that the charactors that come after a \n will be down one more line. If a charactor is not a newline( \n ), we just put the charactor into video memory and set the attribute byte to 0x07(black background with white non-blinking text).

    Conclusion
    There! A basic kernel. You probably will want to write a better k_printf function, as the one used in this example is rather simple and doesn't handle things like %s, %d, %c, etc. Still, this should be enough to get you on the track towards making a better one. Hope you enjoyed this tutorial!

  2. #2
    Just a Virtualized Geek MrLinus's Avatar
    Join Date
    Sep 2001
    Location
    Redondo Beach, CA
    Posts
    7,323
    source: http://osdev.neopages.net/tutorials/pdf/basickernel.pdf

    **Thread moved from Tutorials to General Chit Chat. Not original tutorial** Please read the Legal Notices.
    Goodbye, Mittens (1992-2008). My pillow will be cold without your purring beside my head
    Extra! Extra! Get your FREE copy of Insight Newsletter||MsMittens' HomePage

  3. #3
    Banned
    Join Date
    Aug 2001
    Location
    Yes
    Posts
    4,424
    No original? No Tutorial... tsk tsk...
    *moved*

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •