问题
The wikipedia page for Reset vector says (for 386+ processors):
The value of the selector portion of the CS register at reset is F000h, the value of the base portion of the CS register is FFFF0000h, and the value of the IP register at reset is FFF0h to form the segmented address FFFFF000h:FFF0h in real mode.
All my reading on computer boot up has said that the processor starts in real mode, and hence "selectors" should not come into picture. Then why the mention here ? Also, what is the "base portion" being referred to here, and in which register is it stored ? Basically, I don't understand how the reset vector is set differently for 386 processors versus the previous ones.
回答1:
Yes, after power-up, all x86 CPUs are in Real Mode but with a strange behaviour until a CS assignment is found!!!.
Being finished reading some x86 documentation, these are the facts:
After power-up, 'CS register', 'CS cache register' and 'EIP' initial values are:
CS= F000h (16 bits wide as it should always be!)
CS_segment_start_address= FFFF_0000h (a 32 bits value, pointing somewhere in RAM?). CS_segment_lenght= 0_FFFFh (a 20 bits size value, yes, this is 64KB).
CS_segment is 'Present' in memory.
CS_segment is a 'Read/Write' chunk.
CS_segment has been 'Accesed'.
EIP= 0000_FFF0h
Now, take note of the following fact of life.
==SOF== (Start of Fact)
When fetching a new instruction (being in whatever mode: real, protected, etc) it seems that the hardware addressing logic is always using some 'CS cache register' values to figure out what address to place on the Address Bus pins. Specifically:
Next_Instruction_Address_on_Bus= CS_segment_start_address + EIP
==EOF== (End of Fact)
So, after power-up we have these numbers:
Next_Instruction_Address_on_Bus= FFFF_0000h + 0000_FFF0h= FFFF_FFF0h
This means, do we have access to the last corner of RAM after power-up, far away from the 1MB limit? Yes!!!. Holy grial!!!.
But wait, don't run and jump yet!!! This is just intended to place (by the software developer) a 'far jump' to some code chunk which it will be located in the BIOS ROM area hopefully!.
However, it is the motherboard who ensures that the instruction at the reset vector (0xFFFFFFF0h) is a far jump to the memory location mapped to the system BIOS entry point (0x0000: 0x000F0000h). In summary, every 'motherboard' has implemented this 'jump hack'. [Thanx Gustavo Duarte for this explanation. Check his smart blog: http://duartes.org/gustavo/blog/post/how-computers-boot-up/]
Following the explanation from above, that last 'far jump' mentioned is what it will update the 'CS_segment_start_address' with a well behaved 'Real Mode' value:
An assignment like CS= XYWZh (done with a far 'jump', far 'call' or any other) is translated to:
CS_segment_star_address= 000X_YZW0h (where XYZW are the CS nibbles values)
Back again in bussiness as usual with the 4 bits left-shift, 1MB limit, 64KB segments length cr..p!!!
A final few words, I guess this behaviour is to assure that your power-up (boot?) code will always be at the last corner of RAM. That way it will leave alone plenty of RAM for future OS disposal. [Honestly, for me, it will make more sense to have placed this 'Reset' vector within the 'Interrupt Vector Table' @ vector #0].
Please, correct me if I am wrong. Hope this helps.
PD: What is CS cache register? Well, it is the descriptor values associated with a CS selector in use. All other segments have this 'cache register' values too for fast accessing. And remember, on x86 CPUs you can not disable 'segmentation' at will. You have to deal with it. Read some 'Protected Mode' involving segmentation to know more... Unfortunately (or fortunately?) segmentation is gone and obsolete. Paging has succeded as a protection mechanism instead.
By the way, some Wikipedia articles seem to be edited with bad logic. Be careful about it!!!
回答2:
The address that needs to be accessed is the last 16 bytes of memory as that is where the reset vector is stored.
The reason that the values for CS are different is because of the differences between 8086/80186 and 80286+ processors. On the 80286 processors and above, there exists a Global Descriptor Table (GDT) which specifies how memory is accessed and utilized on the system. The 8086 did not have a GDT and thus memory access was essentially fixed. Even in real mode on a 286+ there exists GDT entries.
The base and selector values you refer to are just the base and selector portions of a GDT entry.
Therefore, the reset vector is set differently due to the fact that GDT entries exist and have effects on 286+ processors in all processor modes. On a freshly booted system, the following segment:offset values are used:
8086/80186 (16-bit): 0xFFFF:0x0000
80286 (16-bit): 0xF000:0xFFF0
80386+ (32-bit): 0xFFFFF000:0xFFF0
(64-bit): 0xFFFFFFFFFFFFF000:0xFFF0
Essentially, on 80286 and higher processors the offset and segment values are the same except for the segment value being sign-extended on 32 and 64 bit processors.
来源:https://stackoverflow.com/questions/23422594/reset-vector-in-386-processors