Why qemu always resets ?
Posted: Sat May 03, 2014 2:10 am
Hi, I read here these wonderful lessons (http://www.osdever.net/tutorials/view/mixing-assembly-c) and trying to write a bootloader. I'm doing everything exactly as written on the lesson, but qemu always resets ... and i do not understand why ? Here my asm code.
Bochs do not work in my ubuntu and I tried to debug the code using simply "prints", f.e.
I've done here is a file to compile and run.
When qemu starts with our boot image, the screen displays "AB" and it always blinks, seems the boot image always tries resets. Please help me solve this problem.
Code: Select all
[BITS 16] ; We need 16-bit intructions for Real mode
[ORG 0x7C00] ; The BIOS loads the boot sector into memory location 0x7C00
drive db 0
jmp word load
load:
jmp reset_drive
jmp enter_pm
reset_drive:
mov ah, 0Eh ; We want to print a single character
mov al, 'A' ; That character is 'A'
mov bh, 0Eh ; White text on black background, not blinking
mov bl, 0 ; Page number 0
int 10h
mov ah, 0 ; RESET-command
int 13h ; Call interrupt 13h
mov [drive], dl
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
mov ax, 0
mov es, ax
mov bx, 0x1000 ; Destination address = 0000:1000
mov ah, 0Eh ; We want to print a single character
mov al, 'B' ; That character is 'A'
mov bh, 0Eh ; White text on black background, not blinking
mov bl, 0 ; Page number 0
int 10h
mov ah, 02h ; READ SECTOR-command
mov al, 02h ; Number of sectors to read = 1
mov dl, [drive]
mov ch, 0 ; Cylinder = 0
mov cl, 2 ; Sector = 2
mov dh, 0 ; Head = 0
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz load ; Try again if ah != 0
; jc reset_drive
cli ; Disable interrupts, we want to be alone
enter_pm:
xor ax, ax
mov ds, ax ; Set DS-register to 0 - used by lgdt
lgdt [gdt_desc] ; Load the GDT descriptor
mov eax, cr0 ; Copy the contents of CR0 into EAX
or eax, 1 ; Set bit 0
mov cr0, eax ; Copy the contents of EAX into CR0
jmp 08h:clear_pipe ; Jump to code segment, offset clear_pipe
[BITS 32] ; We now need 32-bit instructions
clear_pipe:
mov ax, 10h ; Save data segment identifyer
mov ds, ax ; Move a valid data segment into the data segment register
mov ss, ax ; Move a valid data segment into the stack segment register
mov esp, 090000h ; Move the stack pointer to 090000h
jmp 08h:01000h ; Jump to section 08h (code), offset 01000h
gdt: ; Address for the GDT
gdt_null: ; Null Segment
dd 0
dd 0
gdt_code: ; Code segment, read/execute, nonconforming
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data: ; Data segment, read/write, expand down
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end: ; Used to calculate the size of the GDT
gdt_desc: ; The GDT descriptor
dw gdt_end - gdt - 1 ; Limit (size)
dd gdt ; Address of the GDT
times 510-($-$$) db 0 ; Fill up the file with zeros
dw 0xAA55 ; Boot sector identifyer
Code: Select all
mov ah, 0Eh
mov al, 'B'
mov bh, 0Eh
mov bl, 0
int 10h
Code: Select all
rm -rf *.o *.bin *.img
nasm -f bin bootsect.asm -o bootsect.bin
gcc -ffreestanding -c main.c -o main.o
gcc -c video.c -o video.o
gcc -c ports.c -o ports.o
ld -e main -Ttext 0x1000 -o kernel.o main.o video.o ports.o
ld -i -e main -Ttext 0x1000 -o kernel.o main.o video.o ports.o
objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin
./makeboot a.img bootsect.bin kernel.bin
echo " Running OS... ! "
qemu-system-i386 -fda a.img -no-fd-bootchk