James Molloy's Tutorial Known Bugs: Difference between revisions

m
[unchecked revision][unchecked revision]
No edit summary
 
(6 intermediate revisions by 5 users not shown)
Line 1:
Several sources - including this Wiki - point to [http://www.jamesmolloy.co.uk/tutorial_html/ James Molloy's Roll your own toy UNIX-clone OS] Tutorial as a starting point. This is wellfine, but the tutorial has some well-known weak points that cause trouble for people again and again. It's not uncommon that well-established members traced back mysterious bugs to early parts of their operating systems based on this tutorial. Nonetheless, it's one of the best introductory tutorials out there even if it has the occasional landmine. This article is meant to preempt issues arising from following the tutorial and to aid those that have encountered such problems. It is generally recommended to be sceptical of its advise on how to design your kernel and compare its information against this wiki. Some issues are quite subtle and only experts will recognize them.
 
== Before you follow the tutorial ==
Line 13:
== Problem: __cdecl calling convention ==
 
The tutorial states that the <tt>__cdecl</tt> calling convention is used. This is, however, a Windows term. and yourYour cross-compiler uses a similar calling convention but it is called the System V ABI for i386. It is advisable to understand this calling convention in depth, especially parts about how the parameters on the stack are clobbered and how structure parameters are passed. This will be very useful later and will help you avoid a later subtle bug. The function call example in 2.3 neglects to add 12 to esp following the call instruction, andso the three parameters are never thus popped.
 
== Problem: CFLAGS ==
Line 53:
There are two ways around this. The most practical method is to pass the structure as a pointer instead, which allows you to explicitly edit the register state when needed - very useful for system calls, without having the compiler randomly doing it for you. The compiler can still edit the pointer on the stack when it's not specifically needed. The second option is to make another copy the structure and pass that.
 
== Problem: ISR 17 and 3021 have error codes ==
 
The interrupt handling code in the downloadable code have a bug where it handles ISR 17 and 3021 by pushing a fake error code, but the CPU does push error codes here.
 
== Problem: struct registers::esp is useless ==
Line 74:
 
The <tt>kmalloc</tt> function in 6.4.1 only 1-byte aligns or page-aligns its memory address. This means you can only reliably use it allocate memories for chars (size 1), but not any larger types unless you use page-alignment. A proper malloc implementation returns pointers that are aligned such that they are suitable for all the common types, for instance it could be 64-bit (8-byte) aligned. You'll also want to modify the parameters such that it uses <tt>size_t</tt> appropriately rather than <tt>u32int</tt>.
 
Additionally the check if the address is page aligned is wrong.
<nowiki>
if (align == 1 && (placement_address & 0xFFFFF000)) // If the address is not already page-aligned</nowiki>
should be
<nowiki>
if (align == 1 && (placement_address & 0x00000FFF)) // If the address is not already page-aligned</nowiki>
 
== Problem: Paging Code ==
Line 137 ⟶ 144:
Note how the EAX register is assigned to the ECX register. However, later on the ECX register is assigned to EBP register. The reason for this is that the optimizer was using the EAX register to store the EIP variable and the ECX register to store the EBP variable. This results in the EIP variable being assigned to the ECX register ''as well as'' the EBP register. This leads to a subsequent '''ret''' statement sending the CPU to some invalid memory location.
 
A way to fix this is to remove the Inline Assembly by, for example adding this to '''process.cs''':
<nowiki>
; Here we:
Line 199 ⟶ 206:
%endmacro</nowiki>
 
=== Problem 2: Don't forget to allow interrupts in user mode in idt_set_gate ===
 
Find this comment in chapter 4 and uncomment the code:
Line 227 ⟶ 234:
This fixes a problem where the syscall hander won't get called.
 
=== Problem 4: MisingMissing documentation around set_kernel_stack ===
 
<tt>KERNEL_STACK_SIZE</tt> needs defining in <tt>task.h</tt>:
73

edits