ES segment register behaves unexpectedly
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
ES segment register behaves unexpectedly
In the Intel-manual, one can read that ES segment register is ignored in long mode.
What I have done is:
Enter in long mode in the boot loader, then used INSW instruction with inicial value in EDI 100000h.
Second stage loader load fine, executes fine and jumps work fine, but atempting to read data from above [100000h] memory returns all 0s. This confused me because the second stage loader resides there and work fine, so instructions are fetched. The paging consist at this point of a normal page entry of 2MB.
When I just had no more things to try, have set ES to 0 in the bootloader just before the primitive PIO ATA driver.(the driver worked alredy in long mode(I expected initially the INSW to use RDI))
Now, when setting ES to 0, all works fine.
What I have done is:
Enter in long mode in the boot loader, then used INSW instruction with inicial value in EDI 100000h.
Second stage loader load fine, executes fine and jumps work fine, but atempting to read data from above [100000h] memory returns all 0s. This confused me because the second stage loader resides there and work fine, so instructions are fetched. The paging consist at this point of a normal page entry of 2MB.
When I just had no more things to try, have set ES to 0 in the bootloader just before the primitive PIO ATA driver.(the driver worked alredy in long mode(I expected initially the INSW to use RDI))
Now, when setting ES to 0, all works fine.
Re: ES segment register behaves unexpectedly
Perhaps you're still in compatibility mode. When you follow the procedure to enter long mode, did you do a far jmp to your 64bit code segment after following all other steps ?
Until you do the far jmp you are still in 32 bit mode.
Code: Select all
ljmpl $0x8, $(code_seg_64)
.code64
code_seg_64:
If a trainstation is where trains stop, what is a workstation ?
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
I tested the long mode enabled bit and it's enabled. I will restore the system to previous state and then will try again. Lately I tend to consider virtualization software bugs and programer errors(mine) equally possible.
Re: ES segment register behaves unexpectedly
It's not enough. Even though the bit is set, you must also jump to a 64 bit code segment. Did you do that ?smoothCoder wrote:I tested the long mode enabled bit and it's enabled. I will restore the system to previous state and then will try again. Lately I tend to consider virtualization software bugs and programer errors(mine) equally possible.
If a trainstation is where trains stop, what is a workstation ?
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
pfffff...
This is very frustrating.
I have done the far-jump to the 64-bit code segment. But now with the system restored, independently of the value in the ES register I have the next problem:
here je and jne make the same jump to the same label.
Now I will revise the entire code, and hopefully I'll see it.
This is very frustrating.
I have done the far-jump to the 64-bit code segment. But now with the system restored, independently of the value in the ES register I have the next problem:
Code: Select all
cmp EAX, [EBX]
je jump_PCI_database_match
Now I will revise the entire code, and hopefully I'll see it.
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
Ok, definitively the problem was with the "rep insw" instruction. when I used the "rep insw" instruction, I needed to set the ES reg to 0 in order to can read the memory above 100000h(weird).
And the above code:
I replaced it with:
But the definitively solution for this problem was to use an simple kind of function in the place of "rep insw" instruction:
It seems that the "rep insw" instruction has broken the EDI reg completely.
And the above code:
Code: Select all
cmp EAX, [EDI] ;The truth is that I used EDI reg to reference memory
;here je and jne gives the same jump
Code: Select all
cmp EAX, [EBX] ;When no using EDI as mem ref, the code work fine
;here the jcc behaves as expected
Code: Select all
xor ECX, ECX
inc CH
read_one_sector:
in AX, DX
mov [EDI], AX
inc EDI
inc EDI
dec CX
jnz read_one_sector
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: ES segment register behaves unexpectedly
I thought you were writing 64 bit code: why are you using EDI to store pointers?
Re: ES segment register behaves unexpectedly
Have you ever run Windows or Linux on this processor? Surely if the processor were this broken you would know by now. I feel you haven't initialised the processor correctly. BTW, have you enabled a20 correctly ?It seems that the "rep insw" instruction has broken the EDI reg completely.
If a trainstation is where trains stop, what is a workstation ?
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
NickJohnson:
This is a mine custom I guess. Now the code is in development stage. Optimizations will take place when code it's working.
And yes, I never had problems on this machine executing OSes in the real hardware. But I have done a looot of tests and my previous post is exactly what I have got in virtualized environment.(tests about EDI, rep insw)
This is a mine custom I guess. Now the code is in development stage. Optimizations will take place when code it's working.
I rely on BIOS to do this for me. I really need to spare every byte in the boot loader(first stage/512 bytes).gerryg400 wrote:Have you ever run Windows or Linux on this processor? Surely if the processor were this broken you would know by now. I feel you haven't initialised the processor correctly. BTW, have you enabled a20 correctly ?It seems that the "rep insw" instruction has broken the EDI reg completely.
And yes, I never had problems on this machine executing OSes in the real hardware. But I have done a looot of tests and my previous post is exactly what I have got in virtualized environment.(tests about EDI, rep insw)
Re: ES segment register behaves unexpectedly
Which virtualised environment are you using ?
If a trainstation is where trains stop, what is a workstation ?
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
Microsoft Hypervisor. Earlier I often used it in networks training stuff and never disapointed me when used microsoft OSes.
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: ES segment register behaves unexpectedly
This is not an optimization: it's probably the source of your bug! EDI is a 32 bit register, so it should not (be attempted to) be used to store 64 bit pointer values. If you're truly in long mode, rep insw would be reading the upper 32 bits of RDI as well, which could be anything! Perhaps RDX just happened to be cleared, giving you the impression that EDI was "broken" and EBX was "not broken". Use RDI, or at least clear it before using EDI.smoothCoder wrote:NickJohnson:
This is a mine custom I guess. Now the code is in development stage. Optimizations will take place when code it's working.
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
Thanks!NickJohnson wrote:This is not an optimization: it's probably the source of your bug! EDI is a 32 bit register, so it should not (be attempted to) be used to store 64 bit pointer values. If you're truly in long mode, rep insw would be reading the upper 32 bits of RDI as well, which could be anything! Perhaps RDX just happened to be cleared, giving you the impression that EDI was "broken" and EBX was "not broken". Use RDI, or at least clear it before using EDI.smoothCoder wrote:NickJohnson:
This is a mine custom I guess. Now the code is in development stage. Optimizations will take place when code it's working.
When I code "mov EDI, 100000h", the upper 32 bits of the RDI are cleared automaticaly. And if I need an pointer to below the 4GB space, the only difference between "mov EAX, [EDI]" and "mov EAX, [RDI]" is one byte diference in the size of the opcode produced, and shorter code is better always. This is why I consider this as optimization stuff.
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: ES segment register behaves unexpectedly
I guess you're right: mov EDI does clear RDI as well, so that wouldn't cause a problem. Still, you want to avoid premature optimization like this.
-
- Member
- Posts: 43
- Joined: Sat Aug 28, 2010 10:32 pm
Re: ES segment register behaves unexpectedly
As long as my code do what I expect to do, I'm happy.
I guess latter I will try again to use "rep insw" because is shorter way to do the same. Now I load the e820 output to a known place, enter in long mode and load second stage. This leave me with only 15 bytes free place. There are more things I want to do in the 1 stage(512B) loader, so probably latter I will try to make "rep insw" to work correctly and to enter directly in long mode, this way I will spare two GDT entryes and a few lines of code to enter 32 bit mode. I tried to enter in long mode directly but not worked for me. But this latter, now I'm doing another stuff.
I guess latter I will try again to use "rep insw" because is shorter way to do the same. Now I load the e820 output to a known place, enter in long mode and load second stage. This leave me with only 15 bytes free place. There are more things I want to do in the 1 stage(512B) loader, so probably latter I will try to make "rep insw" to work correctly and to enter directly in long mode, this way I will spare two GDT entryes and a few lines of code to enter 32 bit mode. I tried to enter in long mode directly but not worked for me. But this latter, now I'm doing another stuff.