Isn't it 07C0: 0000, the same physical address on x86 machines as 0000: 7C00?

The reason for my question is that Starman seems to believe in the explanation of the author of GRUB Legacy (see the following inexplicable code:

7C4B EA507C0000 JMP 0000:7C50 ; Long Jump to the next instruction ; because some bogus BIOSes jump to ; 07C0:0000 instead of 0000:7C00. 

When I execute the Intel-specific algorithm for creating efficient addresses in the first memory link, I multiply 07C0: by 16 (in fact, its left shift is four bits or one nibble). Then I add the offset: 0000 and get the decimal address of 31,744.

If I left the shift, the segment of the second memory record is four bits, I still have 0000: and the offset: 7C00 still addresses 31,744. So my gut reaction is the author of this GRUB Legacy boot sector code that pulls our leg. Regardless of the shape of the memory link made by any BIOS, if the effective address is calculated to the decimal number 31 744, then there seems to be no problem that this long jump resolves.

Assuming that the author of the code simply expressed a fake physical memory location in a way that seems to be the same physical location that was correct, I began to think about how to handle the BIOS that sent the wrong address. A five-byte long jump does not seem to be the solution to anything. Five NOPs will fulfill the same goal (in fact, just starting the boot sector's initial code by five bytes and eliminating the long jump will have the same effect as Long Jump to the next command).

If the BIOS moves to the right place (7C00), no problem. If the BIOS moves to a position above 7C00, then no code loaded on the 7C00 can fix this problem. If the BIOS moves to a location between 7C00 and 7C4B, then the data stored in this area (or errors interpreted with missing bytes) will most likely cause a failure. If the BIOS jumps exactly to 7C4B, the TEST instruction will be rewritten (using Long Jump), and the JNZ - 7C54 will be executed based on the latest math performed in the BIOS.

For BIOS transitions below 7C4B, incorrect instructions again may cause a failure. With luck, part of the boot sector code will be executed. The results of this execution will depend on what exactly the "fictitious" memory address is loaded by the BIOS. So the author of this boot sector code extends our leg with a story about a "fake BIOS that goes to the wrong place"?

I note in Luke Luo BLOG that the boot sector of GRUB2, although different from the boot sector of GRUB Legacy, retains this inexplicable Long Jump . Therefore, if the original author of the GRUB Legacy boot sector made a joke on us, this is a pretty good joke (she survived a complete rewriting of GRUB). I was left with a choice, believing an incredible statement about some unnamed BIOS and solving a problem that seems to be doing virtually nothing or believing that the author of the original boot sector is joking with us.

Luke Luo seems to agree to write NOP instructions for the 7C66 and 7C67, indicating that he does not have a BIOS that jumps to the wrong place. The boot sector of GRUB2, which was recorded on my Linux Mint 13 flash drive, has the same NOP. However, the boot sector GRUB2, written on my laptop hard drive (Debian Etch), has a short jump to the next instruction written on 7C66 and 7C67 (note that Luke Luo shows us that the original boot sector, stored in / usr / lib / grub / i 386-pc / boot.img is Debian). Both alternatives have the same effect (they follow the instructions that follow them), so both boot sectors work. There will also be no such efficiency as I would expect in a boot sector, where only about 450 bytes are available for code that should load another sector and execute it (including error messages if something goes wrong with this simple operation and eight bytes address of the sector itself).

So, did I miss something, or did I define a kludge that should be removed from the GRUB boot sector (to make room for more meaningful code)?

+6
source share
1 answer

You are missing the difference in the actual state of the CPU (while the physical address is the same as the correct one).

When the BIOS runs JMP 0000:7C00 :

your first instruction is in cs=0000, ip=7C00 , and your machine code must be compiled for this kind of movement, whenever it does any absolute addressing, like mov ax,cs:[myTable] (then myTable can be something like 0x7F00 ).

When the BIOS runs JMP 07C0:0000 :

your first instruction is in cs=07C0, ip=0000 , so things like myTable will be more like 0x0300 .

Thus, the first long jump at the beginning of the code โ€œnormalizesโ€ the same physical address 31,744 to the expected form cs:ip , making the remaining absolute addresses in the bootloader code working correctly.

+6
source

Source: https://habr.com/ru/post/1013757/


All Articles