Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I started to learn to create a personal OS ( just a little boot loader and a 32 bits kernel ^_^ ), but i have a problem with my boot sector, it reboots on the 29th line ( mov ax,10h ) .
Who can help me please ? Here's my code ( inspired from Gregor Brunmar's tutorial ) :
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Try this, I don't know why people like to waste the memory in their boot loader, or why everyone thinks because it's called a NULL descriptor that it must be NULL, this is not the case. You can put the gdt descriptor in that memory space to save a few bytes, and if you'r really worried you can even use that last 2-bytes in the null descriptor to hold a variable or two, just make sure you don't mess up the size of the descriptor. The CPU does not use the NULL descriptor, it is only a space filler. If cs,ds,es is 0, it will throw an exception no matter what is in the descriptor.
gdt:
gdt_null: ;Yay, i'm not emptry anymore, i have a purpose
gdt_desc:
dw gdt_end - gdt - 1
dd gdt
dw 0
gdt_code:
dw 0xFFff
dw 0
db 0
db 0x9A
db 0xCF
db 0
gdt_data:
dw 0FFFFh
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end:
This saves you 6 bytes in your boot loader, possibly 8 if you use the other 2 for a variable .
Try this, I don't know why people like to waste the memory in their boot loader, or why everyone thinks because it's called a NULL descriptor that it must be NULL, this is not the case. You can put the gdt descriptor in that memory space to save a few bytes, and if you'r really worried you can even use that last 2-bytes in the null descriptor to hold a variable or two, just make sure you don't mess up the size of the descriptor. The CPU does not use the NULL descriptor, it is only a space filler. If cs,ds,es is 0, it will throw an exception no matter what is in the descriptor.
gdt:
gdt_null: ;Yay, i'm not emptry anymore, i have a purpose
gdt_desc:
dw gdt_end - gdt - 1
dd gdt
dw 0
gdt_code:
dw 0xFFff
dw 0
db 0
db 0x9A
db 0xCF
db 0
gdt_data:
dw 0FFFFh
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end:
This saves you 6 bytes in your boot loader, possibly 8 if you use the other 2 for a variable .
Thanks, it works =)
Now, i have a problem with my kernel, it reboots also x')
I didn't really look at the code at all, but your problem is a little vague. Do you have a BOCHS dump? where does it reboot? if it is right off the bat, then you probably are jumping to the wrong memory address from your bl.
01000101 wrote:I didn't really look at the code at all, but your problem is a little vague. Do you have a BOCHS dump? where does it reboot? if it is right off the bat, then you probably are jumping to the wrong memory address from your bl.
I don't know what you do mean with the BOCHS dump, but here's what i see in the Bochs Console :
push es
mov ax, 0x1000
mov es, ax
mov bx, 0
mov ah, 2
mov al, 2 ; 2 sectors in case when the Kernel becomes too big
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
int 13h ; Interrupt 13h
pop es
push es
mov ax, 0
mov es, ax
mov bx, 0x1000
mov ah, 2
mov al, 2 ; 2 sectors in case when the Kernel becomes too big
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
int 13h ; Interrupt 13h
pop es
Well, firstly, you are linking your text area at 0x1000. You're loading your bootsector at es:si, or 0x1000:0x0000, which is linear address 0x10000, so you need to be linking to 0x10000 instead of 0x1000. Also, do a hex-view of your kernel and make sure that your main function is the FIRST thing in the file (it may be running the wrong piece of code, or trying to run a text string rather than your main function). Typically I use an ASM stub in my kernel and link it to my C code, my ASM stub then jumps to my kernel's main function. This means I don't have to worry about data being put before my startup function, because my asm stub is always the first thing linked, so my main function can be located anywhere within the program. Also, instead of doing while (1), it's typical to use for (;;);, because some compilers will actually do
again:
mov ax, 1
cmp ax,1
je again
Where a for (;;); is typically just:
.j jmp .j, or
again:
jmp again
I think nowadays it's mostly habbit, because a smart compiler should know what to do with while (1);
because of the structure of my OS, I have a pseudo-start function that just pushes the jump to my kernel a little farther to the actual main() function.
you might actually want to consider NOT using C to test if your bl is jmping to your kernel, you might want to use ASM and put a hlt with a trivial one-liner after the hlt to see if you are running the right code or not