BIOS int 0x13 modifies CS:IP?

陌路散爱 提交于 2021-02-10 15:46:55

问题


I'm writing an x86 bootloader which occupies two sections (1024 bytes) on disk and the first thing I want it to do is to load both sections to segment 0x60 before continuing execution

Here is the relocation part of my code:

_start:
  // relocate and load remaining bootloader code    
  mov $0x60, %ax
  mov %ax, %es

  mov $0x02, %ah
  mov $2, %al
  xor %bx, %bx
  mov $0, %ch
  mov $2, %cl
  xor %dh, %dh

  int $0x13

  jmp $0x60, $reloc_done

reloc_done:
  // set up segment registers
  mov $0x60, %ax
  mov %ax, %ds
  mov %ax, %es

  // set up stack
  mov $0x8000, %bx
  mov %bx, %ss
  xor %ax, %ax
  mov %ax, %sp

This does not seem to work however, I have tried to debug my code with gdb by creating an ELF file boot.elf in addition to a flat binary and executing add-symbol-file boot.elf 0x60 followed by break reloc_done after attaching gdb to the qemu process running my binary. I would have expected a continue to then actually hit the breakpoint at 0x60:reloc_done but this doesn't happen. What's wrong here?

When I single step through this program, it looks like the int $0x13 actually modifies CS:IP to F000:E3FE which I do not understand at all.

EDIT: A minimal example trying to integrate some suggestions by MichaelPetch:

boot.S:

// real mode code
.code16

.global _start

jmp $0x0, $_start

_start:
  mov $0x8000, %ax
  mov %ax, %sp

  // relocate and load remaining bootloader code
  mov $0x60, %ax
  mov %ax, %es
  xor %bx, %bx

  mov $0x02, %ah
  mov $2, %al
  mov $0, %ch
  mov $1, %cl
  xor %dh, %dh

  int $0x13

  jmp $0x60, $reloc_done

reloc_done:
  nop

  // set up segment registers
  mov $0x60, %ax
  mov %ax, %ds
  mov %ax, %es

  // set up stack
  mov $0x8000, %bx
  mov %bx, %ss
  xor %ax, %ax
  mov %ax, %sp

boot.ld:

OUTPUT_FORMAT("elf32-i386");

ENTRY(_start);

SECTIONS
{
  . = 0x0;
  .text : {
      *(.text);
      . = 510;
      SHORT(0xAA55);
  }

  .data : SUBALIGN(2) {
      *(.data);
      *(.rodata*);
  }

  /DISCARD/ : {
      *(.eh_frame);
      *(.comment);
  }
}

Compiled like this:

gcc -m32 -fno-PIC -g -gdwarf -Wall -Werroro -c asm/boot.S -o out/boot_S.o
ld -melf_i386 -Tout/boot.ld out/boot_S.o -o ../elf/boot.elf
objcopy -O binary ../elf/boot.elf ../img/boot.img

boot.img is then copied to the first sector of a disk image. Now the initial instruction executed is not mov $0x60, %ax but something else entirely.

ANOTHER EDIT: I think I got it now, I had to change the link address in my linker script as suggested by MichaelPetch but then also remove the initial jmp $0x0, ... from my code which didn't make sense anymore.

来源:https://stackoverflow.com/questions/64987706/bios-int-0x13-modifies-csip

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!