grub4kos: works fine, at least in VMware and Bochs

git-svn-id: svn://kolibrios.org@4440 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2014-01-11 05:22:10 +00:00
parent c184a722c5
commit 98dad9f109

View File

@ -0,0 +1,276 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Kolibri OS support loader for GRUB
;
; Copyright (C) Alex Nogueira Teixeira
; Copyright (C) Diamond
; Copyright (C) Dmitry Kartashov aka shurf
; Copyright (C) Serge
;
; Distributed under GPL, see file COPYING for details
;
; Version 1.0
lf equ 0x0A
cr equ 0x0D
use32
org 0x100000
mboot:
dd 0x1BADB002
dd 0x00010003
dd -(0x1BADB002 + 0x00010003)
dd mboot
dd 0x100000
dd __edata
dd __end
dd __start
align 16
__start:
virtual at ebp+3
.BS_OEMName rb 8
.BPB_BytsPerSec rw 1 ; bytes per sector
.BPB_SecPerClus rb 1 ; sectors per cluster
.BPB_RsvdSecCnt rw 1 ; number of reserver sectors
.BPB_NumFATs rb 1 ; count of FAT data structures
.BPB_RootEntCnt rw 1 ; count of 32-byte dir. entries (224*32 = 14 sectors)
.BPB_TotSec16 rw 1 ; count of sectors on the volume (2880 for 1.44 mbytes disk)
.BPB_Media rb 1 ; f0 - used for removable media
.BPB_FATSz16 rw 1 ; count of sectors by one copy of FAT
.BPB_SecPerTrk rw 1 ; sectors per track
.BPB_NumHeads rw 1 ; number of heads
.BPB_HiddSec rd 1 ; count of hidden sectors
.BPB_TotSec32 rd 1 ; count of sectors on the volume (if > 65535)
end virtual
cld
mov esi, mboot
mov edi, 0x80000
mov ecx, 600/4 ;magic value
rep movsd
jmp .check_mbi
org $-0x80000
align 4
.check_mbi:
cmp eax, 0x2BADB002
mov ecx, sz_invboot
jne .fault
bt dword [ebx], 3
mov ecx, sz_nomods
jnc .fault
mov edx, [ebx+20] ;mods_count
mov esi, [ebx+24] ;mods_addr
cmp edx, 1
jne .fault
.scan_mod:
mov ebp, [esi] ;image start
mov ecx, [esi+4] ;image end
sub ecx, ebp ;image size
cmp ecx, 512*18*80*2 ;1.44 floppy
jne .fault
mov [_image_start], ebp
mov [_image_size], ecx
; calculate some disk parameters
; - beginning sector of RootDir
movzx eax, word [.BPB_FATSz16]
movzx ecx, byte [.BPB_NumFATs]
mul ecx
add ax, [.BPB_RsvdSecCnt]
mov [FirstRootDirSecNum], eax
mov esi, eax
; - count of sectors in RootDir
movzx ebx, word [.BPB_BytsPerSec]
mov cl, 5 ; divide ax by 32
shr ebx, cl ; bx = directory entries per sector
movzx eax, word [.BPB_RootEntCnt]
xor edx, edx
div ebx
mov [RootDirSecs], eax
; - data start
add esi, eax ; add beginning sector of RootDir and count sectors in RootDir
mov [data_start], esi
; reading root directory
; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!!
mov eax, [FirstRootDirSecNum]
mul word [.BPB_BytsPerSec]
lea esi, [ebp+eax]
mov eax, [RootDirSecs]
mul word [.BPB_BytsPerSec]
add eax, esi ; EAX = end of root dir. in buffer pos_read_tmp
; find kernel file in root directory
.loop_find_dir_entry:
push esi
mov ecx, 11
mov edi, kernel_name
rep cmpsb ; compare es:si and es:di, cx bytes long
pop esi
je .found_kernel_file
add esi, 32 ; next dir. entry
cmp esi, eax ; end of directory
jb .loop_find_dir_entry
mov ecx, sz_kernel
jmp .fault
; === KERNEL FOUND. LOADING... ===
.found_kernel_file:
movzx ecx, word [esi+01ah] ; first cluster of kernel file
; reading first FAT table
movzx eax, word [.BPB_RsvdSecCnt] ; begin first FAT abs sector number
mul word [.BPB_BytsPerSec]
lea ebx, [ebp+eax] ; FAT address
;ebx = FAT
;ecx = cluster
;esi = src
;edi = dst
;ebp = image
; copy kernel file
movzx eax, word [.BPB_BytsPerSec]
movsx edx, byte [.BPB_SecPerClus]
mul edx
shr eax, 2
mov [cluster_size], eax
mov edi, 0x10000 ;kernel base address
.copy_kernel:
; convert cluster number to sector number
mov eax, ecx ; data cluster to read
sub eax, 2
movzx edx, byte [.BPB_SecPerClus]
mul edx
add eax, [data_start]
movzx edx, word [.BPB_BytsPerSec]
mul edx
lea esi, [ebp+eax]
mov edx, ecx
mov ecx, [cluster_size]
rep movsd
mov ecx, edx
shr edx, 1
pushf
add edx, ecx ; di = bp * 1.5
mov ax, word [ebx+edx] ; read next entry from FAT-chain
popf
jc .move_4_right
and ax, 0fffh
jmp .verify_end_sector
.move_4_right:
shr ax, 4
.verify_end_sector:
cmp ax, 0ff8h ; last cluster
jae .execute_kernel
movzx ecx, ax
jmp .copy_kernel
.execute_kernel:
mov edi, 0x100000
mov esi, [_image_start]
mov ecx, [_image_size]
shr ecx, 2
rep movsd
xor eax, eax
mov ecx, 1024
rep stosd
xor ebx, ebx
xor ecx, ecx
xor edx, edx
xor esi, esi
xor edi, edi
xor ebp, ebp
xor esp, esp
lgdt [.tmp_gdt]
jmp far 0x08:.mode_16 and 0xFFFF
.fault:
; push ecx
; call _lcls
; call __bprintf
._hlt:
hlt
jmp ._hlt
align 8
.tmp_gdt: dw 15
dd .tmp_gdt
dw 0
.code16: dw 0xFFFF
dw 0
db 8
db 10011010b
dw 0
use16
.mode_16:
mov eax, cr0
and eax, not 0x80000001
mov cr0, eax
jmp far 0x8000:.real_mode and 0xFFFF
.real_mode:
xor eax, eax
mov ds, ax
mov es, ax
mov ss, ax
mov gs, ax
mov fs, ax
jmp far 0x1000:0000
sz_invboot db 'Invalid multiboot loader magic value',cr,lf
db 'Halted',0
sz_nomods db 'No modules loaded',cr,lf
db 'Halted',0
sz_kernel db cr,lf
kernel_name db 'KERNEL MNT ?',cr,lf,0
org $+0x80000
__edata:
align 4
_image_start rd 1
_image_size rd 1
FirstRootDirSecNum rd 1
RootDirSecs rd 1
data_start rd 1
cluster_size rd 1
__end: