Ronald, It seems that you made some mistake in mixing 16 and 32 bits code in the intel_start32.S:
_realstart: cli movw %cs, %eax movw %eax, %es
xor %eax, %eax mov %eax, %cr3 /* Invalidate TLB*/
.byte 0x66 /* prefix */ .byte 0x26 .byte 0x0f, 0x01, 0x16 /* lgdt [es:offset]*/ .word 0x02 /* offset in segment */
movl %cr0, %eax andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0*/ orl $1, %eax movl %eax, %cr0 data32 ljmp $0x10, $.Lprotected
Before _realstart there was a .code16 directive, so it should be in 16 bits mode, so how could those 32 bits (long) operation works ??
This bugs seems breaks gas 2.9.5 also.
Ollie - To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message
Ollie Lho wrote:
Ronald, It seems that you made some mistake in mixing 16 and 32 bits code in the intel_start32.S:
_realstart: cli movw %cs, %eax movw %eax, %es
xor %eax, %eax mov %eax, %cr3 /* Invalidate TLB*/ .byte 0x66 /* prefix */ .byte 0x26 .byte 0x0f, 0x01, 0x16 /* lgdt [es:offset]*/ .word 0x02 /* offset in segment */ movl %cr0, %eax andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0*/ orl $1, %eax movl %eax, %cr0 data32 ljmp $0x10, $.Lprotected
Before _realstart there was a .code16 directive, so it should be in 16 bits mode, so how could those 32 bits (long) operation works ??
The compiler (assembler) adds 32-bit prefix to the insn.
On Wed, 17 May 2000, Ollie Lho wrote:
.byte 0x66 /* prefix */ .byte 0x26 .byte 0x0f, 0x01, 0x16 /* lgdt [es:offset]*/ .word 0x02 /* offset in segment */
Hmm, why would you encode lgdt manually? I can't recall gas handling it incorrectly and even if it did it would be gas that would need fixing. AFAIR, the "lgdtl %es:2" instruction yields exactly the same bytes as you emit explicitly above.
On Wed, 17 May 2000, Ollie Lho wrote:
.byte 0x66 /* prefix */ .byte 0x26 .byte 0x0f, 0x01, 0x16 /* lgdt [es:offset]*/ .word 0x02 /* offset in segment */
Hmm, why would you encode lgdt manually? I can't recall gas handling it incorrectly and even if it did it would be gas that would need fixing. AFAIR, the "lgdtl %es:2" instruction yields exactly the same bytes as you emit explicitly above.
As I remember we wanted it and a jump to fit in an exact space at FFF0 or something like that. Ron can tell us better Monday (LANL is closed for a few days because of fire).
- James
- To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message
On Fri, 19 May 2000, James Hendricks wrote:
Hmm, why would you encode lgdt manually? I can't recall gas handling it incorrectly and even if it did it would be gas that would need fixing. AFAIR, the "lgdtl %es:2" instruction yields exactly the same bytes as you emit explicitly above.
As I remember we wanted it and a jump to fit in an exact space at FFF0 or something like that. Ron can tell us better Monday (LANL is closed for a few days because of fire).
well the reason we don't use a symbolic reference to the GDT is that ld kept fouling it up. Hence the need to hardcode the address. I just got disgusted with the whole thing and hand-assembled it.
ron
- To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message
On Sat, 20 May 2000, Ronald G Minnich wrote:
Hmm, why would you encode lgdt manually? I can't recall gas handling it incorrectly and even if it did it would be gas that would need fixing. AFAIR, the "lgdtl %es:2" instruction yields exactly the same bytes as you emit explicitly above.
As I remember we wanted it and a jump to fit in an exact space at FFF0 or something like that. Ron can tell us better Monday (LANL is closed for a few days because of fire).
well the reason we don't use a symbolic reference to the GDT is that ld kept fouling it up. Hence the need to hardcode the address. I just got disgusted with the whole thing and hand-assembled it.
Unless there is a relocation associated with the instruction (you can see it with `objdump -Sr' on an object file to be sure) ld must not twiddle with the operand. What I wrote above will not create a relocation in any case as the instruction uses absolute addressing and there is no symbol referenced here. If it contained an external symbol reference originally, it will include a relocation but ld should be able to resolve it appropriately in all addressing modes.
If there is a problem with ld it should definitely be reported, otherwise you'll be responsible for the bug remaining forever. There is a mailing list devoted to binutils (i.e. gas, ld, etc.) at binutils@sourceware.cygnus.com. Please also note that many problems with 16-bit code for i386 were fixed during the 2.9.4/2.9.5 development cycle and the 2.10 release should be available really soon. In particular all 16-bit and 8-bit relocations should be handled properly now, so that you may link 16-bit objects together and yield expected results (but you'll often need to write a customized ld script). You should also be able add appropriate operand and address size prefixes automatically using "w" and "l" suffixes and an appropriate format of memory references, now. If you find any instruction that diverges please do not hesitate reporting it.
Maciej
On Fri, 19 May 2000, Maciej W. Rozycki wrote:
On Wed, 17 May 2000, Ollie Lho wrote:
.byte 0x66 /* prefix */ .byte 0x26 .byte 0x0f, 0x01, 0x16 /* lgdt [es:offset]*/ .word 0x02 /* offset in segment */
Hmm, why would you encode lgdt manually? I can't recall gas handling it incorrectly and even if it did it would be gas that would need fixing. AFAIR, the "lgdtl %es:2" instruction yields exactly the same bytes as you emit explicitly above.
including the 0x66?
anyway I'm more than happy to change this code, but I was having GAS pains :-). I like your fix though.
Seriously, though, don't forget that this code doesn't change after this point as far as I am concerned. The real effort at this point is in the C code.
But thanks for the tip!
ron
- To unsubscribe: send mail to majordomo@freiburg.linux.de with 'unsubscribe openbios' in the body of the message
On Sat, 20 May 2000, Ronald G Minnich wrote:
Hmm, why would you encode lgdt manually? I can't recall gas handling it incorrectly and even if it did it would be gas that would need fixing. AFAIR, the "lgdtl %es:2" instruction yields exactly the same bytes as you emit explicitly above.
including the 0x66?
"lgdt" gives you a default argument size, with no prefix ever. "lgdtw" and "lgdtl" specify an explicit argument size, which implies an argument size override prefix if the chosen arument size disagrees with the current .code16/.code32 mode. It's much like "mov" vs "movw" and "movl" and like all other instructions.
Yes, I know "lgdtl" actually works differently than "lgdtw" as the latter one masks the most significant byte out of GDT's base and always treats it as 0x00 due to the 80286 compatibility (where "sgdt" would store it as 0xff and "lgdt" ignore, due to the lack of address lines, mostly).
anyway I'm more than happy to change this code, but I was having GAS pains :-). I like your fix though.
It's actually quite straightforward once you get it. Version 2.9.1 has plenty of bugs in the 16-bit area, though, so be sure to use at least 2.9.5. Version 2.10 should be out soon.
Seriously, though, don't forget that this code doesn't change after this point as far as I am concerned. The real effort at this point is in the C code.
I just noticed a hand-coded assembly and was curious whether there is really something wrong with binutils here.
But thanks for the tip!
You're welcomed.