Page 2 of 3
Posted: Tue Apr 03, 2007 2:37 pm
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.
Posted: Tue Apr 03, 2007 2:42 pm
by frank
Have you tried changing this code
to
Posted: Tue Apr 03, 2007 2:45 pm
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.
Posted: Tue Apr 03, 2007 2:50 pm
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.
Posted: Tue Apr 03, 2007 2:51 pm
by ehird
-W == -Wextra, and the rest I'll try.
(But friends don't let friends use -Werror
)
Posted: Tue Apr 03, 2007 3:01 pm
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*)
Posted: Tue Apr 03, 2007 3:05 pm
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.
Posted: Tue Apr 03, 2007 3:27 pm
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...
Posted: Tue Apr 03, 2007 3:31 pm
by ehird
Maybe gcc is automatically casting it or something... I wouldn't put it past that voodoo compiler. I'll try bochs.
Posted: Tue Apr 03, 2007 3:42 pm
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<.
Posted: Tue Apr 03, 2007 4:29 pm
by Kevin McGuire
If you are using Bochs place a:
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.
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.
Posted: Tue Apr 03, 2007 4:41 pm
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.
Posted: Tue Apr 03, 2007 5:00 pm
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.
Posted: Tue Apr 03, 2007 6:12 pm
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.
Posted: Wed Apr 04, 2007 5:34 am
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.