KERNEL_OFFSET is the offset in memory that the kernel was loaded to. The reason I don't use the loop you suggested is because my bootloader is in the same source file, at the beginning of it. And just before the bootloader I ORGed the file to 0x7C00 for the bootloder. So, whenever I want to JMP somewhere in the kernel, I have to say (($-k_main)+KERNEL_OFFSET) where k_main is the beginning of the kernel and KERNEL_OFFSET is the kernel's offset in memory. For clarity's sake, here is the whole source:
Code: Select all
; general sizes (in bytes)
%define SECTOR_SIZE 0x0200
%define KILOBYTE_SIZE 0x0002 * SECTOR_SIZE
%define MEGABYTE_SIZE 0x0200 * KILOBYTE_SIZE
%define GIGABYTE_SIZE 0x0200 * MEGABYTE_SIZE
%define PAGE_SIZE 0x0004 * KILOBYTE_SIZE
; kernel disk info
%define KERNEL_DRIVE 0x0000
%define KERNEL_HEAD 0x0000
%define KERNEL_TRACK 0x0000
%define KERNEL_SECTOR 0x0002
%define KERNEL_SIZE PAGE_SIZE * 2
; kernel memory info
%define KERNEL_OFFSET 0x00000040
; kernel screen module
%define SCREEN_WIDTH 80
%define SCREEN_HEIGHT 25
%define BLACK 0x00
%define BLUE 0x01
%define GREEN 0x02
%define CYAN 0x03
%define RED 0x04
%define MAGENTA 0x05
%define BROWN 0x06
%define LIGHT_GREY 0x07
%define DARK_GREY 0x08
%define LIGHT_BLUE 0x09
%define LIGHT_GREEN 0x0A
%define LIGHT_CYAN 0x0B
%define LIGHT_RED 0x0C
%define LIGHT_MAGENTA 0x0D
%define LIGHT_BROWN 0x0E
%define WHITE 0x0F
;||=====================================================||
;|| BOOT LOADER ||
;||=====================================================||
[BITS 16]
[ORG 0x7C00]
bl_main:
; setup stack
xor ax,ax
mov ss,ax
mov sp,0x8000
; setup data
xor ax,ax
mov ds,ax
; load kernel
call kernel_loader
; load gdt
lgdt [gdt_descriptor]
; enter pmode
mov eax,cr0
or eax,1
mov cr0,eax
; jmp to kernel
jmp 0x8:KERNEL_OFFSET
kernel_loader:
; determine # of sectors to load
; dx:ax / bx = ax remainder dx
mov dx,0x0000
mov ax,KERNEL_SIZE
mov bx,SECTOR_SIZE
div bx
; ensure size is even number of sectors
cmp dx,0x0000
jnz .kl_error
; setup to loop thru sectors
mov cx,ax
mov BYTE [sector_current], KERNEL_SECTOR
mov WORD [offset_current], KERNEL_OFFSET
.lk_copy_sector:
push cx
; copy current sector
; disk loc -> es:bx in mem
mov dh,KERNEL_DRIVE
mov dl,KERNEL_HEAD
mov ch,KERNEL_TRACK
mov cl,[sector_current]
xor bx,bx
mov es,bx
mov bx,[offset_current]
mov ah,0x02
mov al,0x01
int 0x13
; prepare for next sector
add WORD [offset_current],SECTOR_SIZE
inc BYTE [sector_current]
pop cx
loop .lk_copy_sector
; completed
jmp .kl_success
; error section
.kl_error:
jmp $
; success section
.kl_success:
ret
gdt_entries:
; null entry
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
db 00000000b
; code segment descriptor: OFFSET = 0x0008
db 11111111b
db 11111111b
db 00000000b
db 00000000b
db 00000000b
db 10011010b
db 11001111b
db 00000000b
; data segment descriptor: OFFSET = 0x0010
db 11111111b
db 11111111b
db 00000000b
db 00000000b
db 00000000b
db 10010010b
db 11001111b
db 00000000b
gdt_descriptor:
; table size (2 bytes)
dw (gdt_descriptor - gdt_entries)
; table offset (4 bytes)
dd gdt_entries
bl_data:
; kernel_load data
sector_current db 0x00 ; KERNEL_SECTOR
offset_current dw 0x0000 ; KERNEL_OFFSET
bl_padding:
;pad to 510 bytes
times (512-2-($-bl_main)) db 0x00
;make disk bootable w/ 2 byte flag
db 0x55
db 0xAA
;||=====================================================||
;|| END BOOT LOADER ||
;||=====================================================||
;||=====================================================||
;|| KERNEL ||
;||=====================================================||
[BITS 32]
;||======================================||
;|| K_MAIN ||
;||======================================||
k_main:
; setup segments and stack
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x0000D000
mov al,0x78
call k_set_screen_colors
jmp (($-k_main)+KERNEL_OFFSET)
end_k_main:
;||======================================||
;|| END K_MAIN ||
;||======================================||
;||======================================||
;|| K_SCREEN ||
;||======================================||
k_screen:
k_set_screen_colors:
mov ebx,0x00B8001
mov ecx,(80*25)
.kssc_set_next:
mov BYTE [ds:ebx],al
add ebx,0x2
loop .kssc_set_next
ret
k_print:
mov ebx,0x000B8000
imul eax,160
add ebx,eax
.kp_next_char:
lodsb
cmp al,0x00
jz .kp_done
mov BYTE [ds:ebx],al
add ebx,0x2
jmp .kp_next_char
.kp_done:
ret
end_k_screen:
;||======================================||
;|| END K_SCREEN ||
;||======================================||
kl_data:
dbg_msg db "Debug MSG.",0x00
kl_padding:
; pad to kernel size
times (KERNEL_SIZE - ($-k_main)) db 0x00
;||=====================================================||
;|| END KERNEL ||
;||=====================================================||
Also yemista, I'm staying at a hotel in Boston tonight
. Small world, eh?
Brodeur235