Why do the bytes "0xea 0000 ffff" in a bootloader cause the computer to reboot?
Asked Answered
I

2

3

I was researching boot loaders and I found this interesting piece of assembly:

;Sends us to the end of the memory
;causing reboot
db 0x0ea
dw 0x0000
dw 0xffff

By the comment I know what it does; sends the computer to the end of memory, but what I can't figure out is how those numbers reboot the computer (x86_64 processor on 16-bit mode).

Insurrectionary answered 8/7, 2015 at 14:58 Comment(1)
On Linux kernel 4.2: github.com/torvalds/linux/blob/v4.2/arch/x86/realmode/rm/…Mckeehan
H
3

Those bytes correspond to jmp word 0xffff:0000 (you can see this by assembling with NASM and then disassembling the resulting binary), which happens to be a jump to the x86 reset vector in real mode.

Howitzer answered 8/7, 2015 at 15:3 Comment(3)
So I guess this is just someone trying to be tricky then. Would you think it'd be more clear if I just replaced those lines with jmp word 0xffff:0000?Insurrectionary
It would certainly be clearer. Note that the exact syntax of that jump instruction would depend on which assembler you use.Howitzer
@TheTromboneWilly The person who used the DB/DW directives probably just didn't know how to write a 16-bit far jump instruction using his assembler. The syntax can be a bit tricky.Consociate
C
3

It's a far jump instruction to the old 8086 reset address. When the 8086 was reset it would start executing instructions at FFFF:0000. For compatibility reasons modern BIOS implementation have a jump to their reset code here, though reset address of modern CPUs is different.

Consociate answered 8/7, 2015 at 15:3 Comment(15)
The reset address still works on my 2014 macbook pro though and I would consider that pretty modern ;)Insurrectionary
@TheTromboneWilly Yes, as I said, modern BIOS implementations support this for backwards compatibility. However the CPU actually begins executing instructions at FFFF000:FFF0 after a reset.Consociate
Does it begin in protected mode?Insurrectionary
@TheTromboneWilly When the CPU is reset (including at power on) is begins executing BIOS code in real mode (the reset address isn't a valid a real-mode address, but it works anyway). The BIOS code initializes the hardware, does a self test and then looks for something to boot. When it finds your boot loader it loads it in to memory at 0000:7C00 and jumps to it.Consociate
I know that, but you said modern CPUs begin executing instructions at FFFF000:FFF0. When does it begin doing that?Insurrectionary
@TheTromboneWilly When the CPU is reset it begins executing instructions at FFFF000:FFF0.Consociate
@TheTromboneWilly: From the page I linked to in my answer: "The reset vector for the 80386 and later x86 processors is physical linear address FFFFFFF0h. 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."Howitzer
@RossRidge Would you have to reset it from the bootloader?Insurrectionary
I think you two are talking at cross purposes and not understanding one another (though I could be wrong). The reset vector is where the CPU will begin reading and executing instructions from when it is powered on and/or reset. The standard used in X86 and X86_64 PCs is that the BIOS, after performing whatever setup and testing it needs, will load the boot sector of the boot drive at 0000:7c00 and jmp there.Hiss
@DavidHoelzer Where does the CPU execute instructions after the bootloader has finished?Insurrectionary
@TheTromboneWilly Where ever you tell it to. Normally the bootloader is part of the process of starting an operating system, so the bootloader loads the OS into memory and then jumps to the start of the OS. A bootloader can't just finish, it needs to jump to some other code when it's done whatever it supposed to do. Either that or run in a infinite loop and never finish. The JMP FFFF:0000 instruction you saw ends the bootloader by jumping back to the BIOS. That causes the BIOS to act as if the CPU was reset, just like you had turned the computer off and then on again.Consociate
@RossRidge I think we had a misunderstanding at the beginning, but I think I know what happens now. The CPU starts executing at FFFFF000h:FFF0h, which the motherboard makes sure that there's a jmp instruction to the BIOS code at that address, then BIOD loads the bootloader.Insurrectionary
Correct. Reset vector will point to BIOS (processor starts there) and BIOS will load and execute boot sector.Hiss
@DavidHoelzer Yeah that's I was getting mixed up. I thought that Ross Ridge meant the CPU executed at 0xFFFFFFF0 after the bootloader and I was bamboozled .Insurrectionary
@DavidHoelzer and Ross Ridge, you both get gold stars for being so patientInsurrectionary
H
3

Those bytes correspond to jmp word 0xffff:0000 (you can see this by assembling with NASM and then disassembling the resulting binary), which happens to be a jump to the x86 reset vector in real mode.

Howitzer answered 8/7, 2015 at 15:3 Comment(3)
So I guess this is just someone trying to be tricky then. Would you think it'd be more clear if I just replaced those lines with jmp word 0xffff:0000?Insurrectionary
It would certainly be clearer. Note that the exact syntax of that jump instruction would depend on which assembler you use.Howitzer
@TheTromboneWilly The person who used the DB/DW directives probably just didn't know how to write a 16-bit far jump instruction using his assembler. The syntax can be a bit tricky.Consociate

© 2022 - 2024 — McMap. All rights reserved.