GDT code - boom
Have you tried changing this code
to
Code: Select all
gp.base = &gdt;
Code: Select all
gp.base = (unsigned int)gdt;
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.
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.
My code compiles with:
Almost all the bugs that get through the compiler are bugs in the programming logic. You should try the above as well.
Code: Select all
-W -Werror -Wall -Wpointer-arith -Wcast-align -Wcast-qual -Wno-unused-parameter
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
-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*)
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.
- Combuster
- 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:
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...
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...
- Kevin McGuire
- Member
- Posts: 843
- Joined: Tue Nov 09, 2004 12:00 am
- Location: United States
- Contact:
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.
Code: Select all
hlt
nop
nop
Code: Select all
mov ds, ax
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?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]);
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])
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.
There's a feature for breaking into Bochs debugger, if the debugger and magic breakpoint are enabled: xchg %bx, %bxKevin McGuire wrote:If you are using Bochs place a:
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.