x86bootreal-mode

Reset vector in 386+ processors


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.


Solution

  • 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'. [Gustavo Duarte has a good 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= XYZWh (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!!!