title: How to fix "qemu: fatal: Trying to execute code outside RAM or ROM at 0x000a0000"
body: <p>I'm developing my own bootloader + kernel. I create a project and placed it on github: <a href="https://github.com/rprata/ubootlua" rel="nofollow noreferrer">https://github.com/rprata/ubootlua</a> (branch tmp-libc-implemenation)</p>
  
  <p>I tried to run my boot.bin using QEMU:</p>
  
  <blockquote>
    <p>qemu-system-i386 -fda boot.bin -nographic -serial stdio -monitor none</p>
  </blockquote>
  
  <p>However a crash happens:</p>
  
  <pre><code>&gt; qemu-system-i386 -fda ./deploy/boot.bin -nographic -serial stdio -monitor none
  &gt; WARNING: Image format was not specified for './deploy/boot.bin' and probing guessed raw.
  &gt;         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
  &gt;         Specify the 'raw' format explicitly to remove the restrictions.
  &gt; qemu: fatal: Trying to execute code outside RAM or ROM at 0x000a0000
  &gt; 
  &gt; EAX=00000055 EBX=00018eb4 ECX=00018eb3 EDX=00000000
  ESI=00000001 EDI=00000000 EBP=00016058 ESP=00015f94
  EIP=0009ffae EFL=00000896 [-OS-AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0
  ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
  CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
  SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
  DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
  FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
  GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
  LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
  TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
  GDT=     00007c36 00000018
  IDT=     00000000 000003ff
  CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
  DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
  DR6=ffff0ff0 DR7=00000400
  CCS=00000055 CCD=000000d1 CCO=ADDB    
  EFER=0000000000000000
  FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
  FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
  FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
  FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
  FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
  XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
  XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
  XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
  XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
  &gt; makefile:26: recipe for target 'run' failed
  &gt; make: *** [run] Aborted (core dumped)
  </code></pre>
  
  <p>My boot.asm and linker.ld:</p>
  
  <pre><code>section .boot
  bits 16                     ; We're working at 16-bit mode here
  global boot
  
  boot:
      mov ax, 0x2401          
      int 0x15                ; Enable A20 bit 
  
      mov ax, 0x3             ; Set VGA text mode 3
      int 0x10                ; Otherwise, call interrupt for printing the char   
  
      mov [disk],dl
  
      mov ah, 0x2             ;read sectors
      mov al, 60              ;sectors to read
      mov ch, 0               ;cylinder idx
      mov dh, 0               ;head idx
      mov cl, 2               ;sector idx
      mov dl, [disk]          ;disk idx
      mov bx, copy_target     ;target pointer
      int 0x13
  
      cli                     ; Disable the interrupts
      lgdt [gdt_pointer]      ; Load the gdt table
      mov eax, cr0            ; Init swap cr0...
      or eax,0x1              ; Set the protected mode bit on special CPU reg cr0
      mov cr0, eax
      jmp CODE_SEG:boot32     ; Long jump to the code segment
  
  
  ; base a 32 bit value describing where the segment begins
  ; limit a 20 bit value describing where the segment ends, can be multiplied by 4096 if granularity = 1
  ; present must be 1 for the entry to be valid
  ; ring level an int between 0-3 indicating the kernel Ring Level
  ; direction:
  ;  &gt; 0 = segment grows up from base, 1 = segment grows down for a data segment
  ;  &gt; 0 = can only execute from ring level, 1 = prevent jumping to higher ring levels
  ; read/write if you can read/write to this segment
  ; accessed if the CPU has accessed this segment
  ; granularity 0 = limit is in 1 byte blocks, 1 = limit is multiples of 4KB blocks
  ; size 0 = 16 bit mode, 1 = 32 bit protected mode
  gdt_start:
      dq 0x0
  gdt_code:
      dw 0xFFFF
      dw 0x0
      db 0x0
      db 10011010b
      db 11001111b
      db 0x0
  gdt_data:
      dw 0xFFFF
      dw 0x0
      db 0x0
      db 10010010b
      db 11001111b
      db 0x0
  gdt_end:
  gdt_pointer:
      dw gdt_end - gdt_start
      dd gdt_start
  disk:
      db 0x0
  
  CODE_SEG equ gdt_code - gdt_start
  DATA_SEG equ gdt_data - gdt_start
  
  ;; Magic numbers
  times 510 - ($ - $$) db 0
  
  dw 0xaa55
  copy_target:
  bits 32
      msg:    db "Hello, World more than 512 bytes!", 0
  
  boot32:
      mov ax, DATA_SEG
      mov ds, ax
      mov es, ax
      mov fs, ax
      mov gs, ax
      mov ss, ax  
      ;mov esi, msg            ; SI now points to our message
      ;mov ebx, 0xb8000       ; vga memory position (0) 
  
  .loop   lodsb               ; Loads SI into AL and increments SI [next char]
      or al, al               ; Checks if the end of the string
      jz halt                 ; Jump to halt if the end
      or eax,0x0200           ; The top byte defines the character colour in the buffer as an int value from 0-15 with 0 = black, 1 = blue and 15 = white. 
                              ; The bottom byte defines an ASCII code point
      mov word [ebx], ax      
      add ebx, 2              
      jmp .loop               ; Next iteration of the loop
  
  halt:   
      mov esp, kernel_stack_top
      extern __start
      call __start
      cli
      hlt                     ; CPU command to halt the execution
  
  section .bss
  align 4
  kernel_stack_bottom: equ $
      resb 16384 ; 16 KB
  kernel_stack_top:
  </code></pre>
  
  <pre><code>
      ENTRY(boot)
      OUTPUT_FORMAT("binary")
      SECTIONS {
          . = 0x7c00;
          .text :
          {
              *(.boot)
              *(.text)
          }
  
          .rodata :
          {
              *(.rodata)
          }
  
          .data :
          {
              *(.data)
          }
  
          .bss :
          {
              *(.bss)
          }
      }
  </code></pre>
  
  <p>The relevant part of my makefile is:</p>
  
  <pre><code>NASM:=nasm
  CC:=gcc
  SRC_NASM:=./src/init/boot.asm
  SRC_C:=./src/init/boot.c ./src/init/init.c ./src/init/version.c
  LINKER:=./src/init/linker.ld
  DEPLOY=./deploy
  BUILD:=./build
  BIN:=$(DEPLOY)/boot.bin
  OBJ_NASM:=$(BUILD)/boot.o
  CFLAGS:=-Wall -Werror -m32 -fno-pie -ffreestanding -mno-red-zone -fno-exceptions -nostdlib -I./src/include
  LDFLAGS:=
  
  export ARCH:=i386
  export ZLIB_SUPPORT:=false
  
  DEPENDENCIES:=libc
  ifeq ($(ZLIB_SUPPORT),true)
  DEPENDENCIES:=$(DEPENDENCIES) zlib
  endif
  
  all: $(DEPENDENCIES)
      mkdir -p $(DEPLOY)
      mkdir -p $(BUILD)
      $(NASM) $(SRC_NASM) -f elf32 -o $(OBJ_NASM)
      $(CC) $(SRC_C) $(OBJ_NASM) -o $(BIN) $(CFLAGS) -T $(LINKER) $(LDFLAGS)
  
  run:
      qemu-system-i386 -fda $(BIN) -nographic -serial stdio -monitor none
  </code></pre>
  
  <p>Why is it failing this way and how can I fix it?</p>