forked from KolibriOS/kolibrios
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:
parent
c184a722c5
commit
98dad9f109
276
kernel/trunk/bootloader/grub4kos.asm
Normal file
276
kernel/trunk/bootloader/grub4kos.asm
Normal 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:
|
Loading…
Reference in New Issue
Block a user