;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2014-2015. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; KolibriOS 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 = 0x0A cr = 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: