forked from KolibriOS/kolibrios
da8c332884
git-svn-id: svn://kolibrios.org@4850 a494cfbc-eb01-0410-851d-a64ba20cac60
300 lines
7.6 KiB
NASM
300 lines
7.6 KiB
NASM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2014. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
|
|
; 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, 624/4 ;magic value
|
|
rep movsd
|
|
jmp .check_mbi
|
|
|
|
org $-0x80000
|
|
align 4
|
|
.check_mbi:
|
|
cmp eax, 0x2BADB002
|
|
mov esi, sz_invboot
|
|
jne .panic
|
|
|
|
bt dword [ebx], 3
|
|
mov esi, sz_nomods
|
|
jnc .panic
|
|
|
|
mov edx, [ebx+20] ;mods_count
|
|
mov edi, [ebx+24] ;mods_addr
|
|
cmp edx, 1
|
|
mov esi, sz_nomods
|
|
jne .panic
|
|
|
|
.scan_mod:
|
|
mov ebp, [edi] ;image start
|
|
mov ecx, [edi+4] ;image end
|
|
sub ecx, ebp ;image size
|
|
cmp ecx, 512*18*80*2 ;1.44 floppy
|
|
mov esi, sz_image
|
|
jne .panic
|
|
|
|
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 esi, sz_kernel
|
|
jmp .panic
|
|
|
|
; === 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
|
|
|
|
.panic:
|
|
mov ebx, sz_halt
|
|
mov edx, 0xb8000+160*10+2
|
|
mov ah, 0x07
|
|
.line:
|
|
mov edi, edx
|
|
.print:
|
|
lodsb
|
|
test al, al
|
|
jz .print_next
|
|
stosw
|
|
jmp .print
|
|
|
|
.print_next:
|
|
test ebx, ebx
|
|
jz ._hlt
|
|
|
|
mov esi, ebx
|
|
xor ebx, ebx
|
|
add edx, 160
|
|
jmp .line
|
|
|
|
._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',0
|
|
sz_nomods db 'No image loaded',0
|
|
sz_image db 'Image size invalid',0
|
|
sz_halt db 'Halted',0
|
|
|
|
sz_kernel db cr
|
|
kernel_name db 'KERNEL MNT ?',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:
|