Reputation: 179
I am following these tutorial in os development link1 link2
I am not able to print in protected mode.
here is my code:
$ gcc -E boot.S
# 1 "boot.S"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "boot.S"
# 1 "header.h" 1
read_fail:
.asciz "Disk read failed"
.altmacro
.macro PUSHA
push %ax
push %bx
push %cx
push %dx
.endm
.macro POPA
pop %ax
pop %bx
pop %cx
pop %dx
.endm
.macro PUSH_EA
push %eax
push %ebx
push %ecx
push %edx
.endm
.macro POP_EA
pop %eax
pop %ebx
pop %ecx
pop %edx
.endm
.macro CLEAR
PUSH_EA
mov $0x0600, %ax
mov $0x07, %bh
mov $0x00, %cx
mov $0x184f, %dx
int $0x10
CURSOR_POS
POP_EA
.endm
.macro CURSOR_POS x=2, y=2
PUSH_EA
mov $0x02, %ah
mov $0x00, %bh
mov \x, %dh
mov \y, %dl
int $0x10
POP_EA
.endm
.macro BEGIN
.code16
_start:
xor %ax,%ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
mov %ax, %bp
mov %bp, %sp
.endm
.macro PRINT_STRING str
LOCAL loop,end
mov \str, %si
mov $0x0E, %ah
cld
loop:
lodsb
cmp $0x00, %al
je end
int $0x10
jmp loop
end:
.endm
.macro HEX_NIBBLE reg
LOCAL end, letter
cmp $10, \reg
jae letter
add $'0', \reg
jmp end
letter:
add $0x37, \reg
.endm
.macro HEX c
mov \c, %al
mov \c, %ah
shr $4, %al
HEX_NIBBLE <%al>
and $0x0F, %al
HEX_NIBBLE <%ah>
.endm
.macro PRINT_CHAR c=$0x20
push %ax
mov \c, %al
mov $0x0E, %ah
int $0x10
pop %ax
.endm
.macro PRINT_HEX reg=<%al>
push %ax
HEX <\reg>
PRINT_CHAR <%al>
PRINT_CHAR <%ah>
pop %ax
.endm
.macro RESET_DISK
LOCAL error,end
mov $0x00, %ah
mov $0x80, %dl
int $0x13
jmp end
end:
.endm
.macro STAGE2
LOCAL read_error, end
RESET_DISK
mov $__stage2_nsectors, %al
mov $0x9000, %ebp
mov %ebp, %esp
mov $0x02, %ah
mov $0x0002, %cx
mov $0x80, %dl
mov $0x00, %dh
mov $0x1000, %bx
int $0x13
jc read_error
jmp 1f
read_error:
PRINT_STRING $read_fail
.section .stage2
1:
jmp *(0x1000)
.endm
.macro PROTECTED_MODE
.equ CODE_SEG, 8
.equ DATA_SEG, gdt_data - gdt_start
cli
lgdt gdt_descriptor
mov %cr0, %eax
orl $0x01, %eax
mov %eax, %cr0
ljmp $CODE_SEG, $protected_mode
gdt_start:
gdt_null:
.long 0x00
.long 0x00
gdt_code:
.word 0xFFFF
.word 0x0000
.byte 0x00
.byte 0b10011010
# 220 "header.h"
.byte 0b11001111
# 230 "header.h"
.byte 0x00
gdt_data:
.word 0xffff
.word 0x00
.byte 0x00
.byte 0b10010010
.byte 0b11001111
.byte 0x00
gdt_end:
gdt_descriptor:
.word gdt_end - gdt_start
.long gdt_start
.code32
protected_mode:
mov $DATA_SEG, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
mov $0x9000, %ebp
mov %ebp, %esp
.endm
vga_current_line:
.long 0
.macro VGA_PRINT_STR str
LOCAL loop,end
PUSH_EA
mov \str, %ecx
mov vga_current_line, %eax
mov $0, %edx
mov $25, %ebx
div %ebx
mov %edx, %eax
mov $160, %edx
mul %edx
lea 0xb8000(%eax), %edx
mov $0x0f, %ah
loop:
mov (%ecx), %al
cmp $0, %al
je end
mov %ax, (%edx)
inc %ecx
addl $2, %edx
jmp loop
end:
POP_EA
incl vga_current_line
.endm
# 2 "boot.S" 2
.section .text
BEGIN
CLEAR
STAGE2
PROTECTED_MODE
VGA_PRINT_STR $str
jmp .
str:
.asciz "Hello"
Makefile
.POSIX:
IMAGE ?= $(FILENAME)
LD ?= ld
LD_SCRIPT ?= linker.ld
HEADER ?=header.h
GAS ?= gcc
CFLAGS ?= -c
QEMU ?= qemu-system-i386
OUT_EXT ?= .bin
all: $(IMAGE)$(OUT_EXT)
$(IMAGE).bin: $(IMAGE).o
$(LD) -T'$(LD_SCRIPT)' --oformat=binary '$<' -o '$@'
$(IMAGE).o : $(IMAGE).S $(HEADER)
$(GAS) -c '$<' -o '$@'
run: $(IMAGE)$(OUT_EXT)
$(QEMU) '$<'
clean:
rm *.o *bin
linker.ld
OUTPUT_FORMAT("elf32_i386");
SECTIONS
{
. = 0x7c00;
.text : {
__start = .;
*(.text)
. = 0x1FE;
SHORT(0xaa55);
*(.stage2 )
__stage2_nsectors = ABSOLUTE((. - __start)/512);
. = ALIGN(512);
__end = . ;
__end_align_4k = ALIGN(4K);
}
}
I am using qemu as an emulator. In Qemu, "Hello" should have been displayed, but this is the output.
I am unable to resolve this issue. Any pointers on this issue is appreciated.
Upvotes: 1
Views: 214
Reputation: 126526
Probably not your only problem, but your POP_EA
will pop things in the reverse order from your PUSH_EA
macro (the stack is last-in first-out), so will not match up:
.macro PUSH_EA
push %eax
push %ebx
push %ecx
push %edx
.endm
.macro POP_EA
pop %eax
pop %ebx
pop %ecx
pop %edx
.endm
since the last thing pushed is %edx and the first pop is %eax, you end up swapping them. The pop needs to be in the reverse order:
.macro POP_EA
pop %edx
pop %ecx
pop %ebx
pop %eax
.endm
Upvotes: 1