GDT code - boom

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.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

Don't know why bkerndev to the letter would be so broken... but OK. Time to work out how to use gdb with a kernel, I guess.
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

Have you tried changing this code

Code: Select all

gp.base = &gdt; 
to

Code: Select all

gp.base = (unsigned int)gdt;
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

frank: Nope, didn't work. Ok, time to fire up tar.

edit: http://filesocket.com/download/3abos.tar.gz if anyone wants to take a look.. it's basically bkerndev but with elf. Binary and a floppy image is included.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

My code compiles with:

Code: Select all

-W -Werror -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wno-unused-parameter
Almost all the bugs that get through the compiler are bugs in the programming logic. You should try the above as well. :)
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

-W == -Wextra, and the rest I'll try.

(But friends don't let friends use -Werror :))
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

-Werror is essential. If you don't use -Werror, then you start thinking of excuses not to fix the compiler warnings. You notice I specifically disable one. It's the only one enabled by -W -Wall for which there's no easy way to tell the compiler that you are fully aware of the fact.

If you don't use -Werror, sooner or later you let one warning get through. Then a week later you've already got so many warnings that you won't notice if there's suddenly one more. At that point having the warnings is for all practical purposes waste of time. If you make them errors, you'll have to fix them, and any warning you see indicates a potential problem.

I've caught numerous bugs because my compile failed because I was comparing a signed with an unsigned, because I was assigned pointers of wrong types, because I was doing assignment when I should have compared for equality, or numerous other similar minor details.

Try it. It'll feel very limiting and make you feel bad at first, but soon you'll get used to it, and start wondering why on earth do people allow such warnings in their code.

edit: oh and one more thing: never use casts if you can avoid them. Let the -Werror trigger an error first, then add the proper cast once you've checked that it's really what should be done. Ofcourse sometimes you'll know you'll have to cast, and that's ok, but try to avoid them like a plague, and even more so for (void*)
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

I always look at each warning and examine it - but e.g. bkerndev uses different memset among other things types to what my system uses, so I'd either have to try and change it, most likely breaking them, or turn those warnings off altogether, in which case I lose out.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I have poked at things a bit and it seems gcc does something really weird:

gdt == &gdt

all of the following variations seem to generate exactly the same working kernel on me:
gp.base = &gdt;
gp.base = (int) &gdt;
gp.base = (int) gdt;
gp.base = (int) &(gdt[0]);

this also means that this issue can't be the cause of the error, but nevertheless its still disturbing...
"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 ]
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

Maybe gcc is automatically casting it or something... I wouldn't put it past that voodoo compiler. I'll try bochs.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

I've tracked down the crash. It's this line of gdt_flush:

mov ds, ax

all before that work, but this goes >boom<.
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by Kevin McGuire »

If you are using Bochs place a:

Code: Select all

hlt
nop
nop
Then wait for Bochs to say it has encountered a hlt instruction. Then press the key combination ctrl+c. Next type the letter s at the prompt and press enter and repeat this sentence until the instruction (below) appears on the screen.

Code: Select all

mov ds, ax
Then type info reg, or try doing a info gdt and tell us what it does along with a the Bochs fatal error message again.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Combuster wrote: all of the following variations seem to generate exactly the same working kernel on me:
gp.base = &gdt;
gp.base = (int) &gdt;
gp.base = (int) gdt;
gp.base = (int) &(gdt[0]);
Nothing strange about that... gdt is an array and foo[bar] is basicly a fancy way to say *(foo+(bar)). If you try, you'll notice you can do 0[gdt] as well and there's not difference. So gdt obviously has to be a pointer in that expression. But if you say &gdt, there's no pointer to take the address of. Strange eh?

The answer is that when you define an array, it will "decay" to a pointer, when necessary. So you indeed have an array, which has an address, but which decays to pointer when used as a value.

So:

Code: Select all

// takes the address of array and makes it pointer
// which gets coerced to int (you didn't ask for warnings, right?)
gp.base = &gdt;
// same as above, but this time with a proper explicit cast
gp.base = (int) &gdt;
// array decays to pointer (to it's first element) which is cast to int
gp.base = (int) gdt;
// takes the addres of the first element of the array and casts to int
gp.base = (int) &(gdt[0]);
// should work just as well, didn't bother trying
gp.base = (int) &(0[&gdt])
So the only strangeness is in the specification: arrays, when used as values, will decay to pointers. If you take the address (with unary-&) you get the same pointer (this was not exact definition from the specification because I can't bother to look up the exact rules right now).

I find it highly unlikely that your problem has anything to do with taking the address of an array. It's more likely just some bug in the code that constructs the GDT entries.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

We could help you better if you posted your Bochs log.

Also, have a go at not taking the underscores off symbols in your assembly files.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Kevin McGuire wrote:If you are using Bochs place a:
There's a feature for breaking into Bochs debugger, if the debugger and magic breakpoint are enabled: xchg %bx, %bx

Just wastes a cycle on real hardware (essentially NOP) but Bochs will catch it.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

pcmattman wrote:We could help you better if you posted your Bochs log.

Also, have a go at not taking the underscores off symbols in your assembly files.
That definately doesn't work - only aout adds leading underscores.
Post Reply