Bootloader funciona en emuladores pero no en hardware real

Estoy escribiendo un gestor de arranque en ensamblaje y parece funcionar bien en qemu, bochs y virtualbox. Sin embargo, no está cargando el kernel en hardware real (parece).

El gestor de arranque comienza escribiendo un carácter en la memoria de video (para la depuración), luego lee el sector 2 de la unidad y salta al núcleo. El núcleo está escribiendo algunos caracteres en la memoria de video.

En una máquina real, veo el personaje del gestor de arranque en la pantalla, y allí se cuelga (intermitente).

He intentado establecer DS, ES, SI en cero, y también estoy configurando un segmento de pila.

Estoy leyendo el sector 2 del disco usando la función bios int 13 2. Sospecho que tiene algo que ver con el número del disco. Ambos intenté usar el número de unidad pasado al gestor de arranque al inicio (en dl), y configurándolo manualmente a 0x0, 0x80 y 0x81.

Una cosa extraña que noté es que las etiquetas que uso para saltar cerca, mágicamente obtienen la dirección correcta. Usando objdump veo, por ejemplo: jmp 0x2, mientras uso gdb y qemu, dice: jmp 0x7c02. CS y todos los demás registros de segmento son cero. Ya sea que use -Ttext 0x0 o -Ttext 0x7c00 en el enlace, el gestor de arranque funciona bien en todos los emuladores. objdump dice jmp 0x7c02 cuando enlazo con -Ttext 0x7c00.

EDITAR, el gestor de arranque se ve así:

.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)

xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es

movw  $0x8000, %ax
movw  %ax, %ss
movw  $0, %sp

movb $2, %ah
movb $1, %al
movw $0x02, %cx
movb $0x00, %dh

movw $0x5000, %bx
movw %bx, %es
movw $0x0, %bx
int $0x13

ljmpw $0x5000, $0x0000

Editar, segunda etapa:

.code16
.text
    movw $0xb800, %ax
    movw %ax, %ds
    movw $0x0742, (0x2)

forever:
    jmp forever

Respuestas a la pregunta(1)

Su respuesta a la pregunta