hello,
well , i am a novice in os developement. i 've written a sample kernel & a bootloader. i used nasm(0.98),ld &gcc. i use win98. The files are :
boot.asm : boot loader for booting from 1.44 floppy.
i assembled it with
nasm -f bin -o boot.bin boot.asm
ka16.asm : 16 bit part of kernel
nasm -f bin -o ka16.bin ka16.asm
ka32.asm : 32 bit part of kernel
nasm -f coff -o ka32.o ka32.asm
kernel.c : sample function kmain() that just display "** " on screen
gcc -c kernel.c -o kernel.o -O2 -nostdlib -fno-builtin -Wall
i included 'ka16.bin' in 'ka32.asm' because coff format do not allow to combine 16 bit & 32 bit code.
then i linked ka32.o & kernel.o as below :
ld -Ttext 0x000600 --oformat binary -o ka32.bin ka32.o kernel.o
ka32.bin is 4kb. i copied it on fdd sector 1,2,3,4 using 'bootw' utility.
i copied boot.bin on sector 0.
when i tried to boot from this bootloader it restarts after displaying the message in ka16.bin...
i placed a 'jmp $ ' instruction before 'jmp dword 8:_go32' instruction in ka32.asm & after 'incbin ka16.bin' instruction. now it hangs instead of restarting . this means that it restarts when i do far jump for the first time when i enter protected mode.
i 'm struck with this problem.
can anybody please help me....
here is the whole code :
file : boot.asm
[BITS 16]
[ORG 0x7c00]
;code ~~~~~~~~~~~~~~~~~~~~~~~~~
start:
mov ax,cs
mov ds,ax
mov ss,ax
mov sp,0xfffe
mov si,msg
call display
call load_image
mov ax, 0x0060
mov ds, ax
jmp 0x0060:0x0000
; jmp $
; display routin ~~~~~~~~~~~~~~
display:
push ax
push bx
mov ah, 0x0E ;Teletype Mode
mov bh, 0x00 ;Page Number
.nextchar:
lodsb ;Load [si] into al and
;increment si
or al, al ;Set the Zero Flag if al = 0
jz .return ;If the Zero Flag is set, jump
;to Break
int 0x10 ;Call BIOS Video Function
jmp .nextchar ;Loop around to write next character
.return:
pop bx
pop ax
ret
; load image routin~~~~~~~~~~~~~
load_image:
mov si,msg1
call display
mov ah, 0x02 ;Read Disk Sectors
mov al, [tot_sec] ;Read one sector only
mov ch, [track] ;Track 0
mov cl, [sector] ;Sector 2
mov dh, [head] ;Head 0
mov dl, [drive] ;Drive 0 (Floppy 1)
mov bx, 0x0060 ;Segment 0x2000
mov es, bx
mov bx, 0x0000 ;Start of Segment
int 0x13
jc error
ret
error:
mov si,ah_msg
mov byte [si],ah
call display
mov si,al_msg
mov byte [si],al
call display
mov si,err_msg
call display
jmp $
;data ~~~~~~~~~~~~~~~~~~~~~~~~~~
msg db "Welcome this is gyan 1st stage bootloader! ",13,10,0
msg1 db "going to load the disk image...",13,10,0
err_msg db "error reading the disk sector..",13,10,0
ah_msg db 0," = AH ",13,10,0
al_msg db 0," = AL ",13,10,0
track db 0
sector db 2
head db 0
tot_sec db 4
drive db 0
;boot signature ~~~~~~~~~~~~~~~~
times 510-($-$$) db 0 ;Loads of zeroes
dw 0xAA55 ;0x55 and 0xAA are the two last bytes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file : ka16.asm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[SECTION .text]
[BITS 16]
[org 0x00]
; if used as [org 0x100] it do not work . after booting messges in this file
; are not displayed
jmp strt
;data
KCODE_SEL equ 0x8
KDATA_SEL equ 0x10
KLINEAR_SEL equ 0x18
gdt: dd 0,0
kcode: dd 0x0000ffff,0x00cf9a00
kdata: dd 0x0000ffff,0x00cf9200
klinear: dd 0x0000ffff,0x00cf9200
gdt_end:
gdtr: dw gdt_end - gdt -1
dd 0
msg db "hello this is in ka16",13,10,0
; display routin ~~~~~~~~~~~~~~
display:
push ax
push bx
mov ah, 0x0E ;Teletype Mode
mov bh, 0x00 ;Page Number
.nextchar:
lodsb ;Load [si] into al and increment si
or al, al ;Set the Zero Flag if al = 0
jz .return ;If the Zero Flag is set, jump
;to Break
int 0x10 ;Call BIOS Video Function
jmp .nextchar ;Loop around to write next character
.return
pop bx
pop ax
ret
;------------------------------
;code
strt:
mov ax,ds
mov ss,ax
mov sp,0xfffe
mov si,msg
call display
xor ebx,ebx
mov bx,ds
shl ebx,4
mov eax,ebx
mov [kcode+2],ax
mov [kdata+2],ax
shr eax,16
mov [kcode+4],al
mov [kdata+4],al
mov [kcode+7],ah
mov [kdata+7],ah
lea eax,[ebx+gdt]
mov [gdtr+2],eax
cli
lgdt [gdtr]
mov eax,cr0
or al,1
mov cr0,eax
jmp skip_data
skip_data:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file ka32.asm
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[SECTION .text]
[BITS 32]
start:
[BITS 16]
incbin "ka16.bin"
;jmp $ ; hangs & do not restart
jmp dword 8: _go32 ; ????????????restarts after this
[BITS 32]
_go32:
mov ax,0x10
mov fs,ax
mov gs,ax
mov ds,ax
mov ss,ax
mov ax,0x18
mov es,ax
[BITS 32]
xor esi,esi
xor edi,edi
mov ecx,60
lea esi,[msg]
mov edi,0xb8000+(80*24+1)*2
cld
rep movsb
call _kmain
jmp short $
times 0x100 dd 0
stk_top dd 0
msg: db "h e l l o ! I a m i n p r o t e c t e d m o d e . "
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file kernel.c
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "types.h"
void kmain();
void kmain()
{
byte *screen = (byte*)0xb8000;
*screen = "*";
screen+=2;
*screen = "*";
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
types.h
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef _types_
#define _types_
#define byte unsigned char
#define word unsigned int
#define dword unsigned long
#define NULL 0
#endif
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i also commented the call to c function 'kmain()' in ka32.asm & excluded kernel.o while linking. Still it restarts.
i combined ka16.asm & ka32.asm into a single file ,kernel.asm, then assembled it to aout format & linked using ld to binary format. still it restarts.
can anybody tell me where i 'm going wrong?
waiting for an early reply....
please include ur mail id in reply so that i can further contact u...
problem with booting my kernel
RE:problem with booting my kernel
Well, try hardcoding the jump for instance:
db 0xea
dw *offset*
dw *segment*
It looks like either the jump itself is cracked, or the GDT. Is gdtr.base and gdtr.limit built correctly? Why is the base counted from DS not CS? Are you sure that these DD definitions are correct?
Adrian
db 0xea
dw *offset*
dw *segment*
It looks like either the jump itself is cracked, or the GDT. Is gdtr.base and gdtr.limit built correctly? Why is the base counted from DS not CS? Are you sure that these DD definitions are correct?
Adrian
RE:problem with booting my kernel
Your machine 'hangs' with jmp $ because it's looping.
jmp $ is an instruction in nasm to reload the same location i.e. jump to the same location. It hasen't really hung, its just not doing anything after that instruction.
Your machine restarts because its tripped faulted. That means you haven't setup everything to enter protected mode properly.
Tip, use Grub it makes life a whole lot easier. Grub is a multiboot compliant bootloader which will put your machine in protected mode, enable the A20 line, then boot your kernel. Easy! It means you don't have to struggle as a newbie handling protected mode and real mode, enabling A20, understanding how to boot your kernel which would need being able to control a disk drive plus understand a file system and understand your file type.
I was messing with bootloaders and using Grub let me a start my os development properly. Instead of mess around and give up five times.
That's not to say you shouldn't make your own bootloader, just make it when you understand and can control your machines hardware first.
jmp $ is an instruction in nasm to reload the same location i.e. jump to the same location. It hasen't really hung, its just not doing anything after that instruction.
Your machine restarts because its tripped faulted. That means you haven't setup everything to enter protected mode properly.
Tip, use Grub it makes life a whole lot easier. Grub is a multiboot compliant bootloader which will put your machine in protected mode, enable the A20 line, then boot your kernel. Easy! It means you don't have to struggle as a newbie handling protected mode and real mode, enabling A20, understanding how to boot your kernel which would need being able to control a disk drive plus understand a file system and understand your file type.
I was messing with bootloaders and using Grub let me a start my os development properly. Instead of mess around and give up five times.
That's not to say you shouldn't make your own bootloader, just make it when you understand and can control your machines hardware first.
RE:problem with booting my kernel
hello Adrian,
First of all thank u very much for ur prompt reply.....
Finally i got the solution.
After throughly studying the problem during these 2 weeks i came to know where i made a little mistake in my program.
On ur suggestion i verified those DD definitions & then i noticed that i missed one descriptor in GDT table. this is linear code segment descrptor.
Here it is :
klinear2 dd 0x0000ffff,0x009acf00.
I was trying to jump at 0x600 with code segment whose base I set to CS.
In fact i meant to jump at offset 0x600 of segment whose base = 0x00000
& i was trying to jump at offset 0x600 of segment whose base = CS.
So after adding one more descriptor entry to GDT whose base = 0x00000
i replaced the jump instruction as below
jmp 0x20:_go32 insted of jmp 8:_go32.
Also I combined the k16.asm & k32.asm into bootloader.
Now k32.asm contains only following lines
[BITS 32]
EXTERN _kamin
call _kmain
Instead of coff format I assembled it to aout format. & then linked it to kernel.o (of kernel.c)...
ok this works now....
well, thanks a lot for ur advice......
Prasad
First of all thank u very much for ur prompt reply.....
Finally i got the solution.
After throughly studying the problem during these 2 weeks i came to know where i made a little mistake in my program.
On ur suggestion i verified those DD definitions & then i noticed that i missed one descriptor in GDT table. this is linear code segment descrptor.
Here it is :
klinear2 dd 0x0000ffff,0x009acf00.
I was trying to jump at 0x600 with code segment whose base I set to CS.
In fact i meant to jump at offset 0x600 of segment whose base = 0x00000
& i was trying to jump at offset 0x600 of segment whose base = CS.
So after adding one more descriptor entry to GDT whose base = 0x00000
i replaced the jump instruction as below
jmp 0x20:_go32 insted of jmp 8:_go32.
Also I combined the k16.asm & k32.asm into bootloader.
Now k32.asm contains only following lines
[BITS 32]
EXTERN _kamin
call _kmain
Instead of coff format I assembled it to aout format. & then linked it to kernel.o (of kernel.c)...
ok this works now....
well, thanks a lot for ur advice......
Prasad
RE:problem with booting my kernel
hello Adrian,
First of all thank u very much for ur prompt reply.....
Finally i got the solution.
After throughly studying the problem during these 2 weeks i came to know where i made a little mistake in my program.
On ur suggestion i verified those DD definitions & then i noticed that i missed one descriptor in GDT table. this is linear code segment descrptor.
Here it is :
klinear2 dd 0x0000ffff,0x009acf00.
I was trying to jump at 0x600 with code segment whose base I set to CS.
In fact i meant to jump at offset 0x600 of segment whose base = 0x00000
& i was trying to jump at offset 0x600 of segment whose base = CS.
So after adding one more descriptor entry to GDT whose base = 0x00000
i replaced the jump instruction as below
jmp 0x20:_go32 insted of jmp 8:_go32.
Also I combined the k16.asm & k32.asm into bootloader.
Now k32.asm contains only following lines
[BITS 32]
EXTERN _kamin
call _kmain
hlt
Instead of coff format I assembled it to aout format. & then linked it to kernel.o (of kernel.c)...
ok this works now....
well, thanks a lot for ur advice......
Prasad
First of all thank u very much for ur prompt reply.....
Finally i got the solution.
After throughly studying the problem during these 2 weeks i came to know where i made a little mistake in my program.
On ur suggestion i verified those DD definitions & then i noticed that i missed one descriptor in GDT table. this is linear code segment descrptor.
Here it is :
klinear2 dd 0x0000ffff,0x009acf00.
I was trying to jump at 0x600 with code segment whose base I set to CS.
In fact i meant to jump at offset 0x600 of segment whose base = 0x00000
& i was trying to jump at offset 0x600 of segment whose base = CS.
So after adding one more descriptor entry to GDT whose base = 0x00000
i replaced the jump instruction as below
jmp 0x20:_go32 insted of jmp 8:_go32.
Also I combined the k16.asm & k32.asm into bootloader.
Now k32.asm contains only following lines
[BITS 32]
EXTERN _kamin
call _kmain
hlt
Instead of coff format I assembled it to aout format. & then linked it to kernel.o (of kernel.c)...
ok this works now....
well, thanks a lot for ur advice......
Prasad