I wrote a kernel to print hello world. but it's not working, hello world is not printed. assembly print is working well.
I using GCC and NASM for cross compile and assemble.
This is the my bootloader, second stage code and C code.
[ORG 0x00]
[BITS 16]
section .text
JMP 0x07C0:START ;
START:
mov ax, cs
mov ds, ax
mov es, ax
mov ax, 0x0000
mov ss, ax
mov ax, 0xffff
mov sp, ax
mov bp, ax
mov si, 0xB800
mov es, si
mov bx, 0x0000
mov cx, 80*25*2
CLEAR: ;Clear screen
mov byte[es:bx], 0x00
inc bx
loop CLEAR
READ: ;Read disk
mov si, 0x1000
mov es, si
mov bx, 0x0000 ; ES:BX, 0x1000:0000
mov ah, 0x02
mov al, 2
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
int 0x13
jnc A20_ENABLE ; No Error -> jump to A20_ENABLE
READERROR: ;If failed to read disk,
jmp $
A20_ENABLE: ;Enable A20 GATE with BIOS
mov ax, 0x2401
int 0x15
jnc ENTRY
A20_FAIL: ;If BIOS Interrupt is not working, use Control Port.
mov al, 2 ;
out 0x92, al
ENTRY: ;Entry Point
cli
lgdt [GDTR]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp $+2 ; for pipeline
nop
nop
jmp dword 0x08:0x10000 ; jump to second stage
GDTR: ; GDT
dw GDTEND - GDT - 1
dd GDT+0x7C00
GDT:
NULL:
dw 0x00 ;프로세서 예약구간
dw 0x00
db 0x00
db 0x00
db 0x00
db 0x00
CODE:
dw 0xFFFF ;LIMIT ADRESS
dw 0x0000 ;BASE ADRESS
db 0x00 ;BASE ADRESS
db 0x9A ;1001 1010 A code segment descriptor (for your kernel, it should have type=0x9A)
db 0xCF ;1100 1111
db 0x00
DATA:
dw 0xFFFF
dw 0x0000
db 0x01
db 0x92 ;1001 0010 A data segment descriptor (you cant write to a code segment, so add this with type=0x92)
db 0xCF ;1100 1111
db 0x00
VIDEO:
dw 0xFFFF
dw 0x8000
db 0x0B
db 0x92
db 0x40
db 0x00
GDTEND:
times 510 - ($-$$) db 0x00
db 0x55
db 0xAA
Second stage.
[ORG 0x10000]
[BITS 32]
PROTECTED:
mov ax, 0x10
mov gs, ax
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
xor esp, esp ; make stack
mov esp, 0xFFFE
mov ebp, 0xFFFE
mov si, 0x18 ; setting for print message
mov es, si
mov bx, 0
lea si, [message]
mov ah, 0x0f
MESSAGE: ; print loop
lodsb
cmp al, 0
je LOADKERNEL
mov [es:bx], ax
add bx, 2
jmp MESSAGE
LOADKERNEL:
jmp dword 0x08:0x10200 ; jump to C kernel
message: db 'Protected Mode Entered.', 0
times 512 - ($ - $$) db 0x00
and C code also.
void write_string();
void main(){
write_string(0x09, "helloworld");
}
void write_string( int colour, const char *string )
{
volatile char *video = (volatile char*)0xB8000;
while( *string != 0 )
{
*video++ = *string++;
*video++ = colour;
}
}
I converted C code to assembly with ld, gcc and objcopy.
gcc -c -m32 -ffreestanding kernel.c -o kernel.o
ld -melf_i386 -Ttext 0x10200 -nostdlib kernel.o -o kernel.tmp
objcopy -O binary kernel.tmp kernel.img
cat bootloader.img secondstage.img kernel.img > Disk
like this.
I really can't understand why it's not working.
If you need more information, plz leave a comment.