Bran's Kernel Development Tutorial Known Bugs: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
m (added suggestion from http://forum.osdev.org/viewtopic.php?f=8&t=18302)
(Fix typographical error)
 
(15 intermediate revisions by 7 users not shown)
Line 1: Line 1:
Several sources - including this Wiki - point to [http://osdever.net/bkerndev/Docs/basickernel.htm Bran's Kernel Development Tutorial] as a starting point. This is all well, but there are some issues with that tutorial that usually make people appear on the forum and asking all the same questions again. This article is meant to preempt those questions, like a "Bran's FAQ" if you like.
Several sources - including this Wiki - point to [http://osdever.net/bkerndev/Docs/basickernel.htm Bran's Kernel Development Tutorial] as a starting point. This is all well, but there are some issues with that tutorial that usually make people appear on the forum and asking all the same questions again. This article is meant to preempt those questions, like a "Bran's FAQ" if you like.

NOTE: osdever.net, the site that contains Bran's tutorial, went down for an extended amount of time recently. You can find it no matter what on the [http://web.archive.org/web/20190306175430/http://osdever.net/bkerndev/Docs/basickernel.htm Internet Archive].


===As soon as I add strings, things go wrong.===
===As soon as I add strings, things go wrong.===
Line 13: Line 15:
code = .;
code = .;
*(.text)
*(.text)
'''*(.rodata)'''
'''*(.rodata*)'''
. = ALIGN(4096);
. = ALIGN(4096);
}
}
Line 32: Line 34:


If you still have problems, you may need to change the output format of the nasm command in the build.bat to make an [[ELF]] file instead of [[a.out]].
If you still have problems, you may need to change the output format of the nasm command in the build.bat to make an [[ELF]] file instead of [[a.out]].

===timer_wait never returns===
The provided method to wait a number of timer ticks never returns because the <code>timer_ticks</code> variable is not defined as volatile. Changing its definition to <code>volatile unsigned int timer_ticks = 0;</code> will make the <code>timer_wait()</code> function work.

Also, instead of busy waiting, the processor could be put into sleep in order to save power. It can be done like this:
<syntaxhighlight lang="c">
void timer_wait(int ticks)
{
unsigned int eticks;

eticks = timer_ticks + ticks;
while(timer_ticks < eticks)
{
__asm__ __volatile__ ("sti//hlt//cli");
}
}
</syntaxhighlight>

===Does not properly set up PIT===
The tutorial says the PIT setup code snippet it provides is "optional", when in reality it isn't.

===Does not use Cross-Compiler===
Bran's Kernel Tutorial uses DJGPP and NASM (standard install) on windows.<br />
To allow the code to link on a cross-compiler you must first remove all leading underscores from Global and External ASM Labels.

===Divide by zero interrupt does not get raised===
After implementing the IDT and ISRs, the tutorial explains that dividing by zero will now raise the exception 'divide by zero' and consequently execute the fault handler. The tutorial provides the following C code:
<syntaxhighlight lang="c">
int i = 10 / 0;
</syntaxhighlight>
The fault handler on this exception, however, will not be raised and nothing happens. Compilers usually optimize and insert some extra code (so there is actually no divide by zero). The only way to guarantee this exception is raised is to write some in-line assembly like:
<syntaxhighlight lang="c">
__asm__ ("div %0" :: "r"(0));
</syntaxhighlight>

===Compiler error: unknown type name ‘size_t'===
GCC produces the following errors: ''unknown type name 'X'''. The tutorial source code doesn't include any standard definitions for types like ''size_t'' or ''uint32_t''. Including the following headers in each source file:
<syntaxhighlight lang="c">
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
</syntaxhighlight>


===References===
===References===
Line 37: Line 81:


[[Category:OS Development]]
[[Category:OS Development]]
[[Category:Troubleshooting]]
[[Category:FAQ]]

Latest revision as of 19:46, 12 July 2022

Several sources - including this Wiki - point to Bran's Kernel Development Tutorial as a starting point. This is all well, but there are some issues with that tutorial that usually make people appear on the forum and asking all the same questions again. This article is meant to preempt those questions, like a "Bran's FAQ" if you like.

NOTE: osdever.net, the site that contains Bran's tutorial, went down for an extended amount of time recently. You can find it no matter what on the Internet Archive.

As soon as I add strings, things go wrong.

The linker script from Bran's tutorial does not add the rodata sections to the binary, which is where the compiler puts static strings. Use this one instead:

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata*)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

If you still have problems, you may need to change the output format of the nasm command in the build.bat to make an ELF file instead of a.out.

timer_wait never returns

The provided method to wait a number of timer ticks never returns because the timer_ticks variable is not defined as volatile. Changing its definition to volatile unsigned int timer_ticks = 0; will make the timer_wait() function work.

Also, instead of busy waiting, the processor could be put into sleep in order to save power. It can be done like this:

void timer_wait(int ticks)
{
    unsigned int eticks;

    eticks = timer_ticks + ticks;
    while(timer_ticks < eticks) 
    {
        __asm__ __volatile__ ("sti//hlt//cli");
    }
}

Does not properly set up PIT

The tutorial says the PIT setup code snippet it provides is "optional", when in reality it isn't.

Does not use Cross-Compiler

Bran's Kernel Tutorial uses DJGPP and NASM (standard install) on windows.
To allow the code to link on a cross-compiler you must first remove all leading underscores from Global and External ASM Labels.

Divide by zero interrupt does not get raised

After implementing the IDT and ISRs, the tutorial explains that dividing by zero will now raise the exception 'divide by zero' and consequently execute the fault handler. The tutorial provides the following C code:

int i = 10 / 0;

The fault handler on this exception, however, will not be raised and nothing happens. Compilers usually optimize and insert some extra code (so there is actually no divide by zero). The only way to guarantee this exception is raised is to write some in-line assembly like:

__asm__  ("div %0" :: "r"(0));

Compiler error: unknown type name ‘size_t'

GCC produces the following errors: unknown type name 'X'. The tutorial source code doesn't include any standard definitions for types like size_t or uint32_t. Including the following headers in each source file:

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

References