Using QEMU to read incomplete kernel. img data

49 Views Asked by At

I use QEMU to run my bootloader program. In bootloader, I read the sysloader and kernel data into the 0x8000 location

bootloader.S:

#include "realmode_def.h"
#This code reads 25 sectors of the image file, prints a string, and jumps to 0x8000
.code16
.text  
ljmp    $BOOTSEG, $_start

_start:
    mov $0, %ax     
    mov %ax, %ds
    mov %ax, %es
    mov $STACK_BASE, %ax             #STACK_BASE 0x070b
    mov %ax, %ss
    mov $0x00ff, %sp
#
hd_load_setup:
    mov $0x1f2, %dx
    mov $SETUP_SECTIORS_LEN, %ax     #SETUP_SECTIORS_LEN  25
    out %al, %dx        

    mov $0x1f3, %dx
    mov $START_SECTORS_BASE, %eax    #START_SECTORS_BASE   1
    out %al, %dx

    mov $8, %cx
    shr %cl, %eax
    mov $0x1f4, %dx
    out %al, %dx

    shr %cl, %eax
    mov $0x1f5, %dx
    out %al, %dx
    
    shr %cl, %eax
        and $0x0f, %al          
        or  $0xe0, %al          
        mov $0x1f6, %dx
        out %al, %dx
    
        mov $0x1f7, %dx
        mov $0x20, %al                        
        out %al, %dx
    
not_ready:
    
    in %dx, %al         
    and $0x88, %al      
    cmp $0x08, %al
    jnz not_ready       

    mov $SETUP_SECTIORS_LEN, %ax
    mov $256, %dx
    mul %dx
    mov %ax, %cx       

    mov $0x1f0, %dx
    mov $SETUP_LOAD, %bx      #SETUP_LOAD  0x8000
go_on_read:
    in %dx, %ax
    mov %ax, (%bx)
    add $2, %bx       
    loop go_on_read
      
      
load_system:
    call print_msg
    ljmp    $SETUP_SEG, $0    #SETUP_SEG 0x0800

print_msg:
    mov $0x07c0, %ax
    mov %ax, %es
    mov $0x03, %ah      
    xor %bh, %bh
    int $0x10
    mov $23, %cx
    mov $0x0007, %bx        
    mov $msg1, %bp
    mov $0x1301, %ax        
    int $0x10
    ret

msg1:
    .byte 13,10
    .ascii "OS is booting ..."
    .byte 13,10,13,10

_end:
    .org  510
    .word 0xAA55

Makefile:

CC  = gcc 
AS  = as --32
LD  = ld
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -ggdb -m32 -fno-omit-frame-pointer -fno-stack-protector -fstrength-reduce
LDFLAGS = -m elf_i386 -T kernel.ld 
OBJCOPY = objcopy
STRIP = strip
AR  = ar

bootloader:bootblock sysloader main make_kernel
    
bootblock:
    @$(CC) $(CFLAGS)  -O -nostdinc -I. -c bootloader_hd.S
    @$(LD) $(LDFLAGS) -o bootloader -Ttext 0 bootloader_hd.o
    @$(OBJCOPY) -R .pdr -R .comment -R.note -S -O binary bootloader 

sysloader:
    @$(CC) $(CFLAGS) -O -nostdinc -I. -c sysloader.S
    @$(LD) $(LDFLAGS) -o sysloader -Ttext 0x8000 sysloader.o    
    @$(OBJCOPY) -R .pdr -R .comment -R.note -S -O binary sysloader  

main:
    @$(CC) $(CFLAGS) -c main.c -o main.o 
    @$(LD) $(LDFLAGS)  -o kernel_img main.o
    
make_kernel: 
    @dd if=/dev/zero of=kernel.img bs=512 count=10000
    @dd if=bootloader of=kernel.img bs=512 count=1 conv=notrunc
    @dd if=sysloader seek=1 of=kernel.img conv=notrunc
    @dd if=kernel_img of=kernel.img seek=4 conv=notrunc

I run my kernel.img using the following command

qemu-system-x86_64 -drive file=kernel.img,index=0,media=disk,format=raw -s -S

I track and debug in GDB, and after running the last instruction of the bootloader, I check its memory data at 0x8000

0x8000: 0x8ec031fa  0xe4c08ed8  0xe6020c92  0x16010f92
0x8010: 0x200f810c  0xc88366c0  0xc0220f01  0x088021ea
0x8020: 0x10b86600  0x8ed88e00  0x66d08ec0  0x8e0000b8
0x8030: 0xb9e88ee0  0x00000400  0x001000b8  0x0000c700
0x8040: 0x83000000  0xf5e204c0  0x001000b8  0x10000500
0x8050: 0xc3890000  0xa307c883  0x00001000  0x001c00a3
0x8060: 0x0400b900  0x00be0000  0xba000000  0x00000007
0x8070: 0x89b33c8d  0x00c28117  0x46000010  0x00b8f2e2
0x8080: 0x0f000010  0x200fd822  0x00000dc0  0x220f8001
0x8090: 0x7bffbcc0  0xc0310000  0xc931db31  0x00b8d231
0x80a0: 0x66000088  0x8b2a508b  0xc3811c58  0x00008800
0x80b0: 0x2c488b66  0x003c038b  0x73ff1774  0x04438b10
0x80c0: 0x00880005  0x73ff5000  0x0011e808  0xc4830000
0x80d0: 0xe2d3010c  0x8800bbdf  0x438b0000  0xfce0ff18
0x80e0: 0x51e58955  0x8b087d8b  0x4d8b0c75  0x59a4f310
0x80f0: 0x9066c35d  0x00000000  0x00000000  0x0000ffff
0x8100: 0x00cf9a00  0x0000ffff  0x00cf9200  0x80f40017
0x8110: 0x00000000  0x00000000  0x00000000  0x00000000
0x8120: 0x00000000  0x00000000  0x00000000  0x00000000
...
0x8600: 0x00000000  0x00000000  0x00000000  0x00000000
0x8610: 0x00000000  0x00000000  0x00000000  0x00000000
0x8620: 0x00000000  0x00000000  0x00000000  0x00000000
0x8630: 0x00000000  0x00000000  0x00000000  0x00000000

I found that the sysloader was loaded to 0x8000, but the data in the elf section after it was not correctly loaded to 0x8600, and all subsequent data is 0

Use xxd to view the data distribution of kernel.img:

00000000: ea05 00c0 07b8 0000 8ed8 8ec0 8ee8 b8b0  ................
...
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

00000200: fa31 c08e d88e c0e4 920c 02e6 920f 0116  .1..............
00000210: 0c81 0f20 c066 83c8 010f 22c0 ea21 8008  ... .f...."..!..
...
000007f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000800: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
...
00001800: 5589 e5fa fb31 c05d c371 0000 0004 0000  U....1.].q......
...                                                                                      

When I ran it in Bochs, it correctly loaded the data of kernel.img into memory

0x0000000000008600 <bogus+    1536>:    0x464c457f      0x00010101      0x00000000      0x00000000
0x0000000000008610 <bogus+    1552>:    0x00030002      0x00000001      0xc0100000      0x00000034
0x0000000000008620 <bogus+    1568>:    0x0000136c      0x00000000      0x00200034      0x00280002
0x0000000000008630 <bogus+    1584>:    0x0009000c      0x00000001      0x00001000      0xc0100000
0x0000000000008640 <bogus+    1600>:    0x00100000      0x00000009      0x00000009      0x00000005
0x0000000000008650 <bogus+    1616>:    0x00001000      0x6474e551      0x00000000      0x00000000
...
0x0000000000009600 <bogus+    5632>:    0xfae58955      0x5dc031fb      0x000071c3      0x00000400
0x0000000000009610 <bogus+    5648>:    0x04000000      0x00000c01      0x00050c00      0x00a50000
0x0000000000009620 <bogus+    5664>:    0x00000000      0x00000000      0x00000000      0x73020000
0x0000000000009630 <bogus+    5680>:    0x01006974      0x63020307      0x0100696c      0x00030302
...

I want to know how to use QEMU correctly to run kernel.img

0

There are 0 best solutions below