diff --git a/kernel/branches/Kolibri-acpi/bootloader/boot_fat12.asm b/kernel/branches/Kolibri-acpi/bootloader/boot_fat12.asm deleted file mode 100644 index 9aeb52f411..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/boot_fat12.asm +++ /dev/null @@ -1,300 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; FAT12 boot sector for Kolibri OS -; -; Copyright (C) Alex Nogueira Teixeira -; Copyright (C) Diamond -; Copyright (C) Dmitry Kartashov aka shurf -; -; Distributed under GPL, see file COPYING for details -; -; Version 1.0 - -include "lang.inc" - -lf equ 0ah -cr equ 0dh - -pos_read_tmp equ 0700h ;position for temporary read -boot_program equ 07c00h ;position for boot code -seg_read_kernel equ 01000h ;segment to kernel read - - jmp start_program - nop - -; Boot Sector and BPB Structure -include 'floppy1440.inc' -;include 'floppy2880.inc' -;include 'floppy1680.inc' -;include 'floppy1743.inc' - -start_program: - - xor ax, ax - mov ss, ax - mov sp, boot_program - push ss - pop ds - - ; print loading string - mov si, loading+boot_program -loop_loading: - lodsb - or al, al - jz read_root_directory - mov ah, 0eh - mov bx, 7 - int 10h - jmp loop_loading - -read_root_directory: - push ss - pop es - - ; calculate some disk parameters - ; - beginning sector of RootDir - mov ax, word [BPB_FATSz16+boot_program] - xor cx, cx - mov cl, byte [BPB_NumFATs+boot_program] - mul cx - add ax, word [BPB_RsvdSecCnt+boot_program] - mov word [FirstRootDirSecNum+boot_program], ax ; 19 - mov si, ax - - ; - count of sectors in RootDir - mov bx, word [BPB_BytsPerSec+boot_program] - mov cl, 5 ; divide ax by 32 - shr bx, cl ; bx = directory entries per sector - mov ax, word [BPB_RootEntCnt+boot_program] - xor dx, dx - div bx - mov word [RootDirSecs+boot_program], ax ; 14 - - ; - data start - add si, ax ; add beginning sector of RootDir and count sectors in RootDir - mov word [data_start+boot_program], si ; 33 - ; reading root directory - ; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!! - mov ah, 2 ; read - push ax - - mov ax, word [FirstRootDirSecNum+boot_program] - call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) - pop ax - mov bx, pos_read_tmp ; es:bx read buffer - call read_sector - - mov si, bx ; read buffer address: es:si - mov ax, [RootDirSecs+boot_program] - mul word [BPB_BytsPerSec+boot_program] - add ax, si ; AX = end of root dir. in buffer pos_read_tmp - - ; find kernel file in root directory -loop_find_dir_entry: - push si - mov cx, 11 - mov di, kernel_name+boot_program - rep cmpsb ; compare es:si and es:di, cx bytes long - pop si - je found_kernel_file - add si, 32 ; next dir. entry - cmp si, ax ; end of directory - jb loop_find_dir_entry - -file_error_message: - mov si, error_message+boot_program - -loop_error_message: - lodsb - or al, al - jz freeze_pc - mov ah, 0eh - mov bx, 7 - int 10h - jmp loop_error_message - -freeze_pc: - jmp $ ; endless loop - - ; === KERNEL FOUND. LOADING... === - -found_kernel_file: - mov bp, [si+01ah] ; first cluster of kernel file - ; - mov [cluster1st+boot_program], bp ; starting cluster of kernel file - ; <\diamond> - - ; reading first FAT table - mov ax, word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number - call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) - mov bx, pos_read_tmp ; es:bx read position - mov ah, 2 ; ah=2 (read) - mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors) - call read_sector - jc file_error_message ; read error - - mov ax, seg_read_kernel - mov es, ax - xor bx, bx ; es:bx = 1000h:0000h - - - ; reading kernel file -loop_obtains_kernel_data: - ; read one cluster of file - call obtain_cluster - jc file_error_message ; read error - - ; add one cluster length to segment:offset - push bx - mov bx, es - mov ax, word [BPB_BytsPerSec+boot_program] ;\ - movsx cx, byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!! - mul cx ; | out this from loop !!! - shr ax, 4 ;/ - add bx, ax - mov es, bx - pop bx - - mov di, bp - shr di, 1 - pushf - add di, bp ; di = bp * 1.5 - add di, pos_read_tmp - mov ax, [di] ; read next entry from FAT-chain - popf - jc move_4_right - and ax, 0fffh - jmp verify_end_sector -move_4_right: - mov cl, 4 - shr ax, cl -verify_end_sector: - cmp ax, 0ff8h ; last cluster - jae execute_kernel - mov bp, ax - jmp loop_obtains_kernel_data - -execute_kernel: - ; - mov ax, 'KL' - push 0 - pop ds - mov si, loader_block+boot_program - ; - push word seg_read_kernel - push word 0 - retf ; jmp far 1000:0000 - - -;------------------------------------------ - ; loading cluster from file to es:bx -obtain_cluster: - ; bp - cluster number to read - ; carry = 0 -> read OK - ; carry = 1 -> read ERROR - - ; print one dot - push bx - mov ax, 0e2eh ; ah=0eh (teletype), al='.' - xor bh, bh - int 10h - pop bx - -writesec: - ; convert cluster number to sector number - mov ax, bp ; data cluster to read - sub ax, 2 - xor dx, dx - mov dl, byte [BPB_SecPerClus+boot_program] - mul dx - add ax, word [data_start+boot_program] - - call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector) -patchhere: - mov ah, 2 ; ah=2 (read) - mov al, byte [BPB_SecPerClus+boot_program] ; al=(one cluster) - call read_sector - retn -;------------------------------------------ - -;------------------------------------------ - ; read sector from disk -read_sector: - push bp - mov bp, 20 ; try 20 times -newread: - dec bp - jz file_error_message - push ax bx cx dx - int 13h - pop dx cx bx ax - jc newread - pop bp - retn -;------------------------------------------ - ; convert abs. sector number (AX) to BIOS T:H:S - ; sector number = (abs.sector%BPB_SecPerTrk)+1 - ; pre.track number = (abs.sector/BPB_SecPerTrk) - ; head number = pre.track number%BPB_NumHeads - ; track number = pre.track number/BPB_NumHeads - ; Return: cl - sector number - ; ch - track number - ; dl - drive number (0 = a:) - ; dh - head number -conv_abs_to_THS: - push bx - mov bx, word [BPB_SecPerTrk+boot_program] - xor dx, dx - div bx - inc dx - mov cl, dl ; cl = sector number - mov bx, word [BPB_NumHeads+boot_program] - xor dx, dx - div bx - ; !!!!!!! ax = track number, dx = head number - mov ch, al ; ch=track number - xchg dh, dl ; dh=head number - mov dl, 0 ; dl=0 (drive 0 (a:)) - pop bx - retn -;------------------------------------------ - -if lang eq sp -loading db cr,lf,'Iniciando el sistema ',00h -else -loading db cr,lf,'Starting system ',00h -end if -error_message db 13,10 -kernel_name db 'KERNEL MNT ?',cr,lf,00h -FirstRootDirSecNum dw ? -RootDirSecs dw ? -data_start dw ? - -; -write1st: - push cs - pop ds - mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3 - mov bp, [cluster1st+boot_program] - push 1000h - pop es - xor bx, bx - call writesec - mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2 - retf -cluster1st dw ? -loader_block: - db 1 - dw 0 - dw write1st+boot_program - dw 0 -; <\diamond> - -times 0x1fe-$ db 00h - - db 55h,0aah ;boot signature diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/build.bat b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/build.bat deleted file mode 100644 index 5419e0d687..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -@fasm -m 65535 kordldr.win.asm kordldr.win -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/fat.inc b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/fat.inc deleted file mode 100644 index 2399f48d34..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/fat.inc +++ /dev/null @@ -1,509 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; in: ss:bp = 0:dat -; in: es:bx = address to load file -; in: ds:si -> ASCIIZ name -; in: cx = limit in sectors -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) -load_file_fat: - mov eax, [bp + root_clus - dat] - mov [bp + cur_obj - dat], root_string - push es - push bx - push cx -.parse_dir_loop: -; convert name to FAT name - push [bp + cur_obj - dat] - push ax - mov [bp + cur_obj - dat], si - push ss - pop es -; convert ASCIIZ filename to FAT name - mov di, fat_filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -.nameloop: - lodsb - test al, al - jz .namedone - cmp al, '/' - jz .namedone - cmp al, '.' - jz .namedot - dec cx - js .badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp .nameloop -.namedot: - inc bx - jp .badname - add di, cx - mov cl, 3 - jmp .nameloop -.badname: - mov si, badname_msg - jmp find_error_si -.namedone: -; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si -; read a folder sector-by-sector and scan -; first, try to use the cache - push ss - pop ds - mov bx, -2 - mov cx, [bp + rootcache_size - dat] - cmp [bp + root_clus - dat], eax - jz .lookcache_root - mov di, foldcache_mark - xor bx, bx - mov cx, [bp + cachelimit - dat] -@@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz .cacheok - test edx, edx - jz .cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - js @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [bp + cachelimit - dat] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b -.cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - lea si, [di+bx] - mov dword [foldcache_clus+si-foldcache_mark+bx], eax -.cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [bp + cachelimit - dat] - add di, di -.cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns .cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 -.lookcache_root: -; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder - ;mov dx, bx - ;shl dx, 8 - ;add dx, 0x9200 - lea dx, [bx + 0x92] - xchg dl, dh - mov ds, dx - mov si, fat_filename ; ss:si -> filename in FAT style - call fat_scan_for_filename - jz .lookup_done -; cache miss, read folder data from disk -; we are reading parent directory, it can result in disk read errors; restore [cur_obj] - mov di, sp - mov bx, [bp + cur_obj - dat] - xchg bx, [ss:di+4] - mov [bp + cur_obj - dat], bx - mov bx, cx - add bx, 0xF - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -.folder_next_cluster: -; internal loop: scan sectors in cluster - movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus - push eax -; FAT12/16 root - special handling - test eax, eax - jnz .folder_notroot - mov cx, [ss:0x3211] ; BPB_RootEntCnt - mov dx, cx - add cx, 0xF - rcr cx, 1 - shr cx, 3 - mov eax, [bp + root_start - dat] - jmp .folder_next_sector -.folder_notroot: - mul ecx - add eax, [bp + data_start - dat] -.folder_next_sector: - sub dx, 0x10 -; skip first bx sectors - dec bx - jns .folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call read - jc ..found_disk_error -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - cmp di, 0x90 - jz .update_rootcache_size - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - jmp .updated_cachesize -.update_rootcache_size: - mov cl, 0x10 - cmp cx, dx - jb @f - mov cx, dx -@@: - add [bp + rootcache_size - dat], cx -.updated_cachesize: - popa -@@: - push es - mov cl, 0x10 ; ch=0 at this point - cmp cx, dx - jb @f - mov cx, dx -@@: - call fat_scan_for_filename - pop es - pop cx - jz .lookup_done_pop -.folder_skip_sector: - inc eax - loop .folder_next_sector - pop eax ; eax = current cluster - test eax, eax - jz @f - call [bp + get_next_cluster_ptr - dat] - jc .folder_next_cluster -@@: - stc - push eax -.lookup_done_pop: - pop eax -.lookup_done: - pop si -; CF=1 <=> failed - jnc .found - pop ds - pop [bp + cur_obj - dat] - mov si, error_not_found - jmp find_error_si -.found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop [bp + cur_obj - dat] ; forget old [cur_obj] - jz .regular_file - cmp byte [si-1], 0 - jnz .parse_dir_loop -..directory_error: - mov si, directory_string - jmp find_error_si -.regular_file: - cmp byte [si-1], 0 - jz @f -..notdir_error: - mov si, notdir_string - jmp find_error_si -@@: -; ok, we have found a regular file and the caller requested it -; parse FAT chunk - push ss - pop es - push ss - pop ds - mov di, 0x4005 - mov byte [di-5], 1 ; non-resident attribute - mov dword [di-4], 1 - stosd - pop cx - push cx -.parsefat: - call [bp + get_next_cluster_ptr - dat] - jnc .done - mov esi, [di-8] - add esi, [di-4] - cmp eax, esi - jz .contc - mov dword [di], 1 - scasd - stosd - jmp @f -.contc: - inc dword [di-8] -@@: - sub cl, [0x320D] - sbb ch, 0 - ja .parsefat -.done: - xor eax, eax - stosd - mov si, 0x4000 -load_file_common_end: - xor ecx, ecx - pop cx - pop bx - pop es - mov [bp + filesize - dat], edx - mov [bp + sectors_read - dat], ecx - add edx, 0x1FF - shr edx, 9 - mov [bp + filesize_sectors - dat], edx - cmp edx, ecx - seta al - mov ah, 0 - push ax - call read_file_chunk -continue_load_common_end: - mov [bp + cur_chunk_ptr - dat], si - pop bx - mov ax, word [bp + filesize - dat] - mov dx, word [bp + filesize+2 - dat] - jnc @f - mov bl, 3 ; read error -@@: - ret - -continue_load_file: -; es:bx -> buffer for output, ecx = cx = number of sectors - mov si, [bp + cur_chunk_ptr - dat] - push ecx - add ecx, [bp + sectors_read - dat] - mov [bp + sectors_read - dat], ecx - cmp [bp + filesize_sectors - dat], ecx - pop ecx - seta al - mov ah, 0 - push ax - push continue_load_common_end - push ss - pop ds - cmp [bp + cur_chunk_resident - dat], ah - jnz .nonresident -.resident: - mov ax, word [bp + num_sectors - dat] - jmp read_file_chunk.resident.continue -.nonresident: - mov eax, [bp + cur_cluster - dat] - mov edx, [bp + num_sectors - dat] - add eax, [bp + cur_delta - dat] - jmp read_file_chunk.nonresident.continue - -fat_scan_for_filename: -; in: ss:si -> 11-bytes FAT name -; in: ds:0 -> part of directory data -; in: cx = number of entries -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz .noent -.loop: - cmp byte [di], 0 - jz .notfound - test byte [di+11], 8 ; volume label? - jnz .cont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz .done -.cont: - add di, 0x20 - loop .loop -.noent: - inc cx ; clear ZF flag -.notfound: - stc -.done: - pop cx - ret - -fat12_get_next_cluster: -; in: ax = cluster (high word of eax is zero) -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 - push si - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 -@@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret - -fat16_get_next_cluster: -; in: ax = cluster (high word of eax is zero) -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 -; each sector contains 200h bytes = 100h FAT entries -; so ah = # of sector, al = offset in sector - push si - mov si, ax - shr si, 8 -; calculate segment for this sector of FAT table -; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) -; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x3400+si], 0 ; sector already loaded? - jnz .noread -; load corresponding sector, try all FATs if disk read error detected - pusha - movzx di, byte [ss:0x3210] ; BPB_NumFATs - xor bx, bx - mov ax, [ss:0x320E] ; BPB_RsvdSecCnt - xor dx, dx - add ax, si - adc dx, bx -@@: - push es - push dx ax - pop eax - mov cx, 1 ; read 1 sector - call read - pop es - jnc @f - add ax, [ss:0x3216] ; BPB_FATSz16 - adc dx, bx - dec di - jnz @b -..found_disk_error: - mov si, disk_error_msg - jmp find_error_si -@@: - popa -.noread: - mov si, ax - and si, 0xFF - add si, si - mov ax, [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret - -fat32_get_next_cluster: -; in: eax = cluster -; out: if there is next cluster: CF=1, eax = next cluster -; out: if there is no next cluster: CF=0 - push di - push ax - shr eax, 7 -; eax = FAT sector number; look in cache - push si - mov si, cache1head - call cache_lookup - pop si - jnc .noread -; read FAT, try all FATs if disk read error detected - push es - pushad - movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt - add eax, edx - movzx si, byte [ss:0x3210] ; BPB_NumFATs -@@: - lea cx, [di - 0x3400 + (0x6000 shr (9-3))] - shl cx, 9-3 - mov es, cx - xor bx, bx - mov cx, 1 - call read - jnc @f - add eax, [ss:0x3224] ; BPB_FATSz32 - dec si - jnz @b - jmp ..found_disk_error -@@: - popad - pop es -.noread: -; get requested item - lea ax, [di - 0x3400 + (0x6000 shr (9-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-3 - push ds - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop ds - pop di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/kordldr.win.asm b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/kordldr.win.asm deleted file mode 100644 index 709348bc5d..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/kordldr.win.asm +++ /dev/null @@ -1,924 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond -; It is used when main bootloader is Windows loader. - -; this code is loaded: -; NT/2k/XP: by ntldr to 0D00:0000 -; 9x: by io.sys from config.sys to xxxx:0100 -; Vista: by bootmgr to 0000:7C00 - format binary - use16 - -; in any case, we relocate this code to 0000:0600 - org 0x600 -; entry point for 9x and Vista booting - call @f - db 'NTFS' -@@: - pop si - sub si, 3 - cmp si, 100h - jnz boot_vista - mov si, load_question + 100h - 600h - call out_string -; mov si, answer + 100h - 0600h ; already is -xxy: - mov ah, 0 - int 16h - or al, 20h - mov [si], al - cmp al, 'y' - jz xxz - cmp al, 'n' - jnz xxy -; continue load Windows -; call out_string -; ret -out_string: - push bx -@@: - lodsb - test al, al - jz @f - mov ah, 0Eh - mov bx, 7 - int 10h - jmp @b -@@: - pop bx - ret -xxz: -; boot KordOS - call out_string -; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers, -; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached - xor di, di - mov ds, di - mov word [di+4], new01handler + 100h - 600h - mov [di+6], cs - pushf - pop ax - or ah, 1 - push ax - popf -; we cannot issue INT 19h directly, because INT command clears TF -; int 19h ; don't issue it directly, because INT command clears TF -; so instead we use direct call -; pushf ; there will be no IRET - call far [di + 19h*4] -xxt: - xor di, di - mov ds, di - cmp word [di + 8*4+2], 0F000h - jz @f - les bx, [di + 8*4] - mov eax, [es:bx+1] - mov [di + 8*4], eax -@@: - mov si, 100h -boot_vista: -; relocate cs:si -> 0000:0600 - push cs - pop ds - xor ax, ax - mov es, ax - mov di, 0x600 - mov cx, 2000h/2 - rep movsw - jmp 0:real_entry - -load_question db 'Load KordOS? [y/n]: ',0 -answer db ? - db 13,10,0 - -new01handler: -; [sp]=ip, [sp+2]=cs, [sp+4]=flags - push bp - mov bp, sp - push ds - lds bp, [bp+2] - cmp word [ds:bp], 19cdh - jz xxt - pop ds - pop bp - iret - -; read from hard disk -; in: eax = absolute sector -; cx = number of sectors -; es:bx -> buffer -; out: CF=1 if error -read: - pushad - add eax, [bp + partition_start - dat] - cmp [bp + use_lba - dat], 0 - jz .chs -; LBA read - push ds -.lbado: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp + boot_drive - dat] - mov ah, 42h - int 13h - jc .disk_error_lba - add sp, 10h ; restore stack -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz .lbado - pop ds - popad - ret -.disk_error_lba: - add sp, 14h - pop ds - popad - stc - ret - -.chs: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx - -; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp + sectors - dat] - xor edx, edx - div esi - mov bx, dx ; bx = sector-1 - -; eax -> dx:ax - push eax - pop ax - pop dx -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp + heads - dat] - -; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si -@@: - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector -; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp + boot_drive - dat] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - add sp, 12 - popad - stc - ret -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz .chs - popad - ret - -disk_error2 db 'Fatal: cannot read partitions info: ' -disk_error_msg db 'disk read error',0 -disk_params_msg db 'Fatal: cannot get drive parameters',0 -start_msg db 2,' KordOS bootloader',13,10,0 -part_msg db 'looking at partition ' -part_char db '0' ; will be incremented before writing message - db ' ... ',0 -errfs_msg db 'unknown filesystem',13,10,0 -fatxx_msg db 'FATxx' -newline db 13,10,0 -ntfs_msg db 'NTFS',13,10,0 -error_msg db 'Error' -colon db ': ',0 -root_string db '\',0 -nomem_msg db 'No memory',0 -filesys_string db '(filesystem)',0 -directory_string db 'is a directory',0 -notdir_string db 'not a directory',0 - -; entry point for NT/2k/XP booting -; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256 - repeat 600h + 256h - $ - db 1 ; any data can be here; 1 in ASCII is a nice face :) - end repeat -; cs=es=0D00, ds=07C0, ss=0 -; esi=edi=ebp=0, esp=7C00 - xor si, si - jmp boot_vista - -real_entry: -; ax = 0 - mov ds, ax - mov es, ax -; our stack is 4 Kb: memory range 2000-3000 - mov ss, ax - mov sp, 3000h - mov bp, dat - sti ; just for case -; say hi to user - mov si, start_msg - call out_string -; we are booting from hard disk identified by [boot_drive] - mov dl, [bp + boot_drive - dat] -; is LBA supported? - mov [bp + use_lba - dat], 0 - mov ah, 41h - mov bx, 55AAh - int 13h - jc .no_lba - cmp bx, 0AA55h - jnz .no_lba - test cl, 1 - jz .no_lba - inc [bp + use_lba - dat] - jmp disk_params_ok -.no_lba: -; get drive geometry - mov ah, 8 - mov dl, [bp + boot_drive - dat] - int 13h - jnc @f - mov si, disk_params_msg - call out_string - jmp $ -@@: - movzx ax, dh - inc ax - mov [bp + heads - dat], ax - and cx, 3Fh - mov [bp + sectors - dat], cx -disk_params_ok: -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jc nomem - shr ax, 3 - mov [bp + cachelimit - dat], ax ; size of cache - 1 -; scan all partitions -new_partition_ex: - xor eax, eax ; read first sector of current disk area - mov [bp + extended_part_cur - dat], eax ; no extended partition yet - mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition - push es - mov cx, 1 - mov bx, 3000h - call read - pop es - jnc new_partition - mov si, disk_error2 - call out_string - jmp $ -new_partition: - mov bx, [bp + cur_partition_ofs - dat] - mov al, [bx+4] ; partition type - test al, al - jz next_partition - cmp al, 5 - jz @f - cmp al, 0xF - jnz not_extended -@@: -; extended partition - mov eax, [bx+8] ; partition start - add eax, [bp + extended_part_start - dat] - mov [bp + extended_part_cur - dat], eax -next_partition: - add [bp + cur_partition_ofs - dat], 10h - cmp [bp + cur_partition_ofs - dat], 31FEh - jb new_partition - mov eax, [bp + extended_part_cur - dat] - test eax, eax - jz partitions_done - cmp [bp + extended_part_start - dat], 0 - jnz @f - mov [bp + extended_part_start - dat], eax -@@: - mov [bp + extended_parent - dat], eax - mov [bp + partition_start - dat], eax - jmp new_partition_ex -partitions_done: - mov si, total_kaput - call out_string - jmp $ -not_extended: - mov eax, [bx+8] - add eax, [bp + extended_parent - dat] - mov [bp + partition_start - dat], eax -; try to load from current partition -; inform user - mov si, part_msg - inc [si + part_char - part_msg] - call out_string -; read bootsector - xor eax, eax - mov [bp + cur_obj - dat], filesys_string - push es - mov cx, 1 - mov bx, 3200h - call read - pop es - mov si, disk_error_msg - jc find_error_si - movzx si, byte [bx+13] - mov word [bp + sect_per_clust - dat], si - test si, si - jz unknown_fs - lea ax, [si-1] - test si, ax - jnz unknown_fs -; determine file system -; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h) - cmp word [bx+11], 0x200 - jnz unknown_fs -; is it NTFS? - cmp dword [bx+3], 'NTFS' - jnz not_ntfs - cmp byte [bx+16], bl - jz ntfs -not_ntfs: -; is it FAT? FAT12/FAT16/FAT32? -; get count of sectors to dword in cx:si - mov si, [bx+19] - xor cx, cx - test si, si - jnz @f - mov si, [bx+32] - mov cx, [bx+34] -@@: - xor eax, eax -; subtract size of system area - sub si, [bx+14] ; BPB_ResvdSecCnt - sbb cx, ax - mov ax, [bx+17] ; BPB_RootEntCnt - add ax, 0xF - rcr ax, 1 - shr ax, 3 - sub si, ax - sbb cx, 0 - push cx - push si - mov ax, word [bx+22] - test ax, ax - jnz @f - mov eax, [bx+36] -@@: - movzx ecx, byte [bx+16] - imul ecx, eax - pop eax - sub eax, ecx -; now eax = count of sectors in the data region - xor edx, edx - div [bp + sect_per_clust - dat] -; now eax = count of clusters in the data region - mov si, fatxx_msg - cmp eax, 0xFFF5 - jae test_fat32 -; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38 - cmp byte [bx+38], 0x29 - jnz not_fat - cmp ax, 0xFF5 - jae fat16 -fat12: - mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster - mov di, cx ; BPB_NumFATs - mov ax, '12' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string - movzx ecx, word [bx+22] ; BPB_FATSz16 -; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes) -.fatloop: -; if first copy is not readable, try to switch to other copies - push 0x6000 - pop es - xor bx, bx - movzx eax, word [0x320E] ; BPB_RsvdSecCnt - push cx - cmp cx, 12 - jb @f - mov cx, 12 -@@: - call read - pop cx - jnc fat1x_common - add eax, ecx ; switch to next copy of FAT - dec di - jnz .fatloop - mov si, disk_error_msg - jmp find_error_si -fat16: - mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster - mov ax, '16' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string -; FAT16: init FAT cache - no sectors loaded - mov di, 0x3400 - xor ax, ax - mov cx, 0x100/2 - rep stosw -fat1x_common: - mov bx, 0x3200 - movzx eax, word [bx+22] ; BPB_FATSz16 - xor esi, esi ; no root cluster - jmp fat_common -test_fat32: -; FAT32 bootsector has it at the offset +66 - cmp byte [bx+66], 0x29 - jnz not_fat - mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster - mov ax, '32' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string -; FAT32 - init cache for FAT table: no sectors loaded - lea si, [bp + cache1head - dat] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [bp + cache1end - dat], 3400h ; first free item = 3400h - mov [bp + cache1limit - dat], 3C00h - mov eax, [bx+36] ; BPB_FATSz32 - mov esi, [bx+44] ; BPB_RootClus - jmp fat_common -not_fat: -unknown_fs: - mov si, errfs_msg - call out_string - jmp next_partition -fat_common: - push ss - pop es - movzx edx, byte [bx+16] ; BPB_NumFATs - mul edx - mov [bp + root_start - dat], eax ; this is for FAT1x -; eax = total size of all FAT tables, in sectors - movzx ecx, word [bx+17] ; BPB_RootEntCnt - add ecx, 0xF - shr ecx, 4 - add eax, ecx - mov cx, word [bx+14] ; BPB_RsvdSecCnt - add [bp + root_start - dat], ecx ; this is for FAT1x - add eax, ecx -; cluster 2 begins from sector eax - movzx ebx, byte [bx+13] ; BPB_SecPerClus - sub eax, ebx - sub eax, ebx - mov [bp + data_start - dat], eax -; no clusters in folders cache - mov di, foldcache_clus - 2 - xor ax, ax - mov cx, 7*8/2 + 1 - rep stosw - mov [bp + root_clus - dat], esi -; load secondary loader - mov [bp + load_file_ptr - dat], load_file_fat -load_secondary: - push 0x1000 - pop es - xor bx, bx - mov si, kernel_name - mov cx, 0x30000 / 0x200 - call [bp + load_file_ptr - dat] -; say error if needed - mov si, error_too_big - dec bx - js @f - jz find_error_si - mov si, disk_error_msg - jmp find_error_si -@@: -; fill loader information and jump to secondary loader - mov al, 'h' ; boot device: hard drive - mov ah, [bp + boot_drive - dat] - sub ah, 80h ; boot device: identifier - pop bx ; restore file system ID ('12'/'16'/'32'/'nt') - mov si, callback - jmp 1000h:0000h - -nomem: - mov si, nomem_msg - call out_string - jmp $ - -ntfs: - push 'nt' ; save for secondary loader - mov si, ntfs_msg - call out_string - xor eax, eax - mov [bp + data_start - dat], eax - mov ecx, [bx+40h] ; frs_size - cmp cl, al - jg .1 - neg cl - inc ax - shl eax, cl - jmp .2 -.1: - mov eax, ecx - shl eax, 9 -.2: - mov [bp + frs_size - dat], ax -; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different -; (at least with standard tools) -; we allow extra size, but no more than 0x1000 bytes = 4 Kb - mov si, invalid_volume_msg - cmp eax, 0x1000 - ja find_error_si -; must be multiple of sector size - test ax, 0x1FF - jnz find_error_si - shr ax, 9 - xchg cx, ax -; initialize cache - no data loaded - lea si, [bp + cache1head - dat] - mov [si], si - mov [si+2], si - mov word [si+4], 3400h ; first free item = 3400h - mov word [si+6], 3400h + 8*8 ; 8 items in this cache -; read first MFT record - description of MFT itself - mov [bp + cur_obj - dat], mft_string - mov eax, [bx+30h] ; mft_cluster - mul [bp + sect_per_clust - dat] - push 0x8000 - pop es - xor bx, bx - push es - call read - pop ds - call restore_usa -; scan for unnamed $DATA attribute - mov [bp + freeattr - dat], 4000h - mov ax, 80h - call load_attr - push ss - pop ds - mov si, nodata_string - jc find_error_si -; load secondary loader - mov [bp + load_file_ptr - dat], load_file_ntfs - jmp load_secondary - -find_error_si: - push si -find_error_sp: - cmp [bp + in_callback - dat], 0 - jnz error_in_callback - push ss - pop ds - push ss - pop es - mov si, error_msg - call out_string - mov si, [bp + cur_obj - dat] -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jz @f - mov ah, 0Eh - mov bx, 7 - int 10h - jmp @b -@@: - mov si, colon - call out_string - pop si - call out_string - mov si, newline - call out_string - mov sp, 0x3000 - jmp next_partition -error_in_callback: -; return status: file not found, except for read errors - mov bx, 2 - cmp si, disk_error_msg - jnz @f - inc bx -@@: - mov ax, 0xFFFF - mov dx, ax - mov sp, 3000h - 6 - ret - -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 3000h - mov bp, dat - mov [bp + in_callback - dat], 1 - push dx - push cx -; set ds:si -> ASCIIZ name - lea si, [di+6] -; set cx = limit in sectors; 4Kb = 8 sectors - movzx ecx, word [di+4] - shl cx, 3 -; set es:bx = pointer to buffer - les bx, [di] -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call [bp + load_file_ptr - dat] -callback_ret_succ: - clc -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -read_file_chunk.resident: -; auxiliary label for read_file_chunk procedure - mov di, bx - lodsw -read_file_chunk.resident.continue: - mov dx, ax - add dx, 0x1FF - shr dx, 9 - cmp dx, cx - jbe @f - mov ax, cx - shl ax, 9 -@@: - xchg ax, cx - rep movsb - xchg ax, cx - clc ; no disk error if no disk requests - mov word [bp + num_sectors - dat], ax - ret - -read_file_chunk: -; in: ds:si -> file chunk -; in: es:bx -> buffer for output -; in: ecx = maximum number of sectors to read (high word must be 0) -; out: CF=1 <=> disk read error - lodsb - mov [bp + cur_chunk_resident - dat], al - test al, al - jz .resident -; normal case: load (non-resident) attribute from disk -.read_block: - lodsd - xchg eax, edx - test edx, edx - jz .ret - lodsd -; eax = start cluster, edx = number of clusters, cx = limit in sectors - imul eax, [bp + sect_per_clust - dat] - add eax, [bp + data_start - dat] - mov [bp + cur_cluster - dat], eax - imul edx, [bp + sect_per_clust - dat] - mov [bp + num_sectors - dat], edx - and [bp + cur_delta - dat], 0 -.nonresident.continue: - cmp edx, ecx - jb @f - mov edx, ecx -@@: - test dx, dx - jz .read_block - add [bp + cur_delta - dat], edx - sub [bp + num_sectors - dat], edx - sub ecx, edx - push cx - mov cx, dx - call read - pop cx - jc .ret - test cx, cx - jnz .read_block -.ret: - ret - -cache_lookup: -; in: eax = value to look, si = pointer to cache structure -; out: di->cache entry; CF=1 <=> the value was not found - push ds bx - push ss - pop ds - mov di, [si+2] -.look: - cmp di, si - jz .not_in_cache - cmp eax, [di+4] - jz .in_cache - mov di, [di+2] - jmp .look -.not_in_cache: -; cache miss -; cache is full? - mov di, [si+4] - cmp di, [si+6] - jnz .cache_not_full -; yes, delete the oldest entry - mov di, [si] - mov bx, [di] - mov [si], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append -.cache_not_full: -; no, allocate new item - add word [si+4], 8 -.cache_append: - mov [di+4], eax - stc - jmp @f -.in_cache: -; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si -@@: -; add new sector to the end of list - mov bx, di - xchg bx, [si+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx - pop bx ds - ret - -include 'fat.inc' -include 'ntfs.inc' - -total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0 -error_too_big db 'file is too big',0 -nodata_string db '$DATA ' -error_not_found db 'not found',0 -noindex_string db '$INDEX_ROOT not found',0 -badname_msg db 'bad name for FAT',0 -invalid_volume_msg db 'invalid volume',0 -mft_string db '$MFT',0 -fragmented_string db 'too fragmented file',0 -invalid_read_request_string db 'cannot read attribute',0 - -kernel_name db 'kernel.mnt',0 - -align 4 -dat: - -extended_part_start dd 0 ; start sector for main extended partition -extended_part_cur dd ? ; start sector for current extended child -extended_parent dd 0 ; start sector for current extended parent -partition_start dd 0 ; start sector for current logical disk -cur_partition_ofs dw ? ; offset in MBR data for current partition -sect_per_clust dd 0 -; change this variable if you want to boot from other physical drive -boot_drive db 80h -in_callback db 0 - -; uninitialized data -use_lba db ? -cur_chunk_resident db ? -align 2 -heads dw ? -sectors dw ? -cache1head rw 2 -cache1end dw ? -cache1limit dw ? -data_start dd ? -cachelimit dw ? -load_file_ptr dw ? -cur_obj dw ? -missing_slash dw ? -root_clus dd ? -root_start dd ? -get_next_cluster_ptr dw ? -frs_size dw ? -freeattr dw ? -index_root dw ? -index_alloc dw ? -cur_index_seg dw ? -cur_index_cache dw ? -filesize dd ? -filesize_sectors dd ? -cur_cluster dd ? -cur_delta dd ? -num_sectors dd ? -sectors_read dd ? -cur_chunk_ptr dw ? - -rootcache_size dw ? ; must be immediately before foldcache_clus -if $-dat >= 0x80 -warning: - unoptimal data displacement! -end if -foldcache_clus rd 7 -foldcache_mark rw 7 -foldcache_size rw 7 -fat_filename rb 11 - -if $ > 2000h -error: - file is too big -end if - -; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long -repeat 0x2600 - $ - db 2 ; any data can be here; 2 is another nice face in ASCII :) -end repeat diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/kordldr.win.txt b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/kordldr.win.txt deleted file mode 100644 index 3affd3f39e..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/kordldr.win.txt +++ /dev/null @@ -1,391 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Нет повести печальнее на свете, - Чем повесть о заклинившем Reset'е... - -Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает -Windows, для носителей с размером сектора 512 байт. - -===================================================================== - -Требования для работы: -1) Все используемые файлы должны быть читабельны. -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 592K свободной базовой памяти. -4) Пути к используемым файлам не должны содержать символических ссылок NTFS - (жёсткие ссылки допускаются). -5) Используемые файлы не должны быть сжатыми или разреженными файлами - (актуально для NTFS, для FAT выполнено автоматически). - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 08.08.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys - и file://C:/ntldr либо file://C:/bootmgr - неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx - официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx - формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx - -===================================================================== - -Схема используемой памяти: - 600-2000 код загрузчика (и данные) - 2000-3000 стек - 3000-3200 сектор MBR - 3200-3400 бутсектор логического диска - 3400-3C00 информация о кэше для таблиц FAT16/FAT32: - для FAT16 - массив на 0x100 байт, каждый байт равен - 0 или 1 в зависимости от того, загружен ли - соответствующий сектор таблицы FAT16; - для FAT32 - 100h входов по 8 байт: 4 байта - (две ссылки - вперёд и назад) для организации L2-списка - всех прочитанных секторов в порядке возрастания - последнего времени использования + 4 байта для номера - сектора; при переполнении кэша выкидывается элемент из - головы списка, то есть тот, к которому дольше всех - не было обращений - 3400-3440 информация о кэше для файловых записей NTFS в - таком же формате, как и кэш для FAT32, но на 8 входов - 3480-34C0 заголовки для кэшей записей индекса NTFS - 3500-3D00 информация о кэшах записей индекса NTFS: с каждой - файловой записью связан свой кэш для - соответствующего индекса - 4000-8000 место для информации об атрибутах для NTFS - 60000-80000 таблица FAT12 / место под таблицу FAT16 / - кэш для таблицы FAT32 / кэш для структур NTFS - 80000-90000 текущий рассматриваемый кластер - 90000-92000 FAT: кэш для корневой папки - 92000-... FAT: кэш для некорневых папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 7 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется - размещением команды install=c:\kordldr.win в первой строке config.sys; - при этом основной загрузчик системы загружает kordldr.win как обычный - com-файл, в какой-то сегмент по смещению 100h и передаёт управление - в начало кода (xxxx:0100). -0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется - добавлением строки наподобие c:\kordldr.win="KordOS" в секцию - [operating systems] файла boot.ini; если загружаемый файл имеет размер - не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS' - (в случае kordldr.win так и есть), то основной загрузчик каждой из - этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт - управление на адрес 0D00:0256. -0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями - с базой данных основного загрузчика через bcdedit и подробно описана в - инструкции к kordldr.win; основной загрузчик загружает целиком - kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода. -1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная - им программа окажется в свою очередь загрузчиком, и в этом случае - kordldr.win оказывается в условиях, когда основной загрузчик уже - установил какое-то окружение, в частности, перехватил некоторые - прерывания. Поэтому перед остальными действиями загрузчик должен - восстановить систему в начальное состояние. (При загрузке под - NT-линейкой такой проблемы не возникает, поскольку там основной - загрузчик ничего в системе не трогает.) Поэтому перед собственно - инициализацией KordOS при работе из-под DOS/9x производятся - дополнительные действия. Первым делом kordldr проверяет, какой из - случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт - управление не на начало кода): определяет значение ip (команда call - помещает в стек адрес следующей после call инструкции, команда pop si - выталкивает его в регистр si), и если оно равно 100h, то kordldr - загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения - у пользователя (поскольку в этой схеме kordldr загружается всегда, - он должен оставить возможность продолжить загрузку DOS/9x). Если - пользователь хочет продолжить обычную загрузку, kordldr завершается. - Иначе используется тот факт, что при выдаче прерывания перезагрузки - int 19h система предварительно снимает все свои перехваты BIOSовских - прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что - kordldr устанавливает свой обработчик трассировочного прерывания, - устанавливает флаг трассировки и передаёт управление DOSовскому - обработчику. Обработчик трассировочного прерывания ничего не делает - до тех пор, пока следующей инструкцией не оказывается int 19h, а - в этот момент отбирает управление и продолжает загрузку KordOS. - При этом BIOSовские обработчики восстановлены за исключением, - быть может, прерывания таймера int 8, которое, возможно, восстановлено - до команды jmp far на оригинальный обработчик. В последнем случае его - нужно восстановить явно. -2. Загрузчик перемещает свой код на адрес 0000:0600. -3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0, - настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы - все данные можно было адресовать через [bp+N] с однобайтовым N - (в дальнейшем они так и будут адресоваться для освобождения ds и - экономии на размере кода). Разрешает прерывания на случай, если - они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся - с весёлой рожицы (символ с ASCII-кодом 2). -4. Определяет характеристики жёсткого диска, указанного в качестве - загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h), - если LBA не поддерживается, то определяет геометрию - число дорожек - и число секторов на дорожке (функция 8 прерывания 13h), эти параметры - нужны функции чтения с диска. -5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска. - Цель цикла - для каждого логического диска попытаться загрузиться с - него (действия по загрузке с конкретного логического диска начинаются - с метки not_extended), при ошибке загрузки управление передаётся - назад этому циклу (метка next_partition), и поиск подходящего раздела - продолжается. На выходе заполняется одна переменная partition_start, - имеющая смысл начала текущего рассматриваемого логического диска, - но по ходу дела из-за приколов таблиц разделов используются ещё четыре - переменных. cur_partition_ofs - фактически счётчик цикла, формально - указатель на текущий вход в текущей загрузочной записи. Сама - загрузочная запись считывается в память начиная с адреса 3000h. - Три оставшихся нужны для правильной работы с расширенными разделами. - В каждой загрузочной записи помещается не более 4 записей о разделах. - Поэтому главной загрузочной записи, размещающейся в первом физическом - секторе диска, может не хватить, и обычно создаётся так называемый - расширенный раздел с расширенными загрузочными записями, формат - которых почти идентичен главной. Расширенный раздел может быть только - один, но в нём может быть много логических дисков и расширенных - загрузочных записей. Расширенные загрузочные записи организованы - в односвязный список, в каждой такой записи первый вход указывает - на соответствующий логический диск, а второй - на следующую расширенную - загрузочную запись. - При этом в главной загрузочной записи все адреса разделов являются - абсолютными номерами секторов. В расширенных же записях адреса разделов - относительны, причём с разными базами: адрес логического диска - указывается относительно расширенной записи, а адрес следующей - расширенной записи указывается относительно начала расширенного - раздела. Такой разнобой выглядит несколько странно, но имеет место - быть. Три оставшихся переменных содержат: extended_part_start - - начало расширенного раздела; extended_parent - текущая рассматриваемая - расширенная загрузочная запись; extended_part_cur - следующая - загрузочная запись для рассмотрения. - Цикл выглядит так: просматриваются все разделы, указанные в текущей - (главной или расширенной) загрузочной записи; для нормальных разделов - (они же логические диски) происходит переход на not_extended, где - устанавливается partition_start и начинается собственно загрузка - (последующие шаги); при встрече с разделом, тип которого указывает - на расширенность (5 или 0xF), код запоминает начало этого раздела - (в главной загрузочной записи такой тип означает расширенный раздел, - в расширенной - только указатель на следующую расширенную запись, - в обоих случаях он может встретиться только один раз в данной записи); - когда код доходит до конца списка, все нормальные разделы, описываемые - в этой записи, уже просмотрены, так что код с чистой совестью переходит - к следующей расширенной записи. Если он её не встретил, значит, уже - все логические разделы были подвергнуты попыткам загрузиться, и все - безрезультатно, так что выводится ругательство и работа останавливается - (jmp $). - Может возникнуть вопрос, зачем нужна такая сложная схема и почему - нельзя узнать нужный логический диск заранее или хотя бы ограничиться - первым попавшимся логическим диском, не крутя цикл. Так вот, вариант - с предварительным определением нужного раздела в данном случае не - используется, поскольку повлёк бы за собой нетривиальные лишние - действия по установке (в текущем виде установку можно провести вручную, - и она сводится к указанию системному загрузчику на существование - kordldr); кстати, в альтернативной версии загрузки после - Windows-загрузчика, когда установка осуществляется не вручную, а - специальной программой под Windows, используется модифицированная - версия, в которой как раз начальный физический сектор нужного раздела - прописывается установщиком. Сам kordldr не может установить, с какого - раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан - быть файлом на диске C:\). Вариант с первым попавшимся логическим - диском был реализован в первой версии загрузчика, но по ходу дела - обнаружилось, что таки нужно крутить цикл: во-вторых, может быть - приятным, что сама система может стоять вовсе не на системном C:\, а и - на других дисках; во-первых, диск C: может и не быть первым логическим - разделом - Vista любит создавать скрытый первичный раздел перед - системным, и тогда диск C: становится вторым логическим. -6. Извещает пользователя о том, что происходит попытка загрузки с очередного - логического диска. -7. Читает первый сектор логического диска и определяет файловую систему. - И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе - и должно совпадать с характеристикой физического носителя, то есть - 200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число - секторов в кластере и должно быть степенью двойки. - Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со - смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано - быть ненулевым). - Критерий FAT: загрузчик вычисляет число кластеров, определяет - предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению - +38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29). - После определения типа файловой системы извещает пользователя об - определённом типе. Если файловая система не распознана, выдаёт - соответствующее сообщение и переходит к следующему логическому диску. -8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы - - константу '12'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT12-обработчик; считывает в память всю - таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке - чтения пытается использовать другие копии FAT. -8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы - - константу '16'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию - о кэше секторов FAT (массив байт с возможными значениями 0 и 1, - означающими, был ли уже загружен соответствующий сектор - всего в - таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не - загружен, все байты нулевые. -8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы - - константу '32'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию - о кэше секторов FAT (формат информации описан выше, в распределении - используемой загрузчиком памяти) - ни один сектор ещё не загружен. -8г. Общее для FAT-томов: определяет значения служебных переменных - root_start (первый сектор корневого каталога в FAT12/16, игнорируется - при обработке FAT32-томов), data_start (начало данных с поправкой, - вводимой для того, чтобы кластер N начинался с сектора - N*sectors_per_cluster+data_start), root_clus (первый кластер корневого - каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию - загрузки файла на FAT-обработчик. -8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы - - константу 'nt'; определяет значение служебной переменной frs_size - (размер в байтах файловой записи, File Record Segment), для полной - корректности проверяет, что это значение (равное 0x400 байт на всех - реальных NTFS-томах - единственный способ изменить его заключается - в пересоздании всех системных структур вручную) не превосходит 0x1000 - и кратно размеру сектора 0x200 байт; инициализирует кэш файловых - записей - ничего ещё не загружено; считывает первый кластер $MFT - и загружает информацию о расположении на диске всей таблицы $MFT - (атрибут 0x80, $Data); устанавливает указатель на функцию загрузки - файла на NTFS-обработчик. -9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного - загрузчика. При обнаружении ошибки переходит на обработчик ошибок с - соответствующим сообщением. -10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск), - ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h), - может быть изменён путём модификации константы в исходнике или - специальным установщиком), bx=идентификатор файловой системы (берётся - из стека, куда ранее был засунут на шаге 8), ds:si=указатель на - callback-функцию. -11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -Чтение файла: -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным - кодом должна указывать на 0:dat. -2. Разбирает переданные параметры и вызывает процедуру загрузки файла. -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры. -Процедура чтения секторов (read): -на входе должно быть установлено: - ss:bp = 0:dat - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор (относительно начала логического диска) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, - флаг CF установлен, если возникла ошибка чтения -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя номер первого сектора логического диска, - найденный при переборе дисков. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура обработки ошибок (find_error_si и find_error_sp): -на входе: указатель на сообщение об ошибке в si либо на верхушке стека -0. Если вызывается find_error_si, она помещает переданный указатель в стек. -1. Если ошибка произошла в процессе работы callback-функции, то - (метка error_in_callback) обработчик просто возвращает управление - вызвавшему коду, рапортуя о ненайденном файле. -2. Если же ошибка произошла до передачи управления вторичному загрузчику, - обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>" - и (восстановив стек) переходит к следующему логическому диску. - -Процедура чтения файла/атрибута по известному размещению на диске - (read_file_chunk): -на входе должно быть установлено: - ds:si = указатель на информацию о размещении - es:bx = указатель на начало буфера, куда будут прочитаны данные - ecx = лимит числа секторов для чтения, старшее слово должно быть 0 -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, - флаг CF установлен, если возникла ошибка чтения -1. Определяет, является ли атрибут резидентным (возможно только в NTFS - и означает, что данные файла/атрибута уже были целиком прочитаны при - обработке информации о файле) или нерезидентным (означает, что данные - хранятся где-то на диске, и имеется информация о том, где именно). -2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует - данные по месту назначения (с учётом указанного лимита). -3. Для нерезидентных атрибутов информация состоит из пар <размер очередного - фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура - читает фрагменты, пока файл не закончится или пока не будет достигнут - указанный лимит. - -Процедура просмотра кэша (cache_lookup): -на входе должно быть установлено: - eax = искомое значение - ss:si = указатель на структуру-заголовок кэша -на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение - было только что добавлено, и сброшен, если оно уже было в кэше. -1. Просматривает кэш в поисках указанного значения. Если значение найдено - (при этом флаг CF оказывается сброшенным), переходит к шагу 4. -2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в - голове двусвязного списка), иначе добавляет к кэшу ещё один вход. -3. Устанавливает в полученном входе указанное значение. Устанавливает флаг - CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5. -4. Удаляет вход из списка. -5. Добавляет сектор в конец списка (самый новый вход). diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/ntfs.inc b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/ntfs.inc deleted file mode 100644 index 2d1353e8d8..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/after_win/ntfs.inc +++ /dev/null @@ -1,587 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -restore_usa: -; Update Sequence Array restore -; in: ds:bx -> USA-protected structure - push bx - lea di, [bx+1feh] - mov cx, [bx+6] - add bx, [bx+4] - dec cx -@@: - mov ax, [bx+2] - mov [di], ax - inc bx - inc bx - add di, 200h - loop @b - pop bx - ret - -find_attr: -; in: ds:di->file record, ax=attribute -; out: ds:di->attribute or di=0 if not found - add di, [di+14h] -.1: -; attributes' codes are formally dwords, but all of them fit in word - cmp word [di], -1 - jz .notfound - cmp word [di], ax - jnz .continue -; for $DATA attribute, scan only unnamed - cmp ax, 80h - jnz .found - cmp byte [di+9], 0 - jz .found -.continue: - add di, [di+4] - jmp .1 -.notfound: - xor di, di -.found: - ret - -process_mcb_nonres: -; in: ds:si->attribute, es:di->buffer -; out: es:di->buffer end - pushad - pop di - add si, [si+20h] - xor ebx, ebx -.loop: - lodsb - test al, al - jz .done - push invalid_read_request_string - movzx cx, al - shr cx, 4 - jz find_error_sp - xchg ax, dx - and dx, 0Fh - jz find_error_sp - add si, cx - add si, dx - pop ax - push si - dec si - movsx eax, byte [si] - dec cx - jz .l1e -.l1: - dec si - shl eax, 8 - mov al, [si] - loop .l1 -.l1e: - xchg ebp, eax - dec si - movsx eax, byte [si] - mov cx, dx - dec cx - jz .l2e -.l2: - dec si - shl eax, 8 - mov al, byte [si] - loop .l2 -.l2e: - pop si - add ebx, ebp -; eax=length, ebx=disk block - stosd - mov eax, ebx - stosd - cmp di, 0x8000 - 12 - jbe .loop -..attr_overflow: - mov si, fragmented_string - jmp find_error_si -.done: - xor ax, ax - stosw - stosw - push di - popad - ret - -load_attr: -; in: ax=attribute, ds:bx->base record -; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated, -; edx=size of attribute in bytes -; out: if not found: CF=1 - mov di, [bp + freeattr - dat] - push ss - pop es - mov byte [es:di], 1 - inc di - cmp di, 0x8000 - 12 - ja ..attr_overflow - or edx, -1 ; file size is not known yet -; scan for attribute - push di - mov di, bx - add di, [di+14h] -@@: - call find_attr.1 - test di, di - jz .notfound1 - cmp byte [di+8], 0 - jnz .nonresident - mov si, di - pop di - push ds - jmp .resident -.aux_resident: - mov ax, ds - mov si, di - pop di ds bx ds edx - push ss - pop es - push ds - mov ds, ax -; resident attribute -.resident: - dec di - mov al, 0 - stosb - mov ax, [si+10h] - stosw - push di - add di, ax - cmp di, 0x8000 - 12 - pop di - ja ..attr_overflow - movzx edx, ax ; length of attribute - xchg ax, cx - add si, [si+14h] - rep movsb - mov [bp + freeattr - dat], di - pop ds - ret -.nonresident: -; nonresident attribute - cmp dword [di+10h], 0 - jnz @b -; read start of data - mov si, di - mov edx, [di+30h] ; size of attribute - pop di - call process_mcb_nonres - sub di, 4 - push di -.notfound1: - pop di - push edx -; $ATTRIBUTE_LIST is always in base file record - cmp ax, 20h - jz .nofragmented -; try to load $ATTRIBUTE_LIST = 20h - push ax - mov ax, 20h - push [bp + freeattr - dat] - mov [bp + freeattr - dat], di - push di - call load_attr - pop di - pop [bp + freeattr - dat] - pop ax - jc .nofragmented - push ds bx - pusha - mov si, di - push ss - pop ds - push 0x8100 - pop es - xor ecx, ecx - mov cl, 0x78 - xor bx, bx - push es - call read_file_chunk - pop ds - jc ..found_disk_error - test cx, cx - jz ..attr_overflow - popa - push ss - pop es - xor bx, bx -.1: - cmp [bx], ax - jnz .continue1 -; only unnamed $DATA attributes! - cmp ax, 80h - jnz @f - cmp byte [bx+6], 0 - jnz .continue1 -@@: - cmp dword [bx+10h], 0 - jz .continue1 - cmp dword [bx+8], 0 - jnz @f - dec di - cmp di, [bp + freeattr - dat] - lea di, [di+1] - jnz .continue1 -@@: - push ds di - push ax - mov eax, [bx+10h] - mov ecx, [bx+8] - call read_file_record - pop ax - mov di, [14h] -.2: - call find_attr.1 - cmp byte [di+8], 0 - jz .aux_resident - cmp dword [di+10h], ecx - jnz .2 - mov si, di - mov di, sp - cmp dword [ss:di+8], -1 - jnz @f - push dword [si+30h] ; size of attribute - pop dword [ss:di+8] -@@: - pop di - call process_mcb_nonres - sub di, 4 - pop ds -.continue1: - add bx, [bx+4] - cmp bx, dx - jb .1 - pop bx ds -.nofragmented: - pop edx - dec di - cmp di, [bp + freeattr - dat] - jnz @f - stc - ret -@@: - inc di - xor ax, ax - stosw - stosw - mov [bp + freeattr - dat], di - ret - -read_file_record: -; in: eax = index of record -; out: ds:0 -> record -; find place in cache - push di - push si - mov si, cache1head - call cache_lookup - pop si - pushf - sub di, 3400h - shl di, 10-3 - add di, 0x6000 - mov ds, di - popf - pop di - jnc .noread -; read file record to ds:0 - pushad - push ds - push es - movzx ecx, [bp + frs_size - dat] - shr cx, 9 - mul ecx - push ds - pop es - push ss - pop ds - mov si, 0x4000 - xor bx, bx - push [bp + cur_obj - dat] - mov [bp + cur_obj - dat], mft_string - push es - call read_attr -; initialize cache for $INDEX_ALLOCATION for this record - pop si - push si - sub si, 0x6000 - mov ax, si - shr si, 10-3 - shr ax, 2 - add si, 3480h - add ax, 3500h - mov [si], si - mov [si+2], si - mov [si+4], ax - pop ds - call restore_usa - pop [bp + cur_obj - dat] - pop es - pop ds - popad -.noread: - ret - -read_attr: -; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute - push invalid_read_request_string - cmp byte [si], 0 - jnz .nonresident - cmp eax, 10000h shr 9 - jae find_error_sp - shl ax, 9 - shl cx, 9 - cmp ax, [si+2] - jae find_error_sp - cmp cx, [si+2] - ja find_error_sp - add si, 3 - add si, ax - mov di, bx - rep movsb - pop ax - ret -.nonresident: - inc si -.loop: - mov edx, dword [si] - add si, 8 - test edx, edx - jz find_error_sp - imul edx, [bp + sect_per_clust - dat] - sub eax, edx - jnc .loop - add eax, edx - sub edx, eax - push cx - cmp ecx, edx - jb @f - mov cx, dx -@@: - push bx - mov ebx, [si-4] - imul ebx, [bp + sect_per_clust - dat] - add eax, ebx - pop bx - call read - jc ..found_disk_error - mov dx, cx - pop cx - xor eax, eax - sub cx, dx - jnz .loop - pop ax - ret - -load_file_ntfs: -; in: ss:bp = 0:dat -; in: es:bx = address to load file -; in: ds:si -> ASCIIZ name -; in: cx = limit in sectors -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - push es bx cx - mov eax, 5 ; root cluster - mov [bp + cur_obj - dat], root_string -.parse_dir_loop: - push ds si - call read_file_record -; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP - mov ax, [bp + freeattr - dat] - mov [bp + index_root - dat], ax - mov ax, 90h ; $INDEX_ROOT - xor bx, bx - call load_attr - mov si, noindex_string - jc find_error_si - mov ax, [bp + freeattr - dat] - mov [bp + index_alloc - dat], ax - mov ax, 0A0h ; $INDEX_ALLOCATION - call load_attr - jnc @f - mov [bp + index_alloc - dat], bx -@@: - push ds -; search for entry - mov si, [bp + index_root - dat] - push ss - pop ds - push 0x8100 - pop es - xor ecx, ecx - mov cl, 0x78 - xor bx, bx - push es - call read_file_chunk - pop ds - jc ..found_disk_error - test cx, cx - jz ..attr_overflow - mov si, invalid_read_request_string - cmp word [bx+10], 0 - jnz find_error_si -; calculate number of items in cache - mov di, [bx+8] ; subnode_size - mov ax, 0x4000 - sub ax, word [bp + frs_size - dat] - cwd - div di - test ax, ax - jz find_error_si - mov si, invalid_volume_msg - test di, 0x1FF - jnz find_error_si - pop cx - mov [bp + cur_index_seg - dat], cx - shl ax, 3 - sub cx, 6000h - mov si, cx - shr cx, 2 - shr si, 10-3 - add cx, ax - add si, 3480h - mov [bp + cur_index_cache - dat], si - add cx, 3500h - mov [ss:si+6], cx - mov dx, di - add bx, 10h -.scan_record: - add bx, [bx] -.scan: - test byte [bx+0Ch], 2 - jnz .look_child - movzx cx, byte [bx+50h] ; namelen - lea di, [bx+52h] ; name - push ds - pop es - pop si ds - push ds si - xor ax, ax -.1: - lodsb - cmp al, '/' - jnz @f - mov al, 0 -@@: - cmp al, 'A' - jb .nocapital - cmp al, 'Z' - ja .nocapital - or al, 20h -.nocapital: - cmp al, 'a' - jb .notletter - cmp al, 'z' - ja .notletter - or byte [es:di], 20h -.notletter: - scasw - loopz .1 - jb .look_child - ja @f - cmp byte [si], 0 - jz .file_found - cmp byte [si], '/' - jz .file_found -@@: - push es - pop ds - add bx, [bx+8] - jmp .scan -.look_child: - push es - pop ds - test byte [bx+0Ch], 1 - jz .not_found - mov si, [bp + index_alloc - dat] - test si, si - jz .not_found - add bx, [bx+8] - mov eax, [bx-8] - mov es, [bp + cur_index_seg - dat] - push si - mov si, [bp + cur_index_cache - dat] - call cache_lookup - pop si - pushf - mov bx, di - mov bh, 0 - shr bx, 3 - imul bx, dx - add bx, [bp + frs_size - dat] - popf - jnc .noread - push es - push dx - push ss - pop ds - movzx ecx, dx - shr cx, 9 - mul [bp + sect_per_clust - dat] - call read_attr - pop dx - pop es - push es - pop ds - call restore_usa -.noread: - push es - pop ds - add bx, 18h - jmp .scan_record -.not_found: - pop [bp + cur_obj - dat] - mov si, error_not_found - jmp find_error_si -.file_found: - pop [bp + cur_obj - dat] - pop cx - mov ax, [bp + index_root - dat] - mov [bp + freeattr - dat], ax - mov eax, [es:bx] - test byte [es:bx+48h+3], 10h - jz .regular_file - cmp byte [si], 0 - jz ..directory_error - inc si - jmp .parse_dir_loop -.regular_file: - cmp byte [si], 0 - jnz ..notdir_error -; read entry - call read_file_record - xor bx, bx - mov ax, 80h - call load_attr - mov si, nodata_string - jc find_error_si - mov si, [bp + index_root - dat] - mov [bp + freeattr - dat], si - push ss - pop ds - jmp load_file_common_end diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/bootsect.asm b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/bootsect.asm deleted file mode 100644 index eaf2c4e0a0..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/bootsect.asm +++ /dev/null @@ -1,1023 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - jmp far 0:real_start -; special text -org $+0x7C00 -real_start: -; initialize - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov es, ax - cld - sti - mov [bootdrive], dl -; check LBA support - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cl, 1 - jz err_ -; get file system information -; scan for Primary Volume Descriptor - db 66h - movi eax, 10h-1 -pvd_scan_loop: - mov cx, 1 - inc eax - mov bx, 0x1000 - call read_sectors - jnc @f -fatal_read_err: - mov si, aReadError -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -@@: - push ds - pop es - cmp word [bx+1], 'CD' - jnz pvd_scan_loop - cmp word [bx+3], '00' - jnz pvd_scan_loop - cmp byte [bx+5], '1' - jnz pvd_scan_loop -; we have found ISO9660 descriptor, look for type - cmp byte [bx], 1 ; Primary Volume Descriptor? - jz pvd_found - cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? - jnz pvd_scan_loop -; Volume Descriptor Set Terminator reached, no PVD found - fatal error - mov si, no_pvd - jmp err_ -pvd_found: - add bx, 80h - mov ax, [bx] - mov [lb_size], ax -; calculate number of logical blocks in one sector - mov ax, 800h - cwd - div word [bx] - mov [lb_per_sec], ax -; get location of root directory - mov di, root_location - movzx eax, byte [bx+1Dh] - add eax, [bx+1Eh] - stosd -; get memory size - int 12h - mov si, nomem_str - cmp ax, 71000h / 400h - jb err_ - shr ax, 1 - sub ax, 60000h / 800h - mov [size_rest], ax - mov [free_ptr], 60000h / 800h -; load path table -; if size > 62K => it's very strange, avoid using it -; if size > (size of cache)/2 => avoid using it too - mov ecx, [bx+4] - cmp ecx, 0x10000 - 0x800 - ja nopathtable - shr ax, 1 - cmp ax, 0x20 - jae @f - shl ax, 11 - cmp cx, ax - ja nopathtable -@@: -; size is ok, try to load it - mov [pathtable_size], cx - mov eax, [bx+12] - xor edx, edx - div dword [lb_per_sec] - imul dx, [bx] - mov [pathtable_start], dx - add cx, dx - call cx_to_sectors - xor bx, bx - push 6000h - pop es - call read_sectors - jc nopathtable -; path table has been loaded - inc [use_path_table] - sub [size_rest], cx - add [free_ptr], cx -nopathtable: -; init cache - mov ax, [size_rest] - mov [cache_size], ax - mov ax, [free_ptr] - mov [cache_start], ax -; load secondary loader - mov di, secondary_loader_info - call load_file - test bx, bx - jnz noloader -; set registers for secondary loader - mov ah, [bootdrive] - mov al, 'c' - mov bx, 'is' - mov si, callback - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 - -noloader: - mov si, aKernelNotFound - jmp err_ - -read_sectors: -; es:bx = pointer to data -; eax = first sector -; cx = number of sectors - pushad - push ds -do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - db 66h - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [cs:bootdrive] - mov ah, 42h - int 13h - jc diskreaderr -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 7 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popad - ret -diskreaderr: - add sp, 10h + 2*2 - pop ds - popad - stc -out_string.ret: - ret - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz .ret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aNoLBA db 'The drive does not support LBA!',0 -aReadError db 'Read error',0 -no_pvd db 'Primary Volume Descriptor not found!',0 -nomem_str db 'No memory',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 - -load_file: -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) -; parse path to the file - lea si, [di+6] - mov eax, [cs:root_location] - cmp [cs:use_path_table], 0 - jz parse_dir -; scan for path in path table - push di - push 6000h - pop es - mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table - mov dx, 1 ; dx = number of current entry in path table, start from 1 - mov cx, [cs:pathtable_size] -pathtable_newparent: - mov bx, dx ; bx = number of current parent in path table: root = 1 -scan_path_table_e: - call is_last_component - jnc path_table_scanned -scan_path_table_i: - cmp word [es:di+6], bx - jb .next - ja path_table_notfound - call test_filename1 - jc .next -@@: - lodsb - cmp al, '/' - jnz @b - jmp pathtable_newparent -.next: -; go to next entry - inc dx - movzx ax, byte [es:di] - add ax, 8+1 - and al, not 1 - add di, ax - sub cx, ax - ja scan_path_table_i -path_table_notfound: - pop di - mov ax, -1 - mov dx, ax - mov bx, 2 ; file not found - ret -path_table_scanned: - movzx eax, byte [es:di+1] - add eax, [es:di+2] - pop di -parse_dir: -; eax = logical block, ds:di -> information structure, ds:si -> file name -; was the folder already read? - push di ds - push cs - pop ds - mov [cur_desc_end], 2000h - mov bx, cachelist -.scan1: - mov bx, [bx+2] - cmp bx, cachelist - jz .notfound - cmp [bx+4], eax - jnz .scan1 -.found: -; yes; delete this item from the list (the following code will append this item to the tail) - mov di, [bx] - push word [bx+2] - pop word [di+2] - mov di, [bx+2] - push word [bx] - pop word [di] - mov di, bx - jmp .scan -.notfound: -; no; load first sector of the folder to get its size - push eax - push si - mov si, 1 - call load_phys_sector_for_lb_force - mov bx, si - pop si - pop eax - jnc @f -; read error - return -.readerr: - pop ds -.readerr2: - pop di - mov ax, -1 - mov dx, ax - mov bx, 3 - ret -@@: -; first item of the folder describes the folder itself -; do not cache too big folders: size < 64K and size <= (total cache size)/2 - cmp word [bx+12], 0 - jnz .nocache - mov cx, [cache_size] ; cx = cache size in sectors - shr cx, 1 ; cx = (cache size)/2 - cmp cx, 0x20 - jae @f - shl cx, 11 - cmp [bx+10], cx - ja .nocache -@@: -; we want to cache this folder; get space for it - mov cx, [bx+10] - call cx_to_sectors - jnz .yescache -.nocache: - push dword [bx+10] - pop dword [cur_nocache_len] - call lb_to_sector - push ds - pop es - pop ds -.nocache_loop: - push eax - mov dx, 1800h - call scan_for_filename_in_sector - mov cx, dx - pop eax - jnc .j_scandone - sub cx, bx - sub word [es:cur_nocache_len], cx - sbb word [es:cur_nocache_len+2], 0 - jb .j_scandone - ja @f - cmp word [es:cur_nocache_len], 0 - jz .j_scandone -@@: - mov cx, 1 - inc eax - push es - mov bx, 1000h - call read_sectors - pop es - jc .readerr2 - jmp .nocache_loop -.j_scandone: - jmp .scandone -.yescache: - push bx - mov bx, [cachelist.head] -.freeloop: - cmp cx, [size_rest] - jbe .sizeok -@@: -; if we are here: there is not enough free space, so we must delete old folders' data -; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2). -; one loop iteration: delete data of one folder - pusha - mov dx, [bx+10] - mov es, dx ; es = segment of folder data to be deleted - xor di, di - mov ax, [bx+8] - add ax, 0x7FF - rcr ax, 1 - shr ax, 10 - push ax - shl ax, 11-4 ; get number of paragraphs in folder data to be deleted - mov cx, [cache_size] - add cx, [cache_start] - push ds - push ax - add ax, dx - mov ds, ax - pop ax - shl cx, 11-4 - sub cx, dx ; cx = number of paragraphs to be moved - push si - xor si, si -; move cx paragraphs from ds:si to es:di to get free space in the end of cache -@@: - sub cx, 1000h - jbe @f - push cx - mov cx, 8000h - rep movsw - mov cx, ds - add cx, 1000h - mov ds, cx - mov cx, es - add cx, 1000h - mov es, cx - pop cx - jmp @b -@@: - add cx, 1000h - shl cx, 3 - rep movsw - pop si - pop ds -; correct positions in cache for existing items - mov cx, 80h - mov di, 8400h -.correct: - cmp [di+10], dx - jbe @f - sub [di+10], ax -@@: - add di, 12 - loop .correct -; some additional space is free now - pop ax - add [size_rest], ax - sub [free_ptr], ax -; add cache item to the list of free items - mov dx, [bx] - mov ax, [free_cache_item] - mov [bx], ax - mov [free_cache_item], bx - mov bx, dx -; current iteration done - popa - jmp .freeloop -.sizeok: - mov [cachelist.head], bx - mov word [bx+2], cachelist -; allocate new item in cache - mov di, [free_cache_item] - test di, di - jz .nofree - push word [di] - pop [free_cache_item] - jmp @f -.nofree: - mov di, [last_cache_item] - add [last_cache_item], 12 -@@: - pop bx - push si di -; mov [di+4], eax ; start of folder - scasd - stosd - push ax - mov ax, [free_ptr] - shl ax, 11-4 - mov [di+10-8], ax - mov es, ax - pop ax - add [free_ptr], cx - sub [size_rest], cx -; read folder data -; first sector is already in memory, 0000:bx - pusha - mov cx, [bx+10] - mov [di+8-8], cx ; folder size in bytes - mov si, bx - xor di, di - mov cx, 0x1800 - sub cx, si - rep movsb - pop ax - push di - popa -; read rest of folder - mov esi, dword [lb_per_sec] - add eax, esi - dec si - not si - and ax, si - mov si, word [bx+10] - mov bx, di - pop di - sub si, bx - jbe @f - mov [cur_limit], esi - call read_many_bytes - pop si - jnc .scan - jmp .readerr -@@: - pop si -.scan: -; now we have required cache item; append it to the end of list - mov bx, [cachelist.tail] - mov [cachelist.tail], di - mov [di+2], bx - mov word [di], cachelist - mov [bx], di -; scan for given filename - mov es, [di+10] - mov dx, [di+8] - pop ds - xor bx, bx - call scan_for_filename_in_sector -.scandone: - push cs - pop es - mov bx, 2000h - cmp bx, [es:cur_desc_end] - jnz filefound -j_notfound: - jmp path_table_notfound -filefound: -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b -@@: - mov cl, [es:bx+8] - test al, al - jz @f -; parse next component of file name - test cl, 2 ; directory? - jz j_notfound - mov eax, [es:bx] - pop di - jmp parse_dir -@@: - test cl, 2 ; directory? - jnz j_notfound ; do not allow read directories as regular files -; ok, now load the file - pop di - les bx, [di] - call normalize - movzx esi, word [di+4] ; esi = limit in 4K blocks - shl esi, 12 ; esi = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, 2000h -loadloop: - and [cur_start], 0 -.loadnew: - mov esi, [cur_limit] - mov eax, [cur_start] - add esi, eax - mov [overflow], 1 - sub esi, [di+4] - jb @f - xor esi, esi - dec [overflow] -@@: - add esi, [di+4] ; esi = number of bytes to read - mov [cur_start], esi - sub esi, eax - jz .loadcontinue - xor edx, edx - div dword [lb_size] ; eax = number of logical blocks to skip, - mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block - cmp byte [di+10], 0 - jnz .interleaved - add eax, [di] -; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - jc .readerr3 -.loadcontinue: - mov [cur_chunk], di - add di, 11 - cmp di, [cur_desc_end] - jae @f - cmp [cur_limit], 0 - jnz loadloop -@@: - mov bx, [overflow] -.calclen: -; calculate length of file - xor ax, ax - xor dx, dx - mov di, 2000h -@@: - add ax, [di+4] - adc dx, [di+6] - add di, 11 - cmp di, [cur_desc_end] - jb @b - ret -.interleaved: - mov [cur_unit_limit], esi - push esi -; skip first blocks - movzx ecx, byte [di+9] ; Unit Size - movzx esi, byte [di+10] ; Interleave Gap - add si, cx - mov edx, [di] -@@: - sub eax, ecx - jb @f - add edx, esi - jmp @b -@@: - add ecx, eax ; ecx = number of logical blocks to skip - lea eax, [ecx+edx] ; eax = first logical block - pop esi -.interleaved_loop: -; get number of bytes in current file unit - push eax - movzx eax, byte [di+9] - sub ax, cx - imul eax, dword [lb_size] - cmp eax, esi - ja .i2 -.i1: - xchg esi, eax -.i2: - pop eax - sub [cur_unit_limit], esi - push eax -; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - pop eax - jnc @f -.readerr3: - mov bx, 3 - jmp .calclen -@@: - mov esi, [cur_unit_limit] - test esi, esi - jz .loadcontinue - movzx ecx, byte [di+9] ; add Unit Size - add cl, byte [di+10] ; add Interleave Gap - adc ch, 0 - add eax, ecx - xor cx, cx - mov [first_byte], cx - jmp .interleaved_loop - -cx_to_sectors: - add cx, 7FFh - rcr cx, 1 - shr cx, 10 - ret - -is_last_component: -; in: ds:si -> name -; out: CF set <=> current component is not last (=> folder) - push si -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b - stc -@@: - pop si - ret - -test_filename1: -; in: ds:si -> filename, es:di -> path table item -; out: CF set <=> no match - pusha - mov cl, [es:di] - add di, 8 - jmp test_filename2.start -test_filename2: -; in: ds:si -> filename, es:bx -> directory item -; out: CF set <=> no match - pusha - mov cl, [es:bx+32] - lea di, [bx+33] -.start: - mov ch, 0 -@@: - lodsb - test al, al - jz .test1 - cmp al, '/' - jz .test1 - call toupper - mov ah, al - mov al, [es:di] - call toupper - inc di - cmp al, ah - loopz @b - jnz .next1 -; if we have reached this point: current name is done - lodsb - test al, al - jz .ret - cmp al, '/' - jz .ret -; if we have reached this point: current name is done, but input name continues -; so they do not match - jmp .next1 -.test1: -; if we have reached this point: input name is done, but current name continues -; "filename.ext;version" in ISO-9660 represents file "filename.ext" -; "filename." and "filename.;version" are also possible for "filename" - cmp byte [es:di], '.' - jnz @f - inc di - dec cx - jz .ret -@@: - cmp byte [es:di], ';' - jnz .next1 - jmp .ret -.next1: - stc -.ret: - popa - ret - -toupper: -; in: al=symbol -; out: al=symbol in uppercase - cmp al, 'a' - jb .ret - cmp al, 'z' - ja .ret - sub al, 'a'-'A' -.ret: - ret - -scan_for_filename_in_sector: -; in: ds:si->filename, es:bx->folder data, dx=limit -; out: CF=0 if found - push bx -.loope: - push bx -.loop: - cmp bx, dx - jae .notfound - cmp byte [es:bx], 0 - jz .loopd - test byte [es:bx+25], 4 ; ignore files with Associated bit - jnz .next - call test_filename2 - jc .next - push ds es di - push es - pop ds - push cs - pop es - mov di, [es:cur_desc_end] - movzx eax, byte [bx+1] - add eax, [bx+2] - stosd ; first logical block - mov eax, [bx+10] - stosd ; length - mov al, [bx+25] - stosb ; flags - mov ax, [bx+26] - stosw ; File Unit size, Interleave Gap size - mov [es:cur_desc_end], di - cmp di, 3000h - pop di es ds - jae .done - test byte [es:bx+25], 80h - jz .done -.next: - add bl, [es:bx] - adc bh, 0 - jmp .loop -.loopd: - mov ax, bx - pop bx -@@: - add bx, [cs:lb_size] - jz .done2 - cmp bx, ax - jb @b - jmp .loope -.notfound: - stc -.done: - pop bx -.done2: - pop bx - ret - -lb_to_sector: - xor edx, edx - div dword [lb_per_sec] - ret - -load_phys_sector_for_lb_force: -; in: eax = logical block, ds=0 -; in: si=0 - accept 0 logical blocks, otherwise force read at least 1 -; out: 0000:1000 = physical sector data; si -> logical block -; out: eax = next physical sector -; out: CF=1 if read error -; destroys cx -; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector - call lb_to_sector - or si, dx - jnz @f - mov si, 1800h - jmp .done -@@: - mov si, 1000h - imul dx, [lb_size] - add si, dx - mov cx, 1 - push es bx - push ds - pop es - mov bx, 1000h - call read_sectors - pop bx es - inc eax -.done: - ret - -normalize: -; in: es:bx = far pointer -; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10) - push ax bx - mov ax, es - shr bx, 4 - add ax, bx - mov es, ax - pop bx ax - and bx, 0x0F - ret - -read_many_bytes: - and [first_byte], 0 -read_many_bytes.with_first: -; read esi bytes from logical block dx:ax to buffer es:bx -; out: CF=1 <=> disk error - push di -; load first physical sector - push bx si - mov si, [first_byte] - call load_phys_sector_for_lb_force - jnc @f - pop si bx -.ret: - pop di - ret -@@: - add si, [first_byte] - mov ecx, 1800h - sub cx, si - mov ebx, esi - pop bx - sub ebx, ecx - jnc @f - add cx, bx - xor ebx, ebx -@@: - pop di - sub [cur_limit], ecx - rep movsb - mov esi, ebx - mov bx, di - call normalize -; load other physical sectors -; read esi bytes from physical sector eax to buffer es:bx - test esi, esi - jz .ret - push esi - add esi, 0x7FF - and si, not 0x7FF - cmp esi, [cur_limit] - jbe .okplace -.noplace: - sub esi, 800h -.okplace: - shr esi, 11 ; si = number of sectors - mov cx, si - jz @f - call read_sectors -@@: - pop esi - jc .ret - movzx ecx, cx - add eax, ecx - shl ecx, 11 - sub [cur_limit], ecx - sub esi, ecx - jc .big - jz .nopost - push bx es - push ds - pop es - mov bx, 1000h - mov cx, 1 - call read_sectors - pop es di - jc .ret2 - mov cx, si - mov si, 1000h - sub word [cur_limit], cx - sbb word [cur_limit+2], 0 - rep movsb - mov bx, di - call normalize -.nopost: - clc -.ret2: - pop di - ret -.big: - mov ax, es - sub ax, 80h - mov es, ax - add bx, 800h - add bx, si - call normalize - sub [cur_limit], esi - jmp .nopost - -; Callback function for secondary loader -callback: -; in: ax = function number; only function 1 is defined for now - dec ax - jz callback_readfile - dec ax - jz callback_continueread - stc ; unsupported function - retf - -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file - clc ; function is supported - retf - -callback_continueread: -; function 2: continue to read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - les bx, [di] - call normalize - movzx esi, word [di+4] ; si = limit in 4K blocks - shl esi, 12 ; bp:si = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, [cur_chunk] - call loadloop.loadnew - clc ; function is supported - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kernel.mnt',0 -aKernelNotFound db 'Fatal error: cannot load the kernel',0 - -align 2 -cachelist: -.head dw cachelist -.tail dw cachelist -free_cache_item dw 0 -last_cache_item dw 0x8400 - -use_path_table db 0 -bootdrive db ? -align 2 -lb_size dw ? ; Logical Block size in bytes - dw 0 ; to allow access dword [lb_size] -lb_per_sec dw ? ; Logical Blocks per physical sector - dw 0 ; to allow access dword [lb_per_sec] -free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) -size_rest dw ? ; free space in cache (in blocks) -cache_size dw ? -cache_start dw ? -pathtable_size dw ? -pathtable_start dw ? -root_location dd ? -cur_desc_end dw ? -cur_nocache_len dd ? -cur_limit dd ? -cur_unit_limit dd ? -overflow dw ? -cur_chunk dw ? -first_byte dw ? -cur_start dd ? - -times 83FCh-$ db 0 - db 43h -; just to make file 2048 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - - dw 0xAA55 ; this is not required for CD, but to be consistent... diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/bootsect.txt b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/bootsect.txt deleted file mode 100644 index 7fedad1772..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/bootsect.txt +++ /dev/null @@ -1,418 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.? - -Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660. -(ISO-9660 и её расширения - стандарт для CD; DVD может использовать -либо ISO-9660, либо UDF.) - -===================================================================== - -Требования для работы: -1) Сам бутсектор и все используемые файлы должны быть читабельны. -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 452K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 14.09.2008): - стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf - стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Схема используемой памяти: - 1000-1800 временный буфер для чтения одиночных секторов - ...-7C00 стек - 7C00-8400 код бутсектора - 8400-8A00 информация о кэше для папок: массив входов следующего - формата: - dw следующий элемент в L2-списке закэшированных папок, - упорядоченном по времени использования - (голова списка - самый старый); - dw предыдущий элемент в том же списке; - dd первый сектор папки; - dw размер папки в байтах; - dw сегмент кэша - 60000-... содержимое Path Table, если она используется - + кэш для папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip - равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает - дальний прыжок на самого себя с целью получить cs=0 (в некоторых - местах используется адресация переменных загрузчика через cs, поскольку - и ds, и es могут быть заняты под другие сегменты). -2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом) - и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления - и разрешённые прерывания. Сохраняет идентификатор загрузочного диска - в специальную переменную. -3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять - LBA-функции. -4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту - ISO9660 со смещения 10h начинается цепочка описателей тома, - завершающаяся специальным описателем (Volume Descriptor Set - Terminator). Код по очереди считывает все сектора, пока не наткнётся - либо на искомый описатель, либо на терминатор. Во втором случае - выдаётся соответствующее сообщение, и загрузка прекращается. -Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD - располагается в последней сессии. И спецификация ElTorito загрузочного - CD оперирует также с последней сессией. Однако на практике оказывается, - что: во-первых, реальные BIOSы не понимают мультисессионных CD и - всегда используют первую сессию; во-вторых, BIOSовский int 13h просто - не позволяет получить информацию о последней сессии. В связи с этим - загрузчик также использует первую сессию. (В-третьих, в одной из BIOS - обнаружилась заготовка, которая в случае запроса сектора 10h, в котором - во всех нормальных случаях и располагается PVD, перенаправляет его - на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с - последней сессии, то благодаря заготовке загрузчик без всяких - модификаций также читал бы последнюю сессию.) -5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во - внутренние переменные: размер логического блока (согласно спецификации, - должен быть степенью двойки от 512 до размера логического сектора, - равного 2048 для CD и DVD); положение на диске корневой папки; - вычисляет число блоков в секторе (из предыдущего примечания следует, - что оно всегда целое и само является степенью двойки). -6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет - размер пространства, которое может использовать загрузчик (от - адреса 6000:0000 до конца доступной памяти). -7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит - базовую информацию обо всех папках на диске. Если таблица слишком - велика (больше 62K или больше половины доступной памяти), то она - игнорируется. Если таблица путей недоступна, то запрос типа - dir1/dir2/dir3/file приведёт к последовательному разбору корневой - папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать - саму таблицу путей (где записано положение папки dir1/dir2/dir3) - и папку dir3. Если таблица загружена, то соответственно уменьшается - объём оставшейся доступной памяти и увеличивается указатель на - свободную область. -8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7 - доступная память отводится под этот кэш). -9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке - печатает соответствующее сообщение и прекращает загрузку с CD. -10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует - тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is' - идентифицирует файловую систему ISO-9660; ds:si указывает на - callback-функцию, которую может вызывать вторичный загрузчик. -11. Передаёт управление вторичному загрузчику, совершая дальний прыжок - на адрес, куда kord/loader был загружен. - -Функция обратного вызова для вторичного загрузчика (callback): - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -Перенаправляет запрос соответствующей локальной процедуре (load_file при - первом запросе на загрузку файла, loadloop.loadnew при последующих - запросах на продолжение загрузки файла). - -Вспомогательные процедуры. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения секторов (read_sectors): -на входе должно быть установлено: - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор - cx = число секторов -на выходе: - es:bx указывает на конец буфера, в который были прочитаны данные - если произошла ошибка чтения, флаг CF установлен -1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации - число читаемых секторов не превосходило 7Fh (требование спецификации - EDD BIOS). -2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек, - устанавливает CF=1 и выходит из процедуры. - Очищает стек от пакета, сформированного на предыдущем шаге. -5. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 2. - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -Процедура загрузки файла (load_file): -на входе: - ds:di = указатель на информационную структуру, описанную в спецификации - на загрузчик, а также в комментариях к коду -на выходе: - bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть, - 2=файл не найден, 3=ошибка чтения - dx:ax = размер файла, 0xFFFFFFFF, если файл не найден -1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице, - иначе переходит сразу к шагу 4, установив eax = начальный блок - корневой папки. -2. Устанавливает es:di на начало таблицы путей. Ограничение на размер - гарантирует, что вся таблица помещается в сегменте 6000h. - Инициализирует dx (в котором будет хранится номер текущего входа в - таблице, считая с 1), cx (размер оставшегося участка таблицы), - bx (номер входа, соответствующего родительской папке для текущего - рассматриваемого участка пути). -3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы - таблицы путей упорядочены (подробно о порядке написано в спецификации), - так что если родительский элемент для очередного входа больше нужного, - то нужного входа в таблице нет совсем, и в этом случае происходит - выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент, - соответствующий очередной папке в запрошенном пути, то на рассмотрение - выносится следующая компонента пути. Если эта компонента последняя, - то осталось найти файл в папке, и код переходит к пункту 4, - установив eax = начальный блок этой папки. Если же нет, то эта - компонента должна задавать имя папки, и код возвращается к пункту 3, - скорректировав указатель на имя ds:si и номер родительского входа bx. -4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax - и указатель на имя файла относительно этой папки в ds:si. Если - папку искали по таблице путей, то имя файла уже не содержит подпапок; - если же нет, то подпапки вполне возможны. -5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый - из которых задаётся отдельным входом в папке. Информация обо всех - таких кусках при просмотре папки запоминается в области, начинающейся - с адреса 0000:2000. Переменная cur_desc_end содержит указатель на - конец этой области, он же указатель, куда будет помещена информация - при обнаружении следующего входа. (Папки, согласно спецификации, - должны задаваться одним куском.) -6. Код сначала ищет запрошенную папку в кэше папок. -7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка, - отсортированного по давности последнего обращения и код переходит к - п.15. (Следующим действием станет добавление папки в конец списка.) -8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать - с диска. Сначала загружается первый сектор (физический сектор, - содержащий первый логический блок). При ошибке ввода/вывода - происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF. - Первый элемент папки содержит информацию о самой этой папке, конкретно - загрузчик интересуется её размером. -9. Если размер папки слишком большой (больше или равен 64K либо больше половины - общего размера кэша), то кэшироваться она не будет. В этом случае код - считывает папку посекторно во временный буфер (0000:1000) и посекторно - сканирует на наличие запрошенного имени, пока не найдёт такого имени - или пока не кончатся данные. (Цикл начинается со сканирования, - поскольку первая часть данных уже прочитана.) В конце код переходит - к п.17. -10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно - обеспечить достаточное количество свободного места. Для этого может - понадобиться выкинуть какое-то количество старых данных (цикл - parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря, - свободное пространство окажется разорванным на несколько фрагментов. - Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает - все следующие за ней данные назад по памяти и соответственно - корректирует информацию о местонахождении данных в информации о кэше. - При этом новое пространство всегда добавляется в конец доступной - памяти. Цикл выкидывания продолжается, пока не освободится место, - достаточное для хранения папки. Из-за ограничений на размер кэшируемых - папок в конце концов место найдётся. -11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы - организуются в единый список свободных элементов; если он непуст, - то очередной элемент берётся из этого списка; если же пуст, то - берётся совсем новый элемент из области памяти, предназначенной для - элементов кэша. -12. В новом элементе заполняются поля начального блока, сегмента с данными, - размера в байтах. -13. Уже прочитанные данные первого физического сектора пересылаются на - законное место в кэше. -14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся - данные с диска. При ошибке чтения, как и раньше, происходит выход из - процедуры с bx=3, ax=dx=0xFFFF. -15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов - кэша. -16. Загрузчик ищет запрошенное имя в загруженных данных папки. - (Из-за ограничений на размер кэшируемой папки все данные располагаются - в одном сегменте.) -17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено - никаких кусков файла, то cur_desc_end такой же, каким был вначале. - В этом случае процедура рапортует о ненайденном файле и выходит. -18. (filefound) Пропускает текущую компоненту имени. Если она была не последней - (то есть подпапкой, в которой нужно производить дальнейший поиск), - то код проверяет, что найденный вход - действительно подпапка, - устанавливает новый стартовый блок и возвращается к п.4. - Если же последней, то код проверяет, что найденный вход - регулярный - файл и начинает загрузку файла. -19. Нормализует указатель, по которому требуется прочитать файл. Под - нормализацией понимается преобразование типа - 1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса, - но гарантирует отсутствие переполнений: в приведённом примере попытка - переслать 400h байт по rep movsb приведёт к тому, что последние 8 - байт запишутся не в нужное место, а на 64K раньше. Далее нормализация - будет производиться после каждой пересылки. В cur_limit помещает - предельный размер для чтения в байтах. -20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты - (пункты 21-27). -21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое - нужно пропустить с начала фрагмента. -22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего - шага, либо напрямую из callback-процедуры при запросе на продолжение - чтения. Для этого и нужна вышеупомянутая переменная [cur_start] - - при продолжении чтения, прервавшегося из-за конца буфера посередине - фрагмента, там будет записано соответствующее значение. -23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента - и максимальной длины остатка. Если второе строго меньше, то - запоминает, что файл слишком большой и прочитан только частично. - Определяет новое значение числа прочитанных байт во фрагменте - для возможных будущих вызовов [cur_start]. -24. Переводит пропускаемое число байт в число логических блоков и байт - в первом блоке, последнее число записывает в переменную [first_byte], - откуда её позднее достанет read_many_bytes.with_first. -25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код - определяет начальный блок фрагмента и вызывает вспомогательную функцию - чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения) - и выходит из цикла к п.28. -26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала - код пропускает нужное количество непрерывных частей, а потом - в цикле загружает непрерывные части с помощью той же функции, - в промежутках между частями увеличивая номер начального блока. - Пока не кончится фрагмент или пока не наберётся запрошенное число байт. - При ошибке чтения делает то же самое, что и в предыдущем случае. -27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер - ещё не достигнут, переходит к следующему фрагменту и п.20. В противном - случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли - переполнение в п.23. -28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех - фрагментов. - -Процедура проверки, является ли текущая компонента имени файла последней - (is_last_component): -на входе: ds:si = указатель на имя -на выходе: флаг CF установлен, если есть последующие компоненты -В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый, - то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF - и выходит. - -Процедуры проверки на совпадение текущей компоненты имени файла с именем -текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки): -на входе: ds:si = указатель на имя, es:di = указатель на элемент - таблицы путей для test_filename1, папки для test_filename2 -на выходе: CF установлен, если имена не совпадают -В цикле проверяет совпадение приведённых к верхнему регистру очередных символов - имён файла и элемента. Условия выхода из цикла: закончилось имя файла - в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение - возможно только в ситуации типа имени "filename.ext" и элемента - "filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми - именами в папке отсортированы по убыванию версий); - несовпадение символов - означает, что имена не совпадают; - закончилось имя элемента - нужно проверить, закончилось ли при этом имя - файла, и в зависимости от этого принимать решение о совпадении. - -Процедура приведения символа в верхний регистр (toupper): -на входе: ASCII-символ -на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к - нему неприменимо) -Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A', - остальные символы не трогает. - -Процедура поиска файла в данных папки (scan_for_filename_in_sector): -на входе: - ds:si = указатель на имя файла - es:bx = указатель на начало данных папки - es:dx = указатель на конец данных папки -на выходе: - CF сброшен, если найден финальный фрагмент файла - (и дальше сканировать папку не нужно) - в область для информации о фрагментах файла записывается найденное -В цикле просматривает все входы папки, пропуская те, у которых установлен - бит Associated (это специальные входы, дополняющие основные). Если - имя очередного входа совпадает с именем файла, то запоминает новый - фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent), - то код выходит с CF=0. Если достигнут конец данных, то код выходит - с CF=1. Если очередной вход нулевой (первый байт настоящего входа - содержит длину и не может быть нулём), то процедура переходит к - рассмотрению следующего логического блока. При этом потенциально - возможно переполнение при добавлении размера блока; поскольку такой - сценарий означает, что процедура вызвана для кэшированной папки - с размером почти 64K и началом данных bx=0 (это свойство вызывающего - кода), а размер блока - степень двойки, то после переполнения всегда - bx=0, так что это можно обнаружить по взведённому ZF после сложения; - в этом случае также происходит выход (а после переполнения CF=1). - -Процедура перевода логического блока в номер сектора: -на входе: eax = логический блок -на выходе: eax = физический сектор, dx = номер логического блока в секторе -Осуществляет обычное деление 32-битного числа на 32-битное (число логических - блоков в секторе, хранящееся во внутренней переменной). - -Процедура загрузки физического сектора, содержащего указанный логический блок - (load_phys_sector_for_lb_force): -на входе: eax = логический блок; - si - индикатор, задающий, следует ли читать данные в случае, - если логический блок начинается с начала физического: - si = 0 - не нужно, si ненулевой - нужно -на выходе: - физический сектор загружен по адресу 0000:1000 - si указывает на данные логического блока - CF установлен при ошибке чтения -Преобразует предыдущей процедурой номер логического блока в номер физического - сектора и номер логического блока внутри сектора; если последняя - величина нулевая и никаких действий в этом случае не запрошено (si=0), - то ничего и не делает; иначе устанавливает si в соответствии с ней - и читает сектор. - -Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков - (read_many_bytes и read_many_bytes.with_first): -на входе: - eax = логический блок - esi = число байт для чтения - es:bx = указатель на начало буфера, куда будут прочитаны данные - cur_limit = размер буфера (не меньше esi) -на выходе: - es:bx указывает на конец буфера, в который были прочитаны данные - если произошла ошибка чтения, флаг CF установлен - cur_limit соответствующим образом уменьшен -Отличие двух процедур: вторая дополнительно принимает во внимание переменную - [first_byte], начиная чтение первого блока со смещения [first_byte]; - соответственно, первая читает блок с начала, обнуляя [first_byte] - при входе. -1. Отдельно считывает первый физический сектор во временную область 0000:1000, - если первый логический блок начинается не с начала сектора. При - ошибке чтения выходит из процедуры. -2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1, - в буфер. Нормализует указатель на буфер. -3. Если все необходимые данные уже прочитаны, выходит из процедуры. -4. Дальнейшие данные находятся в нескольких физических секторах, при этом, - возможно, последний сектор считывать нужно не целиком. -5. Если в буфере есть место для считывания всех секторов, то сразу читаются - все сектора, после чего указатель на буфер нужным образом уменьшается. -6. Если же нет, то считываются все сектора, кроме последнего, после чего - последний сектор считывается отдельно во временную область, и уже - оттуда нужная часть данных копируется в буфер. diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/build.bat b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/build.bat deleted file mode 100644 index 93b242702f..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/cdfs/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/bootsect.asm b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/bootsect.asm deleted file mode 100644 index 033257c541..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/bootsect.asm +++ /dev/null @@ -1,392 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -use_lba = 0 - org 0x7C00 - jmp start - nop -; FAT parameters, BPB -; note: they can be changed at install, replaced with real values -; these settings are for most typical 1.44M floppies - db 'KOLIBRI ' ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db 1 -BPB_RsvdSecCnt dw 1 -BPB_NumFATs db 2 -BPB_RootEntCnt dw 0xE0 - dw 2880 ; BPB_TotSec16 - db 0xF0 ; BPB_Media -BPB_FATSz16 dw 9 -BPB_SecPerTrk dw 18 -BPB_NumHeads dw 2 -BPB_HiddSec dd 0 - dd 0 ; BPB_TotSec32 -BS_DrvNum db 0 - db 0 ; BS_Reserved1 - db ')' ; BS_BootSig - dd 12344321h ; BS_VolID -filename: - db 'KORD.OS ' ; BS_VolLab - db 'FAT12 ' ; BS_FilSysType -; Used memory map: -; 8000:0000 - current directory -; 9000:0000 - root directory data [cached] -start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - mov [bp+BS_DrvNum-0x7C00], dl -if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cx, 1 - jz err_ -else - mov ah, 8 - int 13h - jc @f ; on error, assume that BPB geometry is valid - mov al, dh - mov ah, 0 - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx -@@: -end if -; get FAT parameters - xor bx, bx - mov al, [bp+BPB_NumFATs-0x7C00] - mov ah, 0 - mul [bp+BPB_FATSz16-0x7C00] - add ax, [bp+BPB_RsvdSecCnt-0x7C00] - adc dx, bx - push dx - push ax ; root directory start = dword [bp-4] - mov cx, [bp+BPB_RootEntCnt-0x7C00] - add cx, 0xF - rcr cx, 1 - shr cx, 3 ; cx = size of root directory in sectors - add ax, cx - adc dx, bx - push dx - push ax ; data start = dword [bp-8] -; load start of root directory (no more than 0x2000 bytes = 0x10 sectors) - cmp cx, 0x10 - jb @f - mov cx, 0x10 -@@: - mov ax, [bp-4] - mov dx, [bp-2] - push 0x9000 - pop es - call read_sectors - add word [bp-4], cx ; dword [bp-4] = start of non-cached root data - adc word [bp-2], bx -; load kordldr.f12 - mov si, main_loader - call lookup_in_root_dir - jc noloader - test byte [es:di+11], 10h ; directory? - jz kordldr_ok -noloader: - mov si, aLoaderNotFound -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -kordldr_ok: - mov ax, [es:di+26] ; get file cluster - mov bx, 0x7E00 - xor cx, cx - mov es, cx - sub ax, 2 - jc noloader - push bx ; save return address: bx = 7E00 - mov cl, [bp+BPB_SecsPerClus-0x7C00] - mul cx -; fall through - 'ret' in read_sectors will return to 7E00 - -read_sectors2: -; same as read_sectors, but dx:ax is relative to start of data - add ax, [bp-8] - adc dx, [bp-6] -read_sectors: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; dx:ax = first sector -; cx = number of sectors - pusha - add ax, word [bp+BPB_HiddSec-0x7C00] - adc dx, word [bp+BPB_HiddSec+2-0x7C00] -if use_lba - push ds -do_read_sectors: - push ax - push cx - push dx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push dx - push ax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp+BS_DrvNum-0x7C00] - mov ah, 42h - int 13h - mov si, aReadError - jc err_ -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - mov si, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop dx - pop cx - pop ax - add ax, si - adc dx, 0 - sub cx, si - jnz do_read_sectors - pop ds - popa - ret -else -do_read_sectors: - pusha - pop di - push bx - -; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx - mov si, ax - xchg ax, dx - xor dx, dx - div [bp+BPB_SecPerTrk-0x7C00] - push ax - mov ax, si - div [bp+BPB_SecPerTrk-0x7C00] - mov bx, dx ; bx=sector-1 - pop dx - -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] - -; number of sectors: read no more than to end of track - push bx - sub bx, [bp+BPB_SecPerTrk-0x7C00] - neg bx - cmp cx, bx - jbe @f - mov cx, bx -@@: - pop bx - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - mov di, cx - mov dh, dl - mov dl, [bp+BS_DrvNum-0x7C00] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err_ -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push di - popa - add ax, di - adc dx, 0 - sub cx, di - jnz do_read_sectors - popa - ret -end if - -scan_for_filename: -; in: ds:si -> 11-bytes FAT name -; in: es:0 -> part of directory data -; in: cx = number of entries -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - xor di, di - push cx -sloop: - cmp byte [es:di], 0 - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone -scont: - add di, 0x20 - loop sloop - inc cx ; clear ZF flag -snotfound: - stc -sdone: - pop cx -lrdret: - ret - -lookup_in_root_dir: -; ss:bp = 0:7C00 -; in: ds:si -> 11-bytes FAT name -; out: if found: CF=0, es:di -> directory entry -; out: if not found: CF=1 - mov cx, [bp+BPB_RootEntCnt-0x7C00] - push cx -; first, look in root directory cache - push 0x9000 - pop es - test ch, ch - jz @f - mov cx, 0x100 -@@: - mov ax, [bp-4] - mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory -lrdloop: - call scan_for_filename - pop bx - jz lrdret - sub bx, cx - mov cx, bx - stc - jz lrdret -; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries - push cx - cmp ch, 0x8 - jb @f - mov cx, 0x800 -@@: - push 0x8000 - pop es - push cx - push es - xor bx, bx - add cx, 0xF - shr cx, 4 - call read_sectors - pop es - add ax, cx - adc dx, bx - pop cx - jmp lrdloop - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz lrdret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aReadError db 'Read error',0 -if use_lba -aNoLBA db 'The drive does not support LBA!',0 -end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F1X' - -if use_lba - db 0 ; make bootsector 512 bytes in length -end if - -; bootsector signature - dw 0xAA55 - -; display offsets of all procedures used by kordldr.f12.asm -macro show [procedure] -{ - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 -} - -show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/bootsect.txt b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/bootsect.txt deleted file mode 100644 index c0449aa693..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/bootsect.txt +++ /dev/null @@ -1,360 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Встречаются вирус и FAT. - - Привет, ты кто? - - Я? Вирус. - - A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... - -Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт. - -===================================================================== - -Есть две версии в зависимости от того, поддерживает ли носитель LBA, -выбор осуществляется установкой константы use_lba в первой строке исходника. -Требования для работы: -1) Сам бутсектор, первая копия FAT и все используемые файлы -должны быть читабельны. -2) Минимальный процессор - 80186. -3) В системе должно быть как минимум 592K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер -занимает 12 бит в таблице FAT, так что общий размер не превосходит -0x17EE = 6126 байт. Вся таблица помещается в памяти. -Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый -кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит -0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в -этом случае несколько нецелесообразно считывать всю таблицу, поскольку -на практике нужна только небольшая её часть. Поэтому место в памяти -резервируется, но данные считываются только в момент, когда к ним -действительно идёт обращение. - -Схема используемой памяти: - ...-7C00 стек - 7C00-7E00 код бутсектора - 7E00-8200 вспомогательный файл загрузчика (kordldr.f1x) - 8200-8300 список загруженных секторов таблицы FAT16 - (1 = соответствующий сектор загружен) - 60000-80000 загруженная таблица FAT12 / место для таблицы FAT16 - 80000-90000 текущий кластер текущей рассматриваемой папки - 90000-92000 кэш для корневой папки - 92000-... кэш для некорневых папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 7 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед - кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало - бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - - это освобождает ds и экономит на размере кода). -2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h - прерывания 13h. Если нет, переходит на код обработки ошибок с - сообщением об отсутствии LBA. -CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и - записывает полученные данные поверх BPB. Если вызов завершился ошибкой, - предполагает уже существующие данные корректными. -3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки - и начальный сектор данных. Кладёт их в стек; впоследствии они - всегда будут лежать в стеке и адресоваться через bp. -4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых - секторов - минимум из размера корневой папки, указанного в BPB, и 16 - (размер кэша для корневой папки - 2000h байт = 16 секторов). -5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если - он оказывается папкой, или если файл имеет нулевую длину - - переходит на код обработки ошибок с сообщением о - ненайденном загрузчике. - Замечание: на этом этапе загрузки искать можно только в корневой - папке и только имена, заданные в формате файловой системе FAT - (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны - быть заглавными, при необходимости имя и расширение дополняются - пробелами, разделяющей точки нет, завершающего нуля нет). -6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт - ему управление. При этом в регистрах dx:ax оказывается абсолютный - номер первого сектора kordldr.f1x, а в cx - число считанных секторов - (равное размеру кластера). - -Вспомогательные процедуры бутсектора. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения секторов (read_sectors и read_sectors2): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - dx:ax = стартовый сектор (относительно начала логического диска - для read_sectors, относительно начала данных для read_sectors2) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные -0. Если вызывается read_sectors2, она переводит указанный ей номер сектора - в номер относительно начала логического диска, прибавляя номер сектора - начала данных, хранящийся в стеке как [bp-8]. -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя значение соответствующего поля из BPB. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура поиска элемента по имени в уже прочитанных данных папки - (scan_for_filename): -на входе должно быть установлено: - ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя, - 3 на расширение, все буквы заглавные, если имя/расширение - короче, оно дополняется до максимума пробелами) - es = сегмент данных папки - cx = число элементов в прочитанных данных -на выходе: ZF определяет, нужно ли продолжать разбор данных папки - (ZF=1, если либо найден запрошенный элемент, либо достигнут - конец папки); CF определяет, удалось ли найти элемент с искомым именем - (CF=1, если не удалось); если удалось, то es:di указывает на него. -scan_for_filename считает, что данные папки размещаются начиная с es:0. -Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки -проверяет имена. - -Процедура поиска элемента в корневой папке (lookup_in_root_dir): -на входе должно быть установлено: - ss:bp = 0:7C00 - ds:si = указатель на имя файла в формате FAT (см. выше) -на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то - CF сброшен и es:di указывает на элемент папки -Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле - сканирует элементы; если по результатам сканирования обнаруживает, - что нужно читать папку дальше, то считывает не более 0x10000 = 64K - байт (ограничение введено по двум причинам: во-первых, чтобы заведомо - не вылезти за пределы используемой памяти, во-вторых, сканирование - предполагает, что все обрабатываемые элементы располагаются в одном - сегменте) и продолжает цикл. -Сканирование прекращается в трёх случаях: обнаружен искомый элемент; - кончились элементы в папке (судя по числу элементов, указанному в BPB); - очередной элемент папки сигнализирует о конце (первый байт нулевой). - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -===================================================================== - -Работа вспомогательного загрузчика kordldr.f1x: -1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. - В зависимости от этого устанавливает смещения используемых процедур - бутсектора. Критерий проверки: scan_for_filename должна начинаться - с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может - с равным успехом ассемблироваться и как 33 FF, но fasm генерирует - именно такую форму). -2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска - адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с - ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента - место должно быть, отсюда ограничение в 592 Kb (94000h байт). - Замечание: этот размер не может превосходить 0A0000h байт и - на практике оказывается немного (на 1-2 килобайта) меньшим из-за - наличия дополнительной области данных BIOS "вверху" базовой памяти. -3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной - спецификации от Microsoft (версия 1.03 спецификации датирована, - к слову, 06 декабря 2000 года), разрядность FAT определяется - исключительно числом кластеров: максимальное число кластеров на - FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12 - может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2, - а число 0xFF7 не может быть корректным номером кластера. - Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается - по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает - явно неверно, считая, что 0xFF6 (или меньше) кластеров означает - FAT12-том, в результате получается, что последний кластер - (в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe - [встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик - [бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы - лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили - в соответствии со спецификацией. Linux при определении FAT12/FAT16 - честно следует спецификации. - Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT - Microsoft если и будет исправлять ошибки, то согласно собственному - описанию. -4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000. - Если размер, указанный в BPB, превосходит 12 секторов, - это означает, что заявленный размер слишком большой (это не считается - ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12 - заведомо влезает в такой объём данных). -Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор - FAT не загружен (они будут подгружаться позднее, когда понадобятся - и только те, которые понадобятся). -5. Если кластер равен сектору, то бутсектор загрузил только часть файла - kordldr.f1x, и загрузчик подгружает вторую свою часть, используя - значения регистров на входе в kordldr.f1x. -6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не - найден, или оказался папкой, или оказался слишком большим, то переходит - на код обработки ошибок из бутсектора с сообщением - "Fatal error: cannot load the secondary loader". - Замечание: на этом этапе имя файла уже можно указывать вместе с путём - и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов - по-прежнему нет. -7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. - Это нужно, чтобы последующие обращения к коду бутсектора в случае - ошибок чтения не выводил соответствующее сообщение с последующей - перезагрузкой, а рапортовал об ошибке чтения, которую мог бы - как-нибудь обработать вторичный загрузчик. -8. Если загрузочный диск имеет идентификатор меньше 0x80, - то устанавливает al='f' ("floppy"), ah=идентификатор диска, - иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). - Устанавливает bx='12', если тип файловой системы - FAT12, и - bx='16' в случае FAT16. Устанавливает si=смещение функции обратного - вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес. -9. Передаёт управление по адресу 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным - кодом должна указывать на 0:7C00, а -8 берётся от того, что - инициализирующий код бутсектора уже поместил в стек 2 двойных слова, - и они должны сохраняться в неизменности. -2. Разбирает переданные параметры, выясняет, какое действие запрошено, - и вызывает нужную вспомогательную процедуру. -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры kordldr.f1x. -Процедура получения следующего кластера в FAT (get_next_cluster): -1. Вспоминает разрядность FAT, вычисленную ранее. -Для FAT12: -2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана - вся таблица FAT. -3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте - слова, задающего следующий кластер. Загружает слово по этому адресу. -4. Если кластер имеет нечётный номер, то соответствующий ему элемент - располагается в старших 12 битах слова, и слово нужно сдвинуть вправо - на 4 бита; в противном случае - в младших 12 битах, и делать ничего не - надо. -5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7: - номера нормальных кластеров меньше, и флаг CF устанавливается; - специальные значения EOF и BadClus сбрасывают флаг CF. -Для FAT16: -2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных - в таблице FAT. -3. Если сектор ещё не загружен, то загружает его. -4. Вычисляет смещение данных для конкретного кластера относительно начала - сектора. -5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3. -6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг - CF устанавливается; специальные значения EOF и BadClus сбрасывают CF. - -Процедура загрузки файла (load_file): -1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. -2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты - разделяются символом '/') в FAT-формат 8+3. Если это невозможно - (больше 8 символов в имени, больше 3 символов в расширении или - больше одной точки), возвращается с ошибкой. -3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой - папки используется процедура из бутсектора. Для остальных папок: - a) Проверяет, есть ли такая папка в кэше некорневых папок. - (Идентификация папок осуществляется по номеру начального кластера.) - Если такой папки ещё нет, добавляет её в кэш; если тот переполняется, - выкидывает папку, к которой дольше всего не было обращений. (Для - каждого элемента кэша хранится метка от 0 до (размер кэша)-1, - определяющая его номер при сортировке по давности последнего обращения. - При обращении к какому-то элементу его метка становится нулевой, - а те метки, которые меньше старого значения, увеличиваются на единицу.) - б) Просматривает в поисках запрошенного имени все элементы из кэша, - используя процедуру из бутсектора. Если обнаруживает искомый элемент, - переходит к шагу 4. Если обнаруживает конец папки, возвращается из - процедуры с ошибкой. - в) В цикле считывает папку посекторно. При этом пропускает начальные - секторы, которые уже находятся в кэше и уже были просмотрены. Каждый - прочитанный сектор копирует в кэш, если там ещё остаётся место, - и просматривает в нём все элементы. Работает, пока не случится одно из - трёх событий: найден искомый элемент; кончились кластеры (судя по - цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце - (первый байт нулевой). В двух последних случаях возвращается с ошибкой. -4. Проверяет тип найденного элемента (файл/папка): последний элемент в - запрошенном имени должен быть файлом, все промежуточные - папками. - Если текущий компонент имени - промежуточный, продвигает текущую - рассматриваемую папку и возвращается к пункту 2. -5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный - при вызове буфер последовательными вызовами функции бутсектора; - при этом если несколько кластеров файла расположены на диске - последовательно, то их чтение объединяется в одну операцию. - Следит за тем, чтобы не превысить указанный при вызове процедуры - лимит числа секторов для чтения. - -Процедура продолжения загрузки файла (continue_load_file): встроена - внутрь шага 5 load_file; загружает в регистры нужные значения (ранее - сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/build.bat b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/build.bat deleted file mode 100644 index 17c30cac18..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@fasm -m 65535 kordldr.f1x.asm kordldr.f1x -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm deleted file mode 100644 index 45a93e1a1b..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat1x/kordldr.f1x.asm +++ /dev/null @@ -1,689 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - org 0x7E00 -; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here -; ss:bp = 0:7C00 -virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? -BPB_TotSec16 dw ? - db ? ; BPB_Media -BPB_FATSz16 dw ? -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? -BPB_TotSec32 dd ? -BS_DrvNum db ? -fat_type db ? ; this is BS_Reserved1, - ; we use it to save FS type: 0=FAT12, 1=FAT16 - db ? ; BS_BootSig -num_sectors dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 3 ; BS_FilSysType, first 3 bytes -read_sectors dw ? -read_sectors2 dw ? -lookup_in_root_dir dw ? -scan_for_filename dw ? -err_ dw ? -noloader dw ? -cachelimit dw ? -filesize: ; will be used to save file size - rb 5 ; BS_FilSysType, last 5 bytes -; following variables are located in the place of starting code; -; starting code is no more used at this point -sect_per_clus dw ? -cur_cluster dw ? -next_cluster dw ? -flags dw ? -cur_delta dd ? -end virtual - -; procedures from boot sector -; LBA version -lba_read_sectors = 7CE2h -lba_read_sectors2 = 7CDCh -lba_lookup_in_root_dir = 7D4Fh -lba_scan_for_filename = 7D2Dh -lba_err = 7CB5h -lba_noloader = 7CB2h -; CHS version -chs_read_sectors = 7CDEh -chs_read_sectors2 = 7CD8h -chs_lookup_in_root_dir = 7D70h -chs_scan_for_filename = 7D4Eh -chs_err = 7CB1h -chs_noloader = 7CAEh - - push ax cx ; save our position on disk - push ss - pop es -; determine version of bootsector (LBA vs CHS) -; mov [read_sectors], chs_read_sectors -; mov [read_sectors2], chs_read_sectors2 -; mov [lookup_in_root_dir], chs_lookup_in_root_dir -; mov [scan_for_filename], chs_scan_for_filename -; mov [err], chs_err -; mov [noloader], chs_noloader - lea di, [read_sectors] - mov si, chs_proc_addresses - mov cx, 6*2 - cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di' - jz @f - add si, cx -; mov [read_sectors], lba_read_sectors -; mov [read_sectors2], lba_read_sectors2 -; mov [lookup_in_root_dir], lba_lookup_in_root_dir -; mov [scan_for_filename], lba_scan_for_filename -; mov [err], lba_err -; mov [noloader], lba_noloader -@@: - rep movsb - mov cl, [BPB_SecsPerClus] - mov [sect_per_clus], cx - xor bx, bx -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jae @f -nomem: - mov si, nomem_str - jmp [err_] -@@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 -; get type of file system - FAT12 or FAT16? -; calculate number of clusters - mov ax, [BPB_TotSec16] - xor dx, dx - test ax, ax - jnz @f - mov ax, word [BPB_TotSec32] - mov dx, word [BPB_TotSec32+2] -@@: - sub ax, [bp-8] ; dword [bp-8] = first data sector - sbb dx, [bp-6] - jb j_noloader - div [sect_per_clus] -; ax = number of clusters -; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes - mov [fat_type], ch - cmp ax, 0xFF5 - jb init_fat12 - inc [fat_type] -init_fat16: -; no sectors loaded - mov di, 0x8200 - xor ax, ax - mov cx, 0x100/2 - rep stosw - jmp init_fat_done -init_fat12: -; read FAT - push 0x6000 - pop es - mov ax, [BPB_RsvdSecCnt] - mov cx, [BPB_FATSz16] - cmp cx, 12 - jb @f - mov cx, 12 -@@: - xor dx, dx - call [read_sectors] -init_fat_done: -; if cluster = sector, we need to read second part of our file -; (bootsector loads only first cluster of kordldr.f1x) - pop cx ax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub ax, [bp-8] - inc ax - inc ax ; ax = first cluster of kordldr.f12 - call get_next_cluster - jc @f -j_noloader: - jmp [noloader] -@@: - dec ax - dec ax - push 0x800 - pop es - call [read_sectors2] -kordldr_full: -; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err_] - jz @f - mov si, aKernelNotFound - jmp bx -@@: -; for subsequent calls to callback function, hook error handler -; mov byte [bx], 0xE9 ; 'jmp' opcode -; mov ax, hooked_err - 3 -; sub ax, bx -; mov word [bx+1], ax -; push hooked_err / ret - mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8) - mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8) -; set registers for secondary loader - mov ah, [BS_DrvNum] - mov al, 'f' - test ah, ah - jns @f - sub ah, 80h - mov al, 'h' -@@: - mov bx, '12' - cmp [fat_type], 0 - jz @f - mov bh, '6' -@@: - mov si, callback ; ds:si = far pointer to callback procedure - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 - -nomem_str db 'No memory',0 - -chs_proc_addresses: - dw chs_read_sectors - dw chs_read_sectors2 - dw chs_lookup_in_root_dir - dw chs_scan_for_filename - dw chs_err - dw chs_noloader -lba_proc_addresses: - dw lba_read_sectors - dw lba_read_sectors2 - dw lba_lookup_in_root_dir - dw lba_scan_for_filename - dw lba_err - dw lba_noloader - -get_next_cluster: -; in: ax = cluster -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 - push si - cmp [fat_type], 0 - jnz gnc16 -; for FAT12 - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 -@@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret -; for FAT16 -gnc16: -; each sector contains 200h bytes = 100h FAT entries -; so ah = # of sector, al = offset in sector - mov si, ax - mov ah, 0 - shr si, 8 -; calculate segment for this sector of FAT table -; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) -; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x8200+si], ah ; sector already loaded? - jnz @f -; load corresponding sector - pusha - push es - xor bx, bx - mov ax, [BPB_RsvdSecCnt] - xor dx, dx - add ax, si - adc dx, bx - mov cx, 1 ; read 1 sector - call [read_sectors] - pop es - popa -@@: - mov si, ax - add si, si -; mov ax, [es:si] - lods word [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret - -if $ > 0x8000 -error 'get_next_cluster must fit in first sector of kordldr.f1x!' -end if - -load_file: -; in: ss:bp = 0:7C00 -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - xor ax, ax ; start from root directory - mov dx, -1 - mov word [filesize], dx - mov word [filesize+2], dx ; initialize file size with invalid value - lea si, [di+6] -parse_dir_loop: -; convert name to FAT name - push di - push ax - push ss - pop es -; convert ASCIIZ filename to FAT name - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp nameloop -namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop -namedone: -; scan directory - pop ax ; ax = cluster of directory or 0 for root - push ds - push si - push es - pop ds - mov si, filename ; ds:si -> filename in FAT style - test ax, ax - jnz lookup_in_notroot_dir -; for root directory, use the subroutine from bootsector - call [lookup_in_root_dir] - jmp lookup_done -lookup_in_notroot_dir: -; for other directories, read a folder sector-by-sector and scan -; first, try to use the cache - push ds - push cs - pop ds - mov bx, [cachelimit] - add bx, bx - mov di, foldcache_mark -@@: - mov dx, [foldcache_clus+di-foldcache_mark+bx] - cmp dx, ax - jz cacheok - test dx, dx - jz cacheadd ; the cache has place for new entry - dec bx - dec bx - jns @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov dx, [cachelimit] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b -cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - mov [foldcache_clus+di-foldcache_mark+bx], ax - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet -cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di -cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 - pop ds -; mov dx, bx -; shl dx, 8 ; dx = (position in cache)*0x2000/0x10 -; add dx, 0x9200 - lea dx, [bx+0x92] - xchg dl, dh - mov es, dx - jcxz not_in_cache - call [scan_for_filename] - jz lookup_done -not_in_cache: -; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -folder_next_cluster: -; internal loop: scan sectors in cluster - mov cx, [sect_per_clus] - push ax - dec ax - dec ax - mul cx - add ax, [bp-8] - adc dx, [bp-6] ; dx:ax = absolute sector -folder_next_sector: -; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call [read_sectors] -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - push si di - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - pop di si -@@: - push es - push 0x8000 - pop es - push cs - pop ds - mov cx, 0x10 - call [scan_for_filename] - pop es - pop cx - jz lookup_done_pop -folder_skip_sector: - inc ax - jnz @f - inc dx -@@: - loop folder_next_sector - pop ax ; ax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push ax -lookup_done_pop: - pop ax -lookup_done: - pop si - pop ds -; CF=1 <=> failed - jnc found -notfound: - pop di - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret -notfound_pop: - pop ax - jmp notfound -found: - mov ax, [es:di+26] ; get cluster - test byte [es:di+11], 10h ; directory? - jz regular_file - cmp byte [si-1], 0 - jz notfound ; don't read directories as a regular files -; ok, we have found a directory and the caller requested a file into it - pop di - jmp parse_dir_loop ; restart with new cluster in ax -regular_file: - cmp byte [si-1], 0 - jnz notfound ; file does not contain another files -; ok, we have found a regular file and the caller requested it -; save file size - mov dx, [es:di+28] - mov [filesize], dx - mov dx, [es:di+30] - mov [filesize+2], dx - pop di - mov si, [di+4] - shl si, 3 - push si ; [ds:di+4] = limit in 4K blocks - les bx, [di] ; es:bx -> buffer -clusloop: -; ax = first cluster, top of stack contains limit in sectors - mov si, ax ; remember current cluster - xor cx, cx ; cx will contain number of consecutive clusters - mov word [cur_delta], cx - mov word [cur_delta+2], cx - mov di, ax -clusfind: - inc di - inc cx - call get_next_cluster - jnc clusread - cmp ax, di - jz clusfind - stc -clusread: - pop di ; limit in sectors - push ax ; save next cluster - pushf ; save flags -; read cx clusters, starting from si -; calculate number of sectors - xchg ax, cx - mul [sect_per_clus] -; dx:ax = number of sectors; compare with limit - mov word [num_sectors], ax - mov word [num_sectors+2], dx - jmp @f -continue_load_file: - les bx, [di] ; es:bx -> buffer - mov di, [di+4] ; ds:di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov ax, word [num_sectors] - mov dx, word [num_sectors+2] - mov si, [cur_cluster] - push [next_cluster] - push [flags] - or ax, dx - jz nextclus -@@: - test dx, dx - jnz clusdecrease - push dx ; limit was not exceeded - cmp ax, di - jbe @f - pop ax -clusdecrease: - push 1 ; limit was exceeded - mov ax, di -@@: - sub di, ax ; calculate new limit - sub word [num_sectors], ax - sbb word [num_sectors+2], 0 -readloop: - push ax -; buffer should not cross a 64K boundary - push bx - shr bx, 4 - mov cx, es - add bx, cx - neg bx - and bh, 0xF - shr bx, 5 - jnz @f - mov bl, 0x80 -@@: - cmp ax, bx - jbe @f - xchg ax, bx -@@: - pop bx - xchg ax, cx -; calculate starting sector - lea ax, [si-2] - mul [sect_per_clus] - add ax, word [cur_delta] - adc dx, word [cur_delta+2] - add word [cur_delta], cx - adc word [cur_delta+2], 0 -; read - call [read_sectors2] - pop ax - sub ax, cx - jnz readloop - pop dx -; next cluster? -nextclus: - popf - pop ax - mov [cur_cluster], si - mov [next_cluster], ax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 ; dh=0 in any case - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue -hooked_err: - mov sp, 7C00h-12-2 ; restore stack - mov dx, 3 ; return: read error -@@: - mov bx, dx - mov ax, [filesize] - mov dx, [filesize+2] - ret - -; Callback function for secondary loader -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-8 - mov bp, 7C00h - push dx - push cx -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret -; function 2: continue loading file -; can be called only after function 1 returned value bx=1 (only part of file was loaded) -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file -callback_ret_succ: - clc ; function is supported -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kernel.mnt',0 -aKernelNotFound db 'Fatal error: cannot load the kernel',0 - -foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache -foldcache_mark rw 7 -foldcache_size rw 7 -filename rb 11 -if $ > 0x8200 -error: - table overwritten -end if diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/bootsect.asm b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/bootsect.asm deleted file mode 100644 index eb0b7c936b..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/bootsect.asm +++ /dev/null @@ -1,358 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -use_lba = 0 - org 0x7C00 - jmp start - nop -; FAT parameters, BPB -; they must be changed at install, replaced with real values - rb 8 ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? - dw ? ; BPB_FSInfo -BPB_BkBootSec dw ? - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID - rb 11 ; BS_VolLab - rb 8 ; - -curseg dw 0x8000 - -start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - push dx ; byte [bp-2] = boot drive -if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cl, 1 - jz err_ -else - mov ah, 8 - int 13h - jc @f - movzx ax, dh - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx -@@: -end if -; get FAT parameters - xor bx, bx - movzx eax, [bp+BPB_NumFATs-0x7C00] - mul [bp+BPB_FATSz32-0x7C00] - movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00] - push ecx ; FAT start = dword [bp-6] - add eax, ecx - push eax ; data start = dword [bp-10] - ;push dword -1 ; dword [bp-14] = current sector for FAT cache - db 66h - push -1 ; dword [bp-14] = current sector for FAT cache - mov eax, [bp+BPB_RootClus-0x7C00] - mov si, main_loader - call lookup_in_dir - jnc kordldr_ok -noloader: - mov si, aLoaderNotFound -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -kordldr_ok: - mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster) - mov ax, [es:di+26] ; loword(eax) = loword(cluster) - mov es, bx ; es = 0 - mov bx, 0x7E00 - push bx ; save return address: bx = 7E00 -; fall through - 'ret' in read_cluster will return to 7E00 - -read_cluster: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; eax = cluster - sub eax, 2 - movzx ecx, [bp+BPB_SecsPerClus-0x7C00] - mul ecx - -read_sectors2: -; same as read_sectors32, but eax is relative to start of data - add eax, [bp-10] -read_sectors32: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; eax = first sector -; cx = number of sectors -; some high words of 32-bit registers are destroyed! - pusha - add eax, [bp+BPB_HiddSec-0x7C00] -if use_lba - push ds -do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp-2] - mov ah, 42h - int 13h - mov si, aReadError - jc err_ -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popa - ret -else -do_read_sectors: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx - -; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp+BPB_SecPerTrk-0x7C00] - xor edx, edx - div esi - mov bx, dx ; bx=sector-1 - -; eax -> dx:ax - push eax - pop ax - pop dx -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] - -; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si -@@: - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp-2] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err_ -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz do_read_sectors - popa - ret -end if - -lookup_in_dir: -; in: ds:si -> 11-bytes FAT name -; in: eax = cluster -; in: bx = 0 -; out: if found: CF=0, es:di -> directory entry -; out: if not found: CF=1 -; push 0x8000 -; pop es -; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000 - mov es, [bp-7C00h + curseg] - push es - push eax - call read_cluster - mov ax, es - cmp ah, 82h - jb @f - mov ax, 8200h -@@: - mov [bp-7C00h + curseg], ax - pop eax - pop es -; scan for filename - shl cx, 4 - xor di, di -sloop: - cmp byte [es:di], bl - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone -scont: - add di, 0x20 - loop sloop -; next cluster - push 0x6000 - pop es - push es ax - shr eax, 7 - cmp eax, [bp-14] - mov [bp-14], eax - jz @f - add eax, [bp-6] - mov cx, 1 - call read_sectors32 -@@: - pop di es - and di, 0x7F - shl di, 2 - and byte [es:di+3], 0x0F - mov eax, [es:di] - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - jb lookup_in_dir -snotfound: - stc -sdone: - ret - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz sdone - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aReadError db 'Read error',0 -if use_lba -aNoLBA db 'The drive does not support LBA!',0 -end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F32' - - db 56h -; just to make file 512 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - -; bootsector signature - dw 0xAA55 - -; display offsets of all procedures used by kordldr.f12.asm -macro show [procedure] -{ - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 -} - -show read_sectors32, read_sectors2, err_, noloader diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/bootsect.txt b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/bootsect.txt deleted file mode 100644 index caabcb33f9..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/bootsect.txt +++ /dev/null @@ -1,333 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Читай между строк - там никогда не бывает опечаток. - -Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт. - -===================================================================== - -Есть две версии в зависимости от того, поддерживает ли носитель LBA, -выбор осуществляется установкой константы use_lba в первой строке исходника. -Требования для работы: -1) Сам бутсектор, первая копия FAT и все используемые файлы -должны быть читабельны. (Если дело происходит на носителе с разбиением на -разделы и загрузочный код в MBR достаточно умный, то читабельности резервной -копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности -самого бутсектора). -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 584K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 15.05.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Схема используемой памяти: - ...-7C00 стек - 7C00-7E00 код бутсектора - 7E00-8200 вспомогательный файл загрузчика (kordldr.f32) - 8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8 - байт: 4 байта (две ссылки - вперёд и назад) для - организации L2-списка всех прочитанных секторов в - порядке возрастания последнего времени использования - + 4 байта для номера сектора; при переполнении кэша - выкидывается элемент из головы списка, то есть тот, - к которому дольше всех не было обращений - 60000-80000 кэш для таблицы FAT (100h секторов) - 80000-90000 текущий кластер текущей рассматриваемой папки - 90000-... кэш для содержимого папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 8 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед - кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало - бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - - это освобождает ds и экономит на размере кода). Сохраняет в стеке - идентификатор загрузочного диска для последующего обращения - через byte [bp-2]. -2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h - прерывания 13h. Если нет, переходит на код обработки ошибок с - сообщением об отсутствии LBA. -CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и - записывает полученные данные поверх BPB. Если вызов завершился ошибкой, - предполагает уже существующие данные корректными. -3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего - обращения через dword [bp-10]. В процессе вычисления узнаёт начало - первой FAT, сохраняет и его в стек для последующего обращения через - dword [bp-6]. -4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1 - для последующего обращения через dword [bp-14] - инициализация - переменной, содержащей текущий сектор, находящийся в кэше FAT - (-1 не является валидным значением для номера сектора FAT). -5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на - код обработки ошибок с сообщением о ненайденном загрузчике. - Замечание: на этом этапе загрузки искать можно только в корневой - папке и только имена, заданные в формате файловой системе FAT - (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны - быть заглавными, при необходимости имя и расширение дополняются - пробелами, разделяющей точки нет, завершающего нуля нет). -6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт - ему управление. При этом в регистре eax оказывается абсолютный - номер первого сектора kordldr.f32, а в cx - число считанных секторов - (равное размеру кластера). - -Вспомогательные процедуры бутсектора. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения кластера (read_cluster): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = номер кластера -на выходе: ecx = число прочитанных секторов (размер кластера), - es:bx указывает на конец буфера, в который были прочитаны данные, - eax и старшие слова других 32-битных регистров разрушаются -Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора -и переходит к следующей процедуре. - -Процедура чтения секторов (read_sectors32 и read_sectors2): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор (относительно начала логического диска - для read_sectors32, относительно начала данных - для read_sectors2) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные - старшие слова 32-битных регистров могут разрушиться -0. Если вызывается read_sectors2, она переводит указанный ей номер сектора - в номер относительно начала логического диска, прибавляя номер сектора - начала данных, хранящийся в стеке как [bp-10]. -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя значение соответствующего поля из BPB. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура поиска элемента в папке (lookup_in_dir): -на входе должно быть установлено: - ss:bp = 0:7C00 - ds:si = указатель на имя файла в формате FAT (см. выше) - eax = начальный кластер папки - bx = 0 -на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то - CF сброшен и es:di указывает на элемент папки -В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных -данных. Для чтения кластера использует уже описанную процедуру read_clusters, -для продвижения по цепочке кластеров - описанную далее процедуру -get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса -8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше, -если чтение прервётся раньше) не перекрываются последующими чтениями -(это будет использовано позднее, в системе кэширования из kordldr.f32). -Выход осуществляется в любом из следующих случаев: найден запрошенный элемент; -кончились элементы в папке (первый байт очередного элемента нулевой); -кончились данные папки в соответствии с цепочкой кластеров из FAT. - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -===================================================================== - -Работа вспомогательного загрузчика kordldr.f32: -1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. - В зависимости от этого устанавливает смещения используемых процедур - бутсектора. Критерий проверки: в CHS-версии по адресу err находится - байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу - находится байт 0x14, а адрес процедуры err другой. -2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска - адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с - ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента - место должно быть, отсюда ограничение в 592 Kb (94000h байт). - Замечание: этот размер не может превосходить 0A0000h байт и - на практике оказывается немного (на 1-2 килобайта) меньшим из-за - наличия дополнительной области данных BIOS "вверху" базовой памяти. -3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть - данных корневой папки; копирует загруженные данные в кэш и запоминает, - что в кэше есть корневая папка. -4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только - том случае, когда ему приходится загружать данные корневой папки, - не поместившиеся в один кластер. В этом случае в памяти присутствует - один сектор FAT (если было несколько обращений - последний из - использованных). -5. Если кластер равен сектору, то бутсектор загрузил только часть файла - kordldr.f32, и загрузчик подгружает вторую свою часть, используя - значения регистров на входе в kordldr.f32. -6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не - найден, или оказался папкой, или оказался слишком большим, то переходит - на код обработки ошибок из бутсектора с сообщением - "Fatal error: cannot load the secondary loader". - Замечание: на этом этапе имя файла уже можно указывать вместе с путём - и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов - по-прежнему нет. -7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. - Это нужно, чтобы последующие обращения к коду бутсектора в случае - ошибок чтения не выводил соответствующее сообщение с последующей - перезагрузкой, а рапортовал об ошибке чтения, которую могло бы - как-нибудь обработать ядро. -8. Если загрузочный диск имеет идентификатор меньше 0x80, - то устанавливает al='f' ("floppy"), ah=идентификатор диска, - иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). - (Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но - уверены ли Вы, что нет загрузочных устройств, подобных дискетам, - но большего размера, и для которых BIOS-идентификатор меньше 0x80?) - Устанавливает bx='32' (тип файловой системы - FAT32). - Устанавливает si=смещение функции обратного вызова. Поскольку в этот - момент ds=0, то ds:si образуют полный адрес. -9. Передаёт управление по адресу 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным - кодом должна указывать на 0:7C00, а -10 берётся от того, что - инициализирующий код бутсектора уже поместил в стек 10 байт параметров, - и они должны сохраняться в неизменности. (Значение [ebp-14], - "текущий сектор, находящийся в кэше FAT", не используется после - инициализации кэширования в kordldr.f32.) -2. Разбирает переданные параметры и вызывает нужную из вспомогательных - процедур (загрузки файла либо продолжения загрузки файла). -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры kordldr.f32. -Процедура получения следующего кластера в FAT (get_next_cluster): -1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент. - (В секторе 0x200 байт, каждый вход занимает 4 байта.) -2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4. -3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен, - выделяет очередной элемент в конце кэша. Если заполнен, удаляет - самый старый элемент (тот, к которому дольше всего не было обращений); - для того, чтобы отслеживать порядок элементов по времени последнего - обращения, все (выделенные) элементы кэша связаны в двусвязный список, - в котором первым элементом является самый старый, а ссылки вперёд - указывают на следующий по времени последнего обращения. -4. Читает соответствующий сектор FAT с диска. -5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции, - где он находится, и добавляется в конец. (В случае со свежедобавленными - в кэш элементами удаления не делается, поскольку их в списке ещё нет.) -6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита. -7. Сравнивает прочитанное значение с пределом: если оно строго меньше - 0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке; - в противном случае цепочка закончилась. - -Процедура загрузки файла (load_file): -1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. -2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты - разделяются символом '/') в FAT-формат 8+3. Если это невозможно - (больше 8 символов в имени, больше 3 символов в расширении или - больше одной точки), возвращается с ошибкой. -3. Ищет элемент с таким именем в текущей рассматриваемой папке. - а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок - осуществляется по номеру начального кластера.) Если такой папки ещё - нет, добавляет её в кэш; если тот переполняется, выкидывает папку, - к которой дольше всего не было обращений. (Для каждого элемента кэша - хранится метка от 0 до (размер кэша)-1, определяющая его номер при - сортировке по давности последнего обращения. При обращении к какому-то - элементу его метка становится нулевой, а те метки, которые меньше - старого значения, увеличиваются на единицу.) - б) Просматривает в поисках запрошенного имени все элементы из кэша, - используя процедуру из бутсектора. Если обнаруживает искомый элемент, - переходит к шагу 4. Если обнаруживает конец папки, возвращается из - процедуры с ошибкой. - в) В цикле считывает папку посекторно. При этом пропускает начальные - секторы, которые уже находятся в кэше и уже были просмотрены. Каждый - прочитанный сектор копирует в кэш, если там ещё остаётся место, - и просматривает в нём все элементы. Работает, пока не случится одно из - трёх событий: найден искомый элемент; кончились кластеры (судя по - цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце - (первый байт нулевой). В двух последних случаях возвращается с ошибкой. -4. Проверяет тип найденного элемента (файл/папка): последний элемент в - запрошенном имени должен быть файлом, все промежуточные - папками. - Если текущий компонент имени - промежуточный, продвигает текущую - рассматриваемую папку и возвращается к пункту 2. -5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный - при вызове буфер последовательными вызовами функции бутсектора; - при этом если несколько кластеров файла расположены на диске - последовательно, то их чтение объединяется в одну операцию. - Следит за тем, чтобы не превысить указанный при вызове процедуры - лимит числа секторов для чтения. - -Процедура продолжения загрузки файла (continue_load_file): встроена - внутрь шага 5 load_file; загружает в регистры нужные значения (ранее - сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/build.bat b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/build.bat deleted file mode 100644 index 267c29375b..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@fasm -m 65535 kordldr.f32.asm kordldr.f32 -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/kordldr.f32.asm b/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/kordldr.f32.asm deleted file mode 100644 index b862419e10..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/extended_primary_loader/fat32/kordldr.f32.asm +++ /dev/null @@ -1,673 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - org 0x7E00 -; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here -; ss:bp = 0:7C00 -; ds = 0 -virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? -filesize: - dw ? ; BPB_FSInfo - dw ? ; BPB_BkBootSec - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 5 ; BS_FilSysType, first 5 bytes -read_sectors32 dw ? -read_sectors2 dw ? -err_ dw ? -noloader dw ? -cachelimit dw ? -fatcachehead rw 2 -fatcacheend dw ? - rb 3 ; BS_FilSysType, last 3 bytes -curseg dw ? -num_sectors dd ? -cur_cluster dd ? -next_cluster dd ? -flags dw ? -cur_delta dd ? -end virtual - -; procedures from boot sector -; LBA version -lba_read_sectors2 = 7CD6h -lba_err = 7CAAh -lba_noloader = 7CA7h ; = lba_err - 3 -; CHS version -chs_read_sectors2 = 7CD2h -chs_err = 7CA6h -chs_noloader = 7CA3h ; = chs_err - 3 - - push eax cx ; save our position on disk -; determine version of bootsector (LBA vs CHS) - mov [read_sectors2], chs_read_sectors2 - mov bx, chs_err - mov [err_], bx -; mov [noloader], chs_noloader - cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version - jz @f - add [read_sectors2], lba_read_sectors2 - chs_read_sectors2 - add [err_], lba_err - chs_err -; mov [noloader], lba_noloader -@@: - xor bx, bx -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 92000h / 1024 - jae @f -nomem: - mov si, nomem_str - jmp [err_] -@@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 - mov es, bx -; no folders in cache yet - mov di, foldcache_clus - mov cx, 8*4/2 + 1 - xor ax, ax - rep stosw -; bootsector code caches one FAT sector, [bp-14], in 6000:0000 -; initialize our (more advanced) FAT caching from this - mov di, 8400h - mov cx, di - lea si, [fatcachehead] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [fatcacheend], di ; first free item = 8400h - stosw ; 'next cached sector' link - stosw ; 'prev cached sector' link - mov eax, [bp-14] - stosd ; first sector number in cache - test eax, eax - js @f - mov [si], cx ; 'first cached sector' link = 8400h - mov [si+2], cx ; 'next cached sector' link = 8400h - mov [fatcacheend], di ; first free item = 8406h -@@: -; if cluster = sector, we need to read second part of our file -; (bootsector loads only first cluster of kordldr.f32) - pop cx eax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub eax, [bp-10] - inc eax - inc eax ; eax = first cluster of kordldr.f32 - call get_next_cluster - jc @f -; jmp [noloader] - mov ax, [err_] - sub ax, 3 - jmp ax -@@: - dec eax - dec eax - push 0x800 - pop es - call [read_sectors2] -kordldr_full: -; bootsector code has read some data of root directory to 8000:0000 -; initialize our folder caching from this - mov eax, [BPB_RootClus] - mov [foldcache_clus], eax - mov cx, [curseg] - mov ax, 8000h - sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes) - shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes) - mov [foldcache_size], cx - shl cx, 4 - push ds - mov ds, ax - push 0x9000 - pop es - xor si, si - xor di, di - rep movsw - pop ds -; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err_] - jz @f - mov si, aKernelNotFound - jmp bx -@@: -; for subsequent calls to callback function, hook error handler -; push hooked_err / ret - mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24) -; set registers for secondary loader - mov ah, [bp-2] ; drive id - mov al, 'f' - btr ax, 15 - jnc @f - mov al, 'h' -@@: - mov bx, '32' - mov si, callback - jmp far [si+secondary_loader_info-callback] - -nomem_str db 'No memory',0 - -cluster2sector: - sub eax, 2 -clustersz2sectorsz: - movzx ecx, [BPB_SecsPerClus] - mul ecx - ret - -get_next_cluster: -; in: eax = cluster -; out: if there is next cluster: CF=1, eax = next cluster -; out: if there is no next cluster: CF=0 - push di bx - push ds es - push ss - pop ds - push ss - pop es - push ax - shr eax, 7 -; eax = FAT sector number; look in cache - mov di, 8400h -.cache_lookup: - cmp di, [fatcacheend] - jae .not_in_cache - scasd - scasd - jnz .cache_lookup -.in_cache: - sub di, 8 -; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si - jmp @f -.not_in_cache: -; cache miss -; cache is full? - mov di, [fatcacheend] - cmp di, 8C00h - jnz .cache_not_full -; yes, delete the oldest entry - mov di, [fatcachehead] - mov bx, [di] - mov [fatcachehead], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append -.cache_not_full: -; no, allocate new sector - add [fatcacheend], 8 -.cache_append: -; read FAT - mov [di+4], eax - pushad - lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-4-3))] ; +0x10000 - for FASM - shl cx, 9-4-3 - mov es, cx - xor bx, bx - mov cx, 1 - add eax, [bp-6] ; FAT start - sub eax, [bp-10] - call [read_sectors2] - popad -@@: -; add new sector to the end of list - mov bx, di - xchg bx, [fatcachehead+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx -; get requested item - lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-4-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-4-3 - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop es ds - pop bx di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret - -if $ > 0x8000 -error 'get_next_cluster must fit in first sector of kordldr.f32!' -end if - -load_file: -; in: ss:bp = 0:7C00 -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - mov eax, [BPB_RootClus] ; start from root directory - or dword [filesize], -1 ; initialize file size with invalid value - lea si, [di+6] -parse_dir_loop: -; convert name to FAT name - push di - push ax - push ss - pop es -; convert ASCIIZ filename to FAT name -filename equ bp - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp nameloop -namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop -namedone: -; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si -; read a folder sector-by-sector and scan -; first, try to use the cache - push ss - pop ds - mov di, foldcache_mark - xor bx, bx - mov cx, [cachelimit] -@@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz cacheok - test edx, edx - jz cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - jns @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [cachelimit] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b - lea si, [di+bx] -cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - mov dword [foldcache_clus+si-foldcache_mark+bx], eax -cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di -cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 - ;mov dx, bx - ;shl dx, 8 ; dx = (position in cache)*0x2000/0x10 - ;add dx, 0x9000 - lea dx, [bx + 0x90] - xchg dl, dh - mov ds, dx - mov si, filename ; ss:si -> filename in FAT style - call scan_for_filename - jz lookup_done -; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -folder_next_cluster: -; internal loop: scan sectors in cluster - push eax - call cluster2sector -folder_next_sector: -; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - push eax - call [read_sectors2] - pop eax -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache - popa -@@: - push es - mov cl, 0x10 ; ch=0 at this point - call scan_for_filename - pop es - pop cx - jz lookup_done_pop -folder_skip_sector: - inc eax - loop folder_next_sector - pop eax ; eax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push eax -lookup_done_pop: - pop eax -lookup_done: - pop si -; CF=1 <=> failed - jnc found - pop ds -notfound: - pop di -notfound2: - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret -notfound_pop: - pop ax - jmp notfound -found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop di - jz regular_file - cmp byte [si-1], 0 - jz notfound2 ; don't read directories as regular files -; ok, we have found a directory and the caller requested a file into it - jmp parse_dir_loop ; restart with new cluster in ax -regular_file: - cmp byte [si-1], 0 - jnz notfound2 ; file does not contain another files -; ok, we have found a regular file and the caller requested it -; save file size - mov [filesize], edx - mov si, [di+4] ; [ds:di+4] = limit in 4K blocks - shl si, 3 - push si - les bx, [di] ; es:bx -> buffer -clusloop: -; eax = first cluster, top of stack contains limit in sectors - mov esi, eax ; remember current cluster - xor ecx, ecx ; ecx will contain number of consecutive clusters - mov [cur_delta], ecx - mov edi, eax -clusfind: - inc edi - inc ecx - call get_next_cluster - jnc clusread - cmp eax, edi - jz clusfind - stc -clusread: - pop di ; limit in sectors - movzx edi, di - push eax ; save next cluster - pushf ; save flags -; read cx clusters, starting from si -; calculate number of sectors - xchg eax, ecx - call clustersz2sectorsz - mov [num_sectors], eax - jmp @f -continue_load_file: - les bx, [di] ; es:bx -> buffer - movzx edi, word [di+4] ; di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov eax, [num_sectors] - mov esi, [cur_cluster] - push [next_cluster] - push [flags] - test eax, eax - jz nextclus -@@: -; eax = number of sectors; compare with limit - cmp eax, edi - seta dl - push dx ; limit was exceeded? - jbe @f - mov eax, edi -@@: - sub di, ax ; calculate new limit - sub [num_sectors], eax - mov [cur_cluster], esi -; calculate starting sector - push ax - xchg eax, esi - call cluster2sector - pop cx - add eax, [cur_delta] - add [cur_delta], ecx -; read - call [read_sectors2] - pop dx -; next cluster? -nextclus: - popf - pop eax - mov [next_cluster], eax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue -hooked_err: - mov sp, 7C00h-14-2 ; restore stack - mov dl, 3 ; return: read error -@@: - mov bl, dl - mov bh, 0 - mov ax, [filesize] - mov dx, [filesize+2] - ret - -scan_for_filename: -; in: ss:si -> 11-bytes FAT name -; in: ds:0 -> part of directory data -; in: cx = number of entries -; in: bh = 0 -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz snoent -sloop: - cmp byte [di], bh - jz snotfound - test byte [di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz sdone -scont: - add di, 0x20 - loop sloop -snoent: - inc cx ; clear ZF flag -snotfound: - stc -sdone: - pop cx -lrdret: - ret - -; Callback function for secondary loader -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-10 - mov bp, 7C00h - push dx - push cx -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret -; function 2: continue loading file -; can be called only after function 1 returned value bx=1 (only part of file was loaded) -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file -callback_ret_succ: - clc ; function is supported -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kernel.mnt',0 -aKernelNotFound db 'Fatal error: cannot load the kernel',0 - -;if $ > 0x8200 -;error 'total size of kordldr.f32 must not exceed 1024 bytes!' -;end if - -;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache -;foldcache_mark dw 0 -; rw 7 -;foldcache_size rw 8 -foldcache_clus rd 8 -foldcache_mark rw 8 -foldcache_size rw 8 diff --git a/kernel/branches/Kolibri-acpi/bootloader/floppy1440.inc b/kernel/branches/Kolibri-acpi/bootloader/floppy1440.inc deleted file mode 100644 index b1cefcc5f6..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/floppy1440.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 1 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) - BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 18 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-acpi/bootloader/floppy1680.inc b/kernel/branches/Kolibri-acpi/bootloader/floppy1680.inc deleted file mode 100644 index 7a89071bce..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/floppy1680.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 1 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 112 ; count of 32-byte dir. entries (112*32 = 7 sectors) - BPB_TotSec16 dw 3360 ; count of sectors on the volume (3360 for 1.68 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 10 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 21 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-acpi/bootloader/floppy1743.inc b/kernel/branches/Kolibri-acpi/bootloader/floppy1743.inc deleted file mode 100644 index 41dd3117fd..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/floppy1743.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 1 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors) - BPB_TotSec16 dw 3486 ; count of sectors on the volume (3486 for 1.74 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 11 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 21 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-acpi/bootloader/floppy2880.inc b/kernel/branches/Kolibri-acpi/bootloader/floppy2880.inc deleted file mode 100644 index b26ef64009..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/floppy2880.inc +++ /dev/null @@ -1,26 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - BS_OEMName db 'KOLIBRI ' ; db 8 - BPB_BytsPerSec dw 512 ; bytes per sector - BPB_SecPerClus db 2 ; sectors per cluster - BPB_RsvdSecCnt dw 1 ; number of reserver sectors - BPB_NumFATs db 2 ; count of FAT data structures - BPB_RootEntCnt dw 240 ; count of 32-byte dir. entries (240*32 = 15 sectors) - BPB_TotSec16 dw 5760 ; count of sectors on the volume (5760 for 2.88 mbytes disk) - BPB_Media db 0f0h ; f0 - used for removable media - BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT - BPB_SecPerTrk dw 36 ; sectors per track - BPB_NumHeads dw 2 ; number of heads - BPB_HiddSec dd 0 ; count of hidden sectors - BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535) - BS_DrvNum db 0 ; int 13h drive number - BS_Reserved db 0 ; reserved - BS_BootSig db 29h ; Extended boot signature - BS_VolID dd 0 ; Volume serial number - BS_VolLab db 'KOLIBRI ' ; Volume label (db 11) - BS_FilSysType db 'FAT12 ' ; file system type (db 8) diff --git a/kernel/branches/Kolibri-acpi/bootloader/readme b/kernel/branches/Kolibri-acpi/bootloader/readme deleted file mode 100644 index b68c8bac03..0000000000 --- a/kernel/branches/Kolibri-acpi/bootloader/readme +++ /dev/null @@ -1,50 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -Загрузочный сектор для ОС Колибри (FAT12, дискета) - -- Описание - Позволяет загружать KERNEL.MNT с дискет/образов - объёмом 1.44M, 1.68M, 1.72M и 2.88M - Для выбора объёма диска, для которого надо собрать - загрузочный сектор, необходимо в файле boot_fat12.asm - раскомментировать строку вида: - include 'floppy????.inc' - для необходимого объёма диска. Доступные варианты: - floppy1440.inc, - floppy1680.inc, - floppy1743.inc и floppy2880.inc - -- Сборка - fasm boot_fat12.asm - -- Для записи загрузочного сектора на диск/образ под Linux - можно воспользоваться следующей командой: - dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc - ---------------------------------------------------------------------- - -Floppy FAT12 boot sector for KolibriOS. - -- Description - Allows booting KERNEL.MNT floppies/images - with volumes of 1.44M, 1.68M, 1.72M and 2.88M - To select the volume of the disk, which should gather - boot sector, it was necessary in file boot_fat12.asm - uncomment line: - include 'floppy????. inc' - for the necessary disk volume. Available options is: - floppy1440.inc, - floppy1680.inc, - floppy1743.inc and floppy2880.inc - -- Compile - fasm boot_fat12.asm - -- To write boot sector to the floppy/image under Linux - you can use the following command: - dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc diff --git a/kernel/branches/Kolibri-acpi/const.inc b/kernel/branches/Kolibri-acpi/const.inc index 30bfcbf545..9922235b98 100644 --- a/kernel/branches/Kolibri-acpi/const.inc +++ b/kernel/branches/Kolibri-acpi/const.inc @@ -501,7 +501,7 @@ struct APPDATA terminate_protection dd ? ;+176 keyboard_mode db ? ;+180 rb 3 - dd ? ;+184 + exec_params dd ? ;+184 dbg_event_mem dd ? ;+188 dbg_regs DBG_REGS ;+192 wnd_caption dd ? ;+212 diff --git a/kernel/branches/Kolibri-acpi/core/memory.inc b/kernel/branches/Kolibri-acpi/core/memory.inc index 39129bfcf3..e604e7c330 100644 --- a/kernel/branches/Kolibri-acpi/core/memory.inc +++ b/kernel/branches/Kolibri-acpi/core/memory.inc @@ -575,15 +575,6 @@ proc page_fault_handler cmp ebx, kernel_tabs jb .alloc;.app_tabs ;таблицы страниц приложения ; ;просто создадим одну -if 0 ;пока это просто лишнее - cmp ebx, LFB_BASE - jb .core_tabs ;таблицы страниц ядра - ;Ошибка - .lfb: - ;область LFB - ;Ошибка - jmp .fail -end if .core_tabs: .fail: ;simply return to caller mov esp, ebp diff --git a/kernel/branches/Kolibri-acpi/core/string.inc b/kernel/branches/Kolibri-acpi/core/string.inc index 3e217d1a34..d78a1f298f 100644 --- a/kernel/branches/Kolibri-acpi/core/string.inc +++ b/kernel/branches/Kolibri-acpi/core/string.inc @@ -115,6 +115,7 @@ align 4 proc strnlen stdcall, s:dword, n:dword push edi + mov ecx, [n] mov edi, [s] ; edi = string xor al, al ; Look for a zero byte mov edx, ecx ; Save maximum count diff --git a/kernel/branches/Kolibri-acpi/core/taskman.inc b/kernel/branches/Kolibri-acpi/core/taskman.inc index 275f70afe5..b2a5806428 100644 --- a/kernel/branches/Kolibri-acpi/core/taskman.inc +++ b/kernel/branches/Kolibri-acpi/core/taskman.inc @@ -30,13 +30,17 @@ struct APP_HEADER_01_ i_icon dd ? ;+32 ends - -struct APP_PARAMS - app_cmdline dd ? ;0x00 - app_path dd ? ;0x04 - app_eip dd ? ;0x08 - app_esp dd ? ;0x0C - app_mem dd ? ;0x10 +struct APP_HDR + cmdline rd 1 ;0x00 + path rd 1 ;0x04 + eip rd 1 ;0x08 + esp rd 1 ;0x0C + _edata rd 1 ;0x10 + _emem rd 1 ;0x14 + img_base rd 1 ;0x18 + img_size rd 1 + filename_size rd 1 + cmdline_size rd 1 ends macro _clear_ op @@ -46,163 +50,73 @@ macro _clear_ op rep stosd } + +_strlen: + mov ecx, 0xFFFFFFFF + xor eax, eax + repne scasb + mov eax, 0xFFFFFFFE + sub eax, ecx + retn + + fs_execute_from_sysdir: xor ebx, ebx fs_execute_from_sysdir_param: xor edx, edx - mov esi, sysdir_path align 4 proc fs_execute - -;fn_read:dword, file_size:dword, cluster:dword - ; ebx - cmdline ; edx - flags ; ebp - full filename -; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it locals - cmdline_size dd ? ; +0 ; cmdline -12 - cmdline_adr dd ? ; +4 ; cmdline -8 - cmdline_flag dd ? ; +8 ; cmdline -4 - cmdline rd 64 ;256/4 - filename rd 256 ;1024/4 - flags dd ? + filename rd 1 + cmdline rd 1 + flags rd 1 + + slot rd 1 + slot_base rd 1 + +;app header data + + hdr_cmdline rd 1 ;0x00 + hdr_path rd 1 ;0x04 + hdr_eip rd 1 ;0x08 + hdr_esp rd 1 ;0x0C + hdr_edata rd 1 ;0x10 + hdr_emem rd 1 ;0x14 + file_base rd 1 ;0x18 + file_size rd 1 ;0x1c + filename_size rd 1 ;0x20 + cmdline_size rd 1 ;0x24 - save_proc dd ? - slot dd ? - slot_base dd ? - file_base dd ? - file_size dd ? -; handle dd ? ;temp. for default cursor handle for curr. thread - ;app header data - hdr_cmdline dd ? ;0x00 - hdr_path dd ? ;0x04 - hdr_eip dd ? ;0x08 - hdr_esp dd ? ;0x0C - hdr_mem dd ? ;0x10 - hdr_i_end dd ? ;0x14 endl - pushad - -; cmp [SCR_MODE], word 0x13 -; jbe @f -; pushad -; stdcall set_cursor, [def_cursor_clock] -; mov [handle], eax -; mov [redrawmouse_unconditional], 1 -; call wakeup_osloop -; popad -;@@: +xchg bx, bx + mov eax, [ebp] mov [flags], edx - -; [ebp] pointer to filename - - lea edi, [filename] - lea ecx, [edi+1024] - mov al, '/' - stosb -@@: - cmp edi, ecx - jae .bigfilename - lodsb - stosb - test al, al - jnz @b - mov esi, [ebp] - test esi, esi - jz .namecopied - mov byte [edi-1], '/' -@@: - cmp edi, ecx - jae .bigfilename - lodsb - stosb - test al, al - jnz @b - jmp .namecopied -.bigfilename: - popad - mov eax, -ERROR_FILE_NOT_FOUND - - jmp .final - -.namecopied: - xor eax, eax - mov [cmdline_flag], eax - mov [cmdline_adr], eax - mov [cmdline_size], eax - mov [cmdline], ebx - test ebx, ebx - jz .no_copy -;-------------------------------------- - pushad - pushfd - mov esi, ebx - mov ecx, 65536 ; 64 Kb max for ext.cmdline - cld -@@: - dec ecx - jz .end_string + mov [filename], eax - lodsb - test al, al - jnz @b + call lock_application_table -.end_string: - mov eax, 65536 ; 64 Kb max for ext.cmdline - sub eax, ecx - mov [cmdline_size], eax - cmp eax, 255 - ja @f - - popfd - popad - jmp .old_copy - -@@: - xor eax, eax - dec eax - mov [cmdline_flag], eax - popfd - popad -; get memory for the extended command line - stdcall kernel_alloc, [cmdline_size] ;eax + call alloc_thread_slot + mov esi, -0x20 ; too many processes test eax, eax - jz .old_copy ; get memory failed + jz .err_0 - mov [cmdline_adr], eax + mov [slot], eax + shl eax, 8 + add eax, SLOT_BASE + mov [slot_base], eax - pushad - pushfd - mov esi, ebx - mov edi, eax - mov ecx, [cmdline_size] - cld - rep movsb - popfd - popad - jmp .no_copy - -.old_copy: -; clear flag because old method with 256 bytes - xor eax, eax - mov [cmdline_flag], eax -;-------------------------------------- - lea eax, [cmdline] - mov dword [eax+252], 0 -.copy: - stdcall strncpy, eax, ebx, 255 -.no_copy: - lea eax, [filename] + mov eax, [filename] stdcall load_file, eax - mov esi, -ERROR_FILE_NOT_FOUND test eax, eax - jz .err_file + jz .err_0 mov [file_base], eax mov [file_size], ebx @@ -213,19 +127,12 @@ proc fs_execute test eax, eax jz .err_hdr - call lock_application_table - - call alloc_thread_slot - test eax, eax - mov esi, -0x20 ; too many processes - jz .err - - mov [slot], eax - shl eax, 8 - add eax, SLOT_BASE - mov [slot_base], eax - mov edi, eax - _clear_ 256 ;clean extended information about process +;clean extended information about process + mov edi, [slot_base] + mov ecx, 265/4 + xor eax, eax + cld + rep stosd ; write application name lea eax, [filename] @@ -246,20 +153,32 @@ proc fs_execute jz .copy_process_name_done stosb loop .copy_process_name_loop + .copy_process_name_done: - mov ebx, [current_process] - mov [save_proc], ebx + mov edi, [cmdline] + xor eax, eax + test edi, edi + jz @F + + call _strlen + cmp eax, 256 + jb @F + lea ebx, [eax+1] + add [hdr_emem], ebx +@@: + mov [cmdline_size], eax + + stdcall create_process, [hdr_emem] - stdcall create_process, [hdr_mem], [file_base], [file_size] mov esi, -30; no memory test eax, eax - jz .failed + jz .err_hdr mov ebx, [sys_proc+LHEAD.prev] __list_add eax, ebx, sys_proc - mov ebx, [hdr_mem] + mov ebx, [hdr_emem] mov [eax+PROC.mem_used], ebx mov ebx, [slot_base] @@ -269,60 +188,39 @@ proc fs_execute lea ecx, [eax+PROC.thr_list] list_add_tail edx, ecx - xor edx, edx - cmp word [6], '02' - jne @f + mov esi, sizeof.APP_HDR + add esi, [cmdline_size] + mov edi, [filename] + call _strlen + add esi, eax + mov [filename_size], eax - not edx -@@: - mov [ebx+APPDATA.tls_base], edx + stdcall kernel_alloc, esi + mov [ebx+APPDATA.exec_params], eax + mov edi, eax + lea esi, [hdr_cmdline] + mov ecx, sizeof.APP_HDR/4 + rep movsd - mov ecx, [hdr_mem] - mov edi, [file_size] - add edi, 4095 - and edi, not 4095 - sub ecx, edi - jna @F + mov esi, [filename] + mov ecx, [filename_size] + rep movsb + mov ecx, [cmdline_size] + mov esi, [cmdline] + rep movsb - xor eax, eax - cld - rep stosb -@@: - -; release only virtual space, not phisical memory - - stdcall free_kernel_space, [file_base] lea eax, [hdr_cmdline] - lea ebx, [cmdline] - lea ecx, [filename] - stdcall set_app_params , [slot], eax, ebx, ecx, [flags] + stdcall set_app_params , [slot], eax, [flags] - mov eax, [save_proc] - call set_cr3 - - mov eax, [process_number];set result + mov eax, [process_number] ;set result call unlock_application_table + ret - jmp .final - -.failed: - mov eax, [save_proc] - call set_cr3 -.err: .err_hdr: stdcall kernel_free, [file_base] -.err_file: +.err_0: call unlock_application_table mov eax, esi -.final: -; cmp [SCR_MODE], word 0x13 -; jbe @f -; pushad -; stdcall set_cursor, [handle] -; mov [redrawmouse_unconditional], 1 -; call wakeup_osloop -; popad -;@@: ret endp @@ -344,17 +242,17 @@ test_app_header: jne .check_01_header mov ecx, [APP_HEADER_00.start] - mov [ebx+0x08], ecx ;app_eip + mov [ebx+APP_HDR.eip], ecx mov edx, [APP_HEADER_00.mem_size] - mov [ebx+0x10], edx ;app_mem + mov [ebx+APP_HDR._emem], edx shr edx, 1 sub edx, 0x10 - mov [ebx+0x0C], edx ;app_esp + mov [ebx+APP_HDR.esp], edx mov ecx, [APP_HEADER_00.i_param] - mov [ebx], ecx ;app_cmdline - mov [ebx+4], dword 0 ;app_path + mov [ebx+APP_HDR.cmdline], ecx + mov [ebx+APP_HDR.path], 0 mov edx, [APP_HEADER_00.i_end] - mov [ebx+0x14], edx + mov [ebx+APP_HDR._edata], edx ret .check_01_header: @@ -365,7 +263,7 @@ test_app_header: jne .fail @@: mov ecx, [APP_HEADER_01.start] - mov [ebx+0x08], ecx ;app_eip + mov [ebx+0x08], ecx mov edx, [APP_HEADER_01.mem_size] ; \begin{diamond}[20.08.2006] @@ -375,15 +273,15 @@ test_app_header: jb .fail ; \end{diamond}[20.08.2006] - mov [ebx+0x10], edx ;app_mem + mov [ebx+APP_HDR._emem], edx mov ecx, [APP_HEADER_01.stack_top] - mov [ebx+0x0C], ecx ;app_esp + mov [ebx+APP_HDR.esp], ecx mov edx, [APP_HEADER_01.i_param] - mov [ebx], edx ;app_cmdline + mov [ebx+APP_HDR.cmdline], edx mov ecx, [APP_HEADER_01.i_icon] - mov [ebx+4], ecx ;app_path + mov [ebx+APP_HDR.path], ecx mov edx, [APP_HEADER_01.i_end] - mov [ebx+0x14], edx + mov [ebx+APP_HDR._edata], edx ret .fail: xor eax, eax @@ -422,10 +320,8 @@ alloc_thread_slot: align 4 -proc create_process stdcall, app_size:dword,img_base:dword,img_size:dword +proc create_process stdcall, app_size:dword locals - app_pages dd ? - img_pages dd ? process dd ? app_tabs dd ? endl @@ -434,37 +330,13 @@ proc create_process stdcall, app_size:dword,img_base:dword,img_size:dword push esi push edi - mov ecx, pg_data.mutex - call mutex_lock - xor eax, eax mov [process], eax mov eax, [app_size] - add eax, 4095 - and eax, NOT(4095) - mov [app_size], eax - mov ebx, eax - shr eax, 12 - mov [app_pages], eax - - add ebx, 0x3FFFFF - and ebx, NOT(0x3FFFFF) - shr ebx, 22 - mov [app_tabs], ebx - - mov ecx, [img_size] - add ecx, 4095 - and ecx, NOT(4095) - - mov [img_size], ecx - shr ecx, 12 - mov [img_pages], ecx - - lea eax, [eax+ebx+2];all requested memory - - cmp eax, [pg_data.pages_free] - ja .fail + add eax, 0x3FFFFF + shr eax, 22 + mov [app_tabs], eax stdcall kernel_alloc, 0x2000 test eax, eax @@ -509,71 +381,36 @@ proc create_process stdcall, app_size:dword,img_base:dword,img_size:dword or eax, PG_SWR mov [edi-4096+(page_tabs shr 20)], eax - lea eax, [edi-8192] - call set_cr3 +xchg bx, bx - mov edx, [app_tabs] - xor edi, edi -@@: + lea edx, [edi-4096] + mov esi, [app_tabs] + +.alloc_page_dir: call alloc_page test eax, eax jz .fail + or eax, PG_UWR + mov [edx], eax - stdcall map_page_table, edi, eax - add edi, 0x00400000 - dec edx - jnz @B - - mov edi, page_tabs - - mov ecx, [app_tabs] - shl ecx, 10 + mov edi, [tmp_task_ptab] + stdcall map_page, edi, eax, PG_SWR + mov ecx, 1024 xor eax, eax rep stosd - mov ecx, [img_pages] - mov ebx, PG_UWR - xor edx, edx - mov esi, [img_base] - shr esi, 10 - add esi, page_tabs - mov edi, page_tabs -.remap: - lodsd - and eax, 0xFFFFF000 - or eax, ebx; force user level r/w access - stosd - add edx, 0x1000 - dec [app_pages] - dec ecx - jnz .remap + add edx, 4 + dec esi + jnz .alloc_page_dir - mov ecx, [app_pages] - test ecx, ecx - jz .done - -.alloc: - call alloc_page - test eax, eax - jz .fail - - stdcall map_page, edx, eax, dword PG_UWR - add edx, 0x1000 - dec [app_pages] - jnz .alloc - -.done: - mov ecx, pg_data.mutex - call mutex_unlock mov eax, [process] pop edi pop esi pop ebx ret + .fail: - mov ecx, pg_data.mutex - call mutex_unlock cmp [process], 0 je @f ;; stdcall destroy_app_space, [dir_addr], 0 @@ -958,8 +795,7 @@ proc new_sys_threads list_add_tail ebx, ecx ;add thread to process child's list lea eax, [app_cmdline] - stdcall set_app_params , [slot], eax, dword 0, \ - dword 0, [flags] + stdcall set_app_params , [slot], eax, [flags] mov eax, [process_number] ;set result call unlock_application_table @@ -972,6 +808,115 @@ proc new_sys_threads ret endp +proc map_process_image stdcall, img_size:dword, file_base:dword, file_size:dword + + mov edx, [img_size] + mov esi, [file_base] + mov ecx, [file_size] + add edx, 4095 + add ecx, 4095 + shr edx, 12 ; total pages + shr ecx, 12 ; image pages + + mov edi, page_tabs + shr esi, 10 + add esi, edi + +.map_image: + lodsd + and eax, -4096 + or eax, PG_UWR + stosd + dec edx + loop .map_image + + test edx, edx + jz .done +.map_bss: + call alloc_page + test eax, eax + jz .fail + + or eax, PG_UWR + stosd + dec edx + jnz .map_bss + + mov edi, [file_size] + mov ecx, [img_size] + add edi, 4095 + and edi, -4096 + add ecx, 4095 + and ecx, -4096 + sub ecx, edi + shr ecx, 2 + xor eax, eax + rep stosd + +.done: +.fail: + ret +endp + +align 4 +common_app_entry: + +xchg bx, bx + mov ebp, [current_slot] + mov ebp, [ebp+APPDATA.exec_params] + test ebp, ebp + jz .exit + + stdcall map_process_image, [ebp+APP_HDR._emem],\ + [ebp+APP_HDR.img_base], [ebp+APP_HDR.img_size] + + xor eax, eax + mov edi, [ebp+APP_HDR.path] + lea esi, [ebp+sizeof.APP_HDR] + mov ecx, [ebp+APP_HDR.filename_size] + test edi, edi + jnz .copy_filename + + add esi, ecx + jmp .copy_cmdline + +.copy_filename: + rep movsb + stosb + +.copy_cmdline: + mov edi, [ebx+APP_HDR.cmdline] + mov ecx, [ebx+APP_HDR.cmdline_size] + test edi, edi + jz .check_tls_header + + rep movsb + stosb + +.check_tls_header: + + cmp word [6], '02' + jne .cleanup + + call init_heap + stdcall user_alloc, 4096 + + mov edx, [current_slot] + mov [edx+APPDATA.tls_base], eax + mov [tls_data_l+2], ax + shr eax, 16 + mov [tls_data_l+4], al + mov [tls_data_l+7], ah + mov dx, app_tls + mov fs, dx + +.cleanup: + stdcall free_kernel_space, [ebp+APP_HDR.img_base] + stdcall kernel_free, ebp +.exit: + popad + iretd + align 4 tls_app_entry: @@ -995,10 +940,8 @@ EFL_IOPL1 equ 0x1000 EFL_IOPL2 equ 0x2000 EFL_IOPL3 equ 0x3000 - align 4 -proc set_app_params stdcall,slot:dword, params:dword,\ - cmd_line:dword, app_path:dword, flags:dword +proc set_app_params stdcall,slot:dword, params:dword, flags:dword locals pl0_stack dd ? @@ -1059,73 +1002,18 @@ proc set_app_params stdcall,slot:dword, params:dword,\ rep movsd shr ebx, 3 - mov eax, new_app_base - mov dword [CURRENT_TASK+ebx+0x10], eax + mov dword [CURRENT_TASK+ebx+0x10], 0 -.add_command_line: - mov edx, [params] - mov edx, [edx] ;app_cmdline - test edx, edx - jz @f ;application doesn't need parameters - - mov eax, edx - add eax, 256 - jc @f - -; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] -; ja @f - - mov eax, [cmd_line] - - cmp [edx], dword 0xffffffff ; extended destination tag - jne .no_ext_dest - - mov edx, [edx+4] ; extended destination for cmdline - jmp .continue - -.no_ext_dest: - mov [eax-12], dword 255 -.continue: - mov byte [edx], 0 ;force empty string if no cmdline given - - test eax, eax - jz @f -;-------------------------------------- - cmp [eax-4], dword 0xffffffff ; cmdline_flag - jne .old_copy - - push eax - stdcall strncpy, edx, [eax-8], [eax-12] - pop eax - - stdcall kernel_free, [eax-8] - jmp @f - -.old_copy: -;-------------------------------------- - stdcall strncpy, edx, eax, 256 -@@: - mov edx, [params] - mov edx, [edx+4];app_path - test edx, edx - jz @F ;application don't need path of file - mov eax, edx - add eax, 1024 - jc @f -; cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] -; ja @f - stdcall strncpy, edx, [app_path], 1024 -@@: mov ebx, [slot] mov eax, ebx shl ebx, 5 lea ecx, [draw_data+ebx];ecx - pointer to draw data - mov edx, irq0.return - cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1 - jne @F - mov edx, tls_app_entry -@@: +; mov edx, common_app_entry +; cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1 +; jne @F +; mov edx, tls_app_entry +;@@: ; set window state to 'normal' (non-minimized/maximized/rolled-up) state mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL mov [ebx+window_data+WDATA.fl_redraw], 1 @@ -1152,7 +1040,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\ lea ecx, [ebx+REG_EIP] xor eax, eax - mov [ebx+REG_RET], edx + mov [ebx+REG_RET], dword common_app_entry mov [ebx+REG_EDI], eax mov [ebx+REG_ESI], eax mov [ebx+REG_EBP], eax @@ -1162,8 +1050,8 @@ proc set_app_params stdcall,slot:dword, params:dword,\ mov [ebx+REG_ECX], eax mov [ebx+REG_EAX], eax - mov eax, [esi+0x08] ;app_eip - mov [ebx+REG_EIP], eax ;app_entry + mov eax, [esi+APP_HDR.eip] + mov [ebx+REG_EIP], eax mov [ebx+REG_CS], dword app_code mov ecx, USER_PRIORITY @@ -1172,12 +1060,11 @@ proc set_app_params stdcall,slot:dword, params:dword,\ mov [ebx+REG_CS], dword os_code ; kernel thread mov ecx, MAX_PRIORITY - @@: mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF - mov eax, [esi+0x0C] ;app_esp - mov [ebx+REG_APP_ESP], eax;app_stack + mov eax, [esi+APP_HDR.esp] + mov [ebx+REG_APP_ESP], eax mov [ebx+REG_SS], dword app_data lea edx, [ebx+REG_RET] diff --git a/kernel/branches/Kolibri-acpi/data32.inc b/kernel/branches/Kolibri-acpi/data32.inc index 17e4ca58da..a2a828ccd8 100644 --- a/kernel/branches/Kolibri-acpi/data32.inc +++ b/kernel/branches/Kolibri-acpi/data32.inc @@ -147,12 +147,10 @@ msg_unresolved db 'unresolved ',0 ;end if msg_CR db 13,10,0 -szHwMouse db 'ATI2D',0 szPS2MDriver db '/rd/1/drivers/PS2MOUSE.SYS',0 ;szCOM_MDriver db 'COM_MOUSE',0 szVidintel db '/rd/1/drivers/vidintel.sys',0 szUSB db 'USB',0 -szAtiHW db '/rd/1/drivers/ati2d.drv',0 szEXPORTS db 'EXPORTS',0 sz_EXPORTS db '_EXPORTS',0 @@ -160,8 +158,8 @@ sz_EXPORTS db '_EXPORTS',0 szIMPORTS db 'IMPORTS',0 read_firstapp db '/sys/' -firstapp db 'LAUNCHER',0 -notifyapp db '@notify',0 +firstapp db '/RD/1/LAUNCHER',0 +notifyapp db '/RD/1/@notify',0 if lang eq ru ud_user_message cp866 'Ошибка: неподдерживаемая инструкция процессора',0 mtrr_user_message cp866 '"Обнаружена проблема с конфигурацией MTRR.\nПроизводительность может быть пониженной" -dW',0 diff --git a/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc b/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc index 619dd0e4aa..846e41ce65 100644 --- a/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc +++ b/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc @@ -133,6 +133,15 @@ file_system_lfn: jnz @f mov esi, [esi] lodsb +@@: + lea ebp, [esi-1] + cmp dword [ebx], 7 + jne @F + mov edx, [ebx+4] + mov ebx, [ebx+8] + call fs_execute; ebp, ebx, edx + mov [image_of_eax], eax + ret @@: cmp al, '/' jz .notcurdir @@ -150,14 +159,6 @@ file_system_lfn: jz .rootdir call process_replace_file_name .parse_normal: - cmp dword [ebx], 7 - jne @F - mov edx, [ebx+4] - mov ebx, [ebx+8] - call fs_execute; esi+ebp, ebx, edx - mov [image_of_eax], eax - ret -@@: mov edi, rootdirs-8 xor ecx, ecx push esi diff --git a/kernel/branches/Kolibri-acpi/kernel.asm b/kernel/branches/Kolibri-acpi/kernel.asm index 65db61c6e5..48b731afdb 100644 --- a/kernel/branches/Kolibri-acpi/kernel.asm +++ b/kernel/branches/Kolibri-acpi/kernel.asm @@ -761,7 +761,7 @@ endg mov esi, boot_v86machine call boot_log ; Initialize system V86 machine - call init_sys_v86 +; call init_sys_v86 mov esi, boot_inittimer call boot_log @@ -974,7 +974,6 @@ include "detect/vortex86.inc" ; Vortex86 SoC detection code mov esi, 250 ; wait 1/4 a second call delay_ms rdtsc - sti sub eax, ecx xor edx, edx diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/PrimaryLoader.txt b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/PrimaryLoader.txt deleted file mode 100644 index eddd3f1633..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/PrimaryLoader.txt +++ /dev/null @@ -1,91 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -Спецификация на первичный загрузчик KordOS. -Загрузчик должен предоставлять следующие сервисы: -1. При загрузке компьютера, получив управление от BIOS'а, загружать - файл loader из папки kord по адресу 1000:0000. - Размер файла loader не превосходит 30000h = 192 Kb. -2. При этом устанавливать следующие регистры: - ax идентифицирует устройство: - al = тип: - 'f' - флопик - 'h' - HDD - 'c' - CD/DVD - 'u' - USB флешка - '?' - неизвестное устройство - ah = номер устройства (среди всех устройств фиксированного типа) - bx = тип файловой системы: - '12' = FAT12 - '16' = FAT16 - '32' = FAT32 - 'nt' = NTFS - 'is' = ISO-9660 - ds:si = far-указатель на callback-сервис -3. Предоставлять callback-сервис для вторичного загрузчика - far-процедуру: - на входе: ax = запрашиваемая функция - на выходе: CF=1, если функция не поддерживается; CF=0 иначе - Загрузчик может разрушать все регистры, включая сегментные, - за исключением ss и sp. -4. Всегда должна поддерживаться callback-функция 1: - назначение: прочитать файл, расположенный на загрузочном устройстве - на входе: ax = 1, ds:di = указатель на информационную структуру: - dw:dw far-указатель на буфер, - первое слово - смещение, второе - сегмент - dw максимальное число 4Kb-блоков для чтения (0x1000 байт) - должно быть ненулевым и строго меньше 0x100 - ASCIIZ имя файла в формате "<папка1>/<папка2>/<файл>" - Если имя файла содержит символы из старшей половины - ASCIIZ-таблицы или не является 8.3-именем (в смысле, одна из компонент - имени файла имеет имя длиннее 8 символов или расширение длиннее 3), - загрузчик может не найти такой файл, даже если он есть - (а может и найти). - на выходе: bx = статус: - 0 = успешно - 1 = файл оказался слишком большим, буфер заполнен целиком - и есть ещё данные файла - 2 = файл не найден - 3 = произошла ошибка чтения - dx:ax = размер файла или FFFF:FFFF, если файл не найден -5. Всегда должна поддерживаться callback-функция 2: - назначение: продолжить чтение файла, частично загруженного функцией 1 - на входе: ax = 2, ds:di = указатель на информационную структуру: - dw:dw far-указатель на буфер, - первое слово - смещение, второе - сегмент - dw максимальное число 4Kb-блоков для чтения (0x1000 байт) - должно быть ненулевым и строго меньше 0x100 - на выходе: bx = статус: - 0 = успешно - 1 = файл оказался слишком большим, буфер заполнен целиком - и есть ещё данные файла - 3 = произошла ошибка чтения - dx:ax = размер файла - Функцию можно вызывать только в случае, когда последний вызов функции - 1 и все последующие вызовы функции 2 вернули bx=1 (иными словами, - только для продолжения загрузки файла, который уже был частично - загружен, но ещё не загружен полностью). -Загрузчик может быть уверен, что данные в областях памяти 0-9000 и - 60000-A0000 не будут модифицированы ядром. diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/build.bat b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/build.bat deleted file mode 100644 index 5419e0d687..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -@fasm -m 65535 kordldr.win.asm kordldr.win -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/fat.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/fat.inc deleted file mode 100644 index 2399f48d34..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/fat.inc +++ /dev/null @@ -1,509 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; in: ss:bp = 0:dat -; in: es:bx = address to load file -; in: ds:si -> ASCIIZ name -; in: cx = limit in sectors -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) -load_file_fat: - mov eax, [bp + root_clus - dat] - mov [bp + cur_obj - dat], root_string - push es - push bx - push cx -.parse_dir_loop: -; convert name to FAT name - push [bp + cur_obj - dat] - push ax - mov [bp + cur_obj - dat], si - push ss - pop es -; convert ASCIIZ filename to FAT name - mov di, fat_filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -.nameloop: - lodsb - test al, al - jz .namedone - cmp al, '/' - jz .namedone - cmp al, '.' - jz .namedot - dec cx - js .badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp .nameloop -.namedot: - inc bx - jp .badname - add di, cx - mov cl, 3 - jmp .nameloop -.badname: - mov si, badname_msg - jmp find_error_si -.namedone: -; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si -; read a folder sector-by-sector and scan -; first, try to use the cache - push ss - pop ds - mov bx, -2 - mov cx, [bp + rootcache_size - dat] - cmp [bp + root_clus - dat], eax - jz .lookcache_root - mov di, foldcache_mark - xor bx, bx - mov cx, [bp + cachelimit - dat] -@@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz .cacheok - test edx, edx - jz .cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - js @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [bp + cachelimit - dat] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b -.cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - lea si, [di+bx] - mov dword [foldcache_clus+si-foldcache_mark+bx], eax -.cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [bp + cachelimit - dat] - add di, di -.cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns .cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 -.lookcache_root: -; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder - ;mov dx, bx - ;shl dx, 8 - ;add dx, 0x9200 - lea dx, [bx + 0x92] - xchg dl, dh - mov ds, dx - mov si, fat_filename ; ss:si -> filename in FAT style - call fat_scan_for_filename - jz .lookup_done -; cache miss, read folder data from disk -; we are reading parent directory, it can result in disk read errors; restore [cur_obj] - mov di, sp - mov bx, [bp + cur_obj - dat] - xchg bx, [ss:di+4] - mov [bp + cur_obj - dat], bx - mov bx, cx - add bx, 0xF - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -.folder_next_cluster: -; internal loop: scan sectors in cluster - movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus - push eax -; FAT12/16 root - special handling - test eax, eax - jnz .folder_notroot - mov cx, [ss:0x3211] ; BPB_RootEntCnt - mov dx, cx - add cx, 0xF - rcr cx, 1 - shr cx, 3 - mov eax, [bp + root_start - dat] - jmp .folder_next_sector -.folder_notroot: - mul ecx - add eax, [bp + data_start - dat] -.folder_next_sector: - sub dx, 0x10 -; skip first bx sectors - dec bx - jns .folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call read - jc ..found_disk_error -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - cmp di, 0x90 - jz .update_rootcache_size - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - jmp .updated_cachesize -.update_rootcache_size: - mov cl, 0x10 - cmp cx, dx - jb @f - mov cx, dx -@@: - add [bp + rootcache_size - dat], cx -.updated_cachesize: - popa -@@: - push es - mov cl, 0x10 ; ch=0 at this point - cmp cx, dx - jb @f - mov cx, dx -@@: - call fat_scan_for_filename - pop es - pop cx - jz .lookup_done_pop -.folder_skip_sector: - inc eax - loop .folder_next_sector - pop eax ; eax = current cluster - test eax, eax - jz @f - call [bp + get_next_cluster_ptr - dat] - jc .folder_next_cluster -@@: - stc - push eax -.lookup_done_pop: - pop eax -.lookup_done: - pop si -; CF=1 <=> failed - jnc .found - pop ds - pop [bp + cur_obj - dat] - mov si, error_not_found - jmp find_error_si -.found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop [bp + cur_obj - dat] ; forget old [cur_obj] - jz .regular_file - cmp byte [si-1], 0 - jnz .parse_dir_loop -..directory_error: - mov si, directory_string - jmp find_error_si -.regular_file: - cmp byte [si-1], 0 - jz @f -..notdir_error: - mov si, notdir_string - jmp find_error_si -@@: -; ok, we have found a regular file and the caller requested it -; parse FAT chunk - push ss - pop es - push ss - pop ds - mov di, 0x4005 - mov byte [di-5], 1 ; non-resident attribute - mov dword [di-4], 1 - stosd - pop cx - push cx -.parsefat: - call [bp + get_next_cluster_ptr - dat] - jnc .done - mov esi, [di-8] - add esi, [di-4] - cmp eax, esi - jz .contc - mov dword [di], 1 - scasd - stosd - jmp @f -.contc: - inc dword [di-8] -@@: - sub cl, [0x320D] - sbb ch, 0 - ja .parsefat -.done: - xor eax, eax - stosd - mov si, 0x4000 -load_file_common_end: - xor ecx, ecx - pop cx - pop bx - pop es - mov [bp + filesize - dat], edx - mov [bp + sectors_read - dat], ecx - add edx, 0x1FF - shr edx, 9 - mov [bp + filesize_sectors - dat], edx - cmp edx, ecx - seta al - mov ah, 0 - push ax - call read_file_chunk -continue_load_common_end: - mov [bp + cur_chunk_ptr - dat], si - pop bx - mov ax, word [bp + filesize - dat] - mov dx, word [bp + filesize+2 - dat] - jnc @f - mov bl, 3 ; read error -@@: - ret - -continue_load_file: -; es:bx -> buffer for output, ecx = cx = number of sectors - mov si, [bp + cur_chunk_ptr - dat] - push ecx - add ecx, [bp + sectors_read - dat] - mov [bp + sectors_read - dat], ecx - cmp [bp + filesize_sectors - dat], ecx - pop ecx - seta al - mov ah, 0 - push ax - push continue_load_common_end - push ss - pop ds - cmp [bp + cur_chunk_resident - dat], ah - jnz .nonresident -.resident: - mov ax, word [bp + num_sectors - dat] - jmp read_file_chunk.resident.continue -.nonresident: - mov eax, [bp + cur_cluster - dat] - mov edx, [bp + num_sectors - dat] - add eax, [bp + cur_delta - dat] - jmp read_file_chunk.nonresident.continue - -fat_scan_for_filename: -; in: ss:si -> 11-bytes FAT name -; in: ds:0 -> part of directory data -; in: cx = number of entries -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz .noent -.loop: - cmp byte [di], 0 - jz .notfound - test byte [di+11], 8 ; volume label? - jnz .cont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz .done -.cont: - add di, 0x20 - loop .loop -.noent: - inc cx ; clear ZF flag -.notfound: - stc -.done: - pop cx - ret - -fat12_get_next_cluster: -; in: ax = cluster (high word of eax is zero) -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 - push si - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 -@@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret - -fat16_get_next_cluster: -; in: ax = cluster (high word of eax is zero) -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 -; each sector contains 200h bytes = 100h FAT entries -; so ah = # of sector, al = offset in sector - push si - mov si, ax - shr si, 8 -; calculate segment for this sector of FAT table -; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) -; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x3400+si], 0 ; sector already loaded? - jnz .noread -; load corresponding sector, try all FATs if disk read error detected - pusha - movzx di, byte [ss:0x3210] ; BPB_NumFATs - xor bx, bx - mov ax, [ss:0x320E] ; BPB_RsvdSecCnt - xor dx, dx - add ax, si - adc dx, bx -@@: - push es - push dx ax - pop eax - mov cx, 1 ; read 1 sector - call read - pop es - jnc @f - add ax, [ss:0x3216] ; BPB_FATSz16 - adc dx, bx - dec di - jnz @b -..found_disk_error: - mov si, disk_error_msg - jmp find_error_si -@@: - popa -.noread: - mov si, ax - and si, 0xFF - add si, si - mov ax, [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret - -fat32_get_next_cluster: -; in: eax = cluster -; out: if there is next cluster: CF=1, eax = next cluster -; out: if there is no next cluster: CF=0 - push di - push ax - shr eax, 7 -; eax = FAT sector number; look in cache - push si - mov si, cache1head - call cache_lookup - pop si - jnc .noread -; read FAT, try all FATs if disk read error detected - push es - pushad - movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt - add eax, edx - movzx si, byte [ss:0x3210] ; BPB_NumFATs -@@: - lea cx, [di - 0x3400 + (0x6000 shr (9-3))] - shl cx, 9-3 - mov es, cx - xor bx, bx - mov cx, 1 - call read - jnc @f - add eax, [ss:0x3224] ; BPB_FATSz32 - dec si - jnz @b - jmp ..found_disk_error -@@: - popad - pop es -.noread: -; get requested item - lea ax, [di - 0x3400 + (0x6000 shr (9-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-3 - push ds - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop ds - pop di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.asm deleted file mode 100644 index 89d750247e..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.asm +++ /dev/null @@ -1,924 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond -; It is used when main bootloader is Windows loader. - -; this code is loaded: -; NT/2k/XP: by ntldr to 0D00:0000 -; 9x: by io.sys from config.sys to xxxx:0100 -; Vista: by bootmgr to 0000:7C00 - format binary - use16 - -; in any case, we relocate this code to 0000:0600 - org 0x600 -; entry point for 9x and Vista booting - call @f - db 'NTFS' -@@: - pop si - sub si, 3 - cmp si, 100h - jnz boot_vista - mov si, load_question + 100h - 600h - call out_string -; mov si, answer + 100h - 0600h ; already is -xxy: - mov ah, 0 - int 16h - or al, 20h - mov [si], al - cmp al, 'y' - jz xxz - cmp al, 'n' - jnz xxy -; continue load Windows -; call out_string -; ret -out_string: - push bx -@@: - lodsb - test al, al - jz @f - mov ah, 0Eh - mov bx, 7 - int 10h - jmp @b -@@: - pop bx - ret -xxz: -; boot KordOS - call out_string -; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers, -; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached - xor di, di - mov ds, di - mov word [di+4], new01handler + 100h - 600h - mov [di+6], cs - pushf - pop ax - or ah, 1 - push ax - popf -; we cannot issue INT 19h directly, because INT command clears TF -; int 19h ; don't issue it directly, because INT command clears TF -; so instead we use direct call -; pushf ; there will be no IRET - call far [di + 19h*4] -xxt: - xor di, di - mov ds, di - cmp word [di + 8*4+2], 0F000h - jz @f - les bx, [di + 8*4] - mov eax, [es:bx+1] - mov [di + 8*4], eax -@@: - mov si, 100h -boot_vista: -; relocate cs:si -> 0000:0600 - push cs - pop ds - xor ax, ax - mov es, ax - mov di, 0x600 - mov cx, 2000h/2 - rep movsw - jmp 0:real_entry - -load_question db 'Load KordOS? [y/n]: ',0 -answer db ? - db 13,10,0 - -new01handler: -; [sp]=ip, [sp+2]=cs, [sp+4]=flags - push bp - mov bp, sp - push ds - lds bp, [bp+2] - cmp word [ds:bp], 19cdh - jz xxt - pop ds - pop bp - iret - -; read from hard disk -; in: eax = absolute sector -; cx = number of sectors -; es:bx -> buffer -; out: CF=1 if error -read: - pushad - add eax, [bp + partition_start - dat] - cmp [bp + use_lba - dat], 0 - jz .chs -; LBA read - push ds -.lbado: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp + boot_drive - dat] - mov ah, 42h - int 13h - jc .disk_error_lba - add sp, 10h ; restore stack -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz .lbado - pop ds - popad - ret -.disk_error_lba: - add sp, 14h - pop ds - popad - stc - ret - -.chs: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx - -; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp + sectors - dat] - xor edx, edx - div esi - mov bx, dx ; bx = sector-1 - -; eax -> dx:ax - push eax - pop ax - pop dx -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp + heads - dat] - -; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si -@@: - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector -; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp + boot_drive - dat] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - add sp, 12 - popad - stc - ret -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz .chs - popad - ret - -disk_error2 db 'Fatal: cannot read partitions info: ' -disk_error_msg db 'disk read error',0 -disk_params_msg db 'Fatal: cannot get drive parameters',0 -start_msg db 2,' KordOS bootloader',13,10,0 -part_msg db 'looking at partition ' -part_char db '0' ; will be incremented before writing message - db ' ... ',0 -errfs_msg db 'unknown filesystem',13,10,0 -fatxx_msg db 'FATxx' -newline db 13,10,0 -ntfs_msg db 'NTFS',13,10,0 -error_msg db 'Error' -colon db ': ',0 -root_string db '\',0 -nomem_msg db 'No memory',0 -filesys_string db '(filesystem)',0 -directory_string db 'is a directory',0 -notdir_string db 'not a directory',0 - -; entry point for NT/2k/XP booting -; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256 - repeat 600h + 256h - $ - db 1 ; any data can be here; 1 in ASCII is a nice face :) - end repeat -; cs=es=0D00, ds=07C0, ss=0 -; esi=edi=ebp=0, esp=7C00 - xor si, si - jmp boot_vista - -real_entry: -; ax = 0 - mov ds, ax - mov es, ax -; our stack is 4 Kb: memory range 2000-3000 - mov ss, ax - mov sp, 3000h - mov bp, dat - sti ; just for case -; say hi to user - mov si, start_msg - call out_string -; we are booting from hard disk identified by [boot_drive] - mov dl, [bp + boot_drive - dat] -; is LBA supported? - mov [bp + use_lba - dat], 0 - mov ah, 41h - mov bx, 55AAh - int 13h - jc .no_lba - cmp bx, 0AA55h - jnz .no_lba - test cl, 1 - jz .no_lba - inc [bp + use_lba - dat] - jmp disk_params_ok -.no_lba: -; get drive geometry - mov ah, 8 - mov dl, [bp + boot_drive - dat] - int 13h - jnc @f - mov si, disk_params_msg - call out_string - jmp $ -@@: - movzx ax, dh - inc ax - mov [bp + heads - dat], ax - and cx, 3Fh - mov [bp + sectors - dat], cx -disk_params_ok: -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jc nomem - shr ax, 3 - mov [bp + cachelimit - dat], ax ; size of cache - 1 -; scan all partitions -new_partition_ex: - xor eax, eax ; read first sector of current disk area - mov [bp + extended_part_cur - dat], eax ; no extended partition yet - mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition - push es - mov cx, 1 - mov bx, 3000h - call read - pop es - jnc new_partition - mov si, disk_error2 - call out_string - jmp $ -new_partition: - mov bx, [bp + cur_partition_ofs - dat] - mov al, [bx+4] ; partition type - test al, al - jz next_partition - cmp al, 5 - jz @f - cmp al, 0xF - jnz not_extended -@@: -; extended partition - mov eax, [bx+8] ; partition start - add eax, [bp + extended_part_start - dat] - mov [bp + extended_part_cur - dat], eax -next_partition: - add [bp + cur_partition_ofs - dat], 10h - cmp [bp + cur_partition_ofs - dat], 31FEh - jb new_partition - mov eax, [bp + extended_part_cur - dat] - test eax, eax - jz partitions_done - cmp [bp + extended_part_start - dat], 0 - jnz @f - mov [bp + extended_part_start - dat], eax -@@: - mov [bp + extended_parent - dat], eax - mov [bp + partition_start - dat], eax - jmp new_partition_ex -partitions_done: - mov si, total_kaput - call out_string - jmp $ -not_extended: - mov eax, [bx+8] - add eax, [bp + extended_parent - dat] - mov [bp + partition_start - dat], eax -; try to load from current partition -; inform user - mov si, part_msg - inc [si + part_char - part_msg] - call out_string -; read bootsector - xor eax, eax - mov [bp + cur_obj - dat], filesys_string - push es - mov cx, 1 - mov bx, 3200h - call read - pop es - mov si, disk_error_msg - jc find_error_si - movzx si, byte [bx+13] - mov word [bp + sect_per_clust - dat], si - test si, si - jz unknown_fs - lea ax, [si-1] - test si, ax - jnz unknown_fs -; determine file system -; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h) - cmp word [bx+11], 0x200 - jnz unknown_fs -; is it NTFS? - cmp dword [bx+3], 'NTFS' - jnz not_ntfs - cmp byte [bx+16], bl - jz ntfs -not_ntfs: -; is it FAT? FAT12/FAT16/FAT32? -; get count of sectors to dword in cx:si - mov si, [bx+19] - xor cx, cx - test si, si - jnz @f - mov si, [bx+32] - mov cx, [bx+34] -@@: - xor eax, eax -; subtract size of system area - sub si, [bx+14] ; BPB_ResvdSecCnt - sbb cx, ax - mov ax, [bx+17] ; BPB_RootEntCnt - add ax, 0xF - rcr ax, 1 - shr ax, 3 - sub si, ax - sbb cx, 0 - push cx - push si - mov ax, word [bx+22] - test ax, ax - jnz @f - mov eax, [bx+36] -@@: - movzx ecx, byte [bx+16] - imul ecx, eax - pop eax - sub eax, ecx -; now eax = count of sectors in the data region - xor edx, edx - div [bp + sect_per_clust - dat] -; now eax = count of clusters in the data region - mov si, fatxx_msg - cmp eax, 0xFFF5 - jae test_fat32 -; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38 - cmp byte [bx+38], 0x29 - jnz not_fat - cmp ax, 0xFF5 - jae fat16 -fat12: - mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster - mov di, cx ; BPB_NumFATs - mov ax, '12' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string - movzx ecx, word [bx+22] ; BPB_FATSz16 -; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes) -.fatloop: -; if first copy is not readable, try to switch to other copies - push 0x6000 - pop es - xor bx, bx - movzx eax, word [0x320E] ; BPB_RsvdSecCnt - push cx - cmp cx, 12 - jb @f - mov cx, 12 -@@: - call read - pop cx - jnc fat1x_common - add eax, ecx ; switch to next copy of FAT - dec di - jnz .fatloop - mov si, disk_error_msg - jmp find_error_si -fat16: - mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster - mov ax, '16' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string -; FAT16: init FAT cache - no sectors loaded - mov di, 0x3400 - xor ax, ax - mov cx, 0x100/2 - rep stosw -fat1x_common: - mov bx, 0x3200 - movzx eax, word [bx+22] ; BPB_FATSz16 - xor esi, esi ; no root cluster - jmp fat_common -test_fat32: -; FAT32 bootsector has it at the offset +66 - cmp byte [bx+66], 0x29 - jnz not_fat - mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster - mov ax, '32' - push ax ; save for secondary loader - mov word [si+3], ax - call out_string -; FAT32 - init cache for FAT table: no sectors loaded - lea si, [bp + cache1head - dat] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [bp + cache1end - dat], 3400h ; first free item = 3400h - mov [bp + cache1limit - dat], 3C00h - mov eax, [bx+36] ; BPB_FATSz32 - mov esi, [bx+44] ; BPB_RootClus - jmp fat_common -not_fat: -unknown_fs: - mov si, errfs_msg - call out_string - jmp next_partition -fat_common: - push ss - pop es - movzx edx, byte [bx+16] ; BPB_NumFATs - mul edx - mov [bp + root_start - dat], eax ; this is for FAT1x -; eax = total size of all FAT tables, in sectors - movzx ecx, word [bx+17] ; BPB_RootEntCnt - add ecx, 0xF - shr ecx, 4 - add eax, ecx - mov cx, word [bx+14] ; BPB_RsvdSecCnt - add [bp + root_start - dat], ecx ; this is for FAT1x - add eax, ecx -; cluster 2 begins from sector eax - movzx ebx, byte [bx+13] ; BPB_SecPerClus - sub eax, ebx - sub eax, ebx - mov [bp + data_start - dat], eax -; no clusters in folders cache - mov di, foldcache_clus - 2 - xor ax, ax - mov cx, 7*8/2 + 1 - rep stosw - mov [bp + root_clus - dat], esi -; load secondary loader - mov [bp + load_file_ptr - dat], load_file_fat -load_secondary: - push 0x1000 - pop es - xor bx, bx - mov si, kernel_name - mov cx, 0x30000 / 0x200 - call [bp + load_file_ptr - dat] -; say error if needed - mov si, error_too_big - dec bx - js @f - jz find_error_si - mov si, disk_error_msg - jmp find_error_si -@@: -; fill loader information and jump to secondary loader - mov al, 'h' ; boot device: hard drive - mov ah, [bp + boot_drive - dat] - sub ah, 80h ; boot device: identifier - pop bx ; restore file system ID ('12'/'16'/'32'/'nt') - mov si, callback - jmp 1000h:0000h - -nomem: - mov si, nomem_msg - call out_string - jmp $ - -ntfs: - push 'nt' ; save for secondary loader - mov si, ntfs_msg - call out_string - xor eax, eax - mov [bp + data_start - dat], eax - mov ecx, [bx+40h] ; frs_size - cmp cl, al - jg .1 - neg cl - inc ax - shl eax, cl - jmp .2 -.1: - mov eax, ecx - shl eax, 9 -.2: - mov [bp + frs_size - dat], ax -; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different -; (at least with standard tools) -; we allow extra size, but no more than 0x1000 bytes = 4 Kb - mov si, invalid_volume_msg - cmp eax, 0x1000 - ja find_error_si -; must be multiple of sector size - test ax, 0x1FF - jnz find_error_si - shr ax, 9 - xchg cx, ax -; initialize cache - no data loaded - lea si, [bp + cache1head - dat] - mov [si], si - mov [si+2], si - mov word [si+4], 3400h ; first free item = 3400h - mov word [si+6], 3400h + 8*8 ; 8 items in this cache -; read first MFT record - description of MFT itself - mov [bp + cur_obj - dat], mft_string - mov eax, [bx+30h] ; mft_cluster - mul [bp + sect_per_clust - dat] - push 0x8000 - pop es - xor bx, bx - push es - call read - pop ds - call restore_usa -; scan for unnamed $DATA attribute - mov [bp + freeattr - dat], 4000h - mov ax, 80h - call load_attr - push ss - pop ds - mov si, nodata_string - jc find_error_si -; load secondary loader - mov [bp + load_file_ptr - dat], load_file_ntfs - jmp load_secondary - -find_error_si: - push si -find_error_sp: - cmp [bp + in_callback - dat], 0 - jnz error_in_callback - push ss - pop ds - push ss - pop es - mov si, error_msg - call out_string - mov si, [bp + cur_obj - dat] -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jz @f - mov ah, 0Eh - mov bx, 7 - int 10h - jmp @b -@@: - mov si, colon - call out_string - pop si - call out_string - mov si, newline - call out_string - mov sp, 0x3000 - jmp next_partition -error_in_callback: -; return status: file not found, except for read errors - mov bx, 2 - cmp si, disk_error_msg - jnz @f - inc bx -@@: - mov ax, 0xFFFF - mov dx, ax - mov sp, 3000h - 6 - ret - -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 3000h - mov bp, dat - mov [bp + in_callback - dat], 1 - push dx - push cx -; set ds:si -> ASCIIZ name - lea si, [di+6] -; set cx = limit in sectors; 4Kb = 8 sectors - movzx ecx, word [di+4] - shl cx, 3 -; set es:bx = pointer to buffer - les bx, [di] -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call [bp + load_file_ptr - dat] -callback_ret_succ: - clc -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -read_file_chunk.resident: -; auxiliary label for read_file_chunk procedure - mov di, bx - lodsw -read_file_chunk.resident.continue: - mov dx, ax - add dx, 0x1FF - shr dx, 9 - cmp dx, cx - jbe @f - mov ax, cx - shl ax, 9 -@@: - xchg ax, cx - rep movsb - xchg ax, cx - clc ; no disk error if no disk requests - mov word [bp + num_sectors - dat], ax - ret - -read_file_chunk: -; in: ds:si -> file chunk -; in: es:bx -> buffer for output -; in: ecx = maximum number of sectors to read (high word must be 0) -; out: CF=1 <=> disk read error - lodsb - mov [bp + cur_chunk_resident - dat], al - test al, al - jz .resident -; normal case: load (non-resident) attribute from disk -.read_block: - lodsd - xchg eax, edx - test edx, edx - jz .ret - lodsd -; eax = start cluster, edx = number of clusters, cx = limit in sectors - imul eax, [bp + sect_per_clust - dat] - add eax, [bp + data_start - dat] - mov [bp + cur_cluster - dat], eax - imul edx, [bp + sect_per_clust - dat] - mov [bp + num_sectors - dat], edx - and [bp + cur_delta - dat], 0 -.nonresident.continue: - cmp edx, ecx - jb @f - mov edx, ecx -@@: - test dx, dx - jz .read_block - add [bp + cur_delta - dat], edx - sub [bp + num_sectors - dat], edx - sub ecx, edx - push cx - mov cx, dx - call read - pop cx - jc .ret - test cx, cx - jnz .read_block -.ret: - ret - -cache_lookup: -; in: eax = value to look, si = pointer to cache structure -; out: di->cache entry; CF=1 <=> the value was not found - push ds bx - push ss - pop ds - mov di, [si+2] -.look: - cmp di, si - jz .not_in_cache - cmp eax, [di+4] - jz .in_cache - mov di, [di+2] - jmp .look -.not_in_cache: -; cache miss -; cache is full? - mov di, [si+4] - cmp di, [si+6] - jnz .cache_not_full -; yes, delete the oldest entry - mov di, [si] - mov bx, [di] - mov [si], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append -.cache_not_full: -; no, allocate new item - add word [si+4], 8 -.cache_append: - mov [di+4], eax - stc - jmp @f -.in_cache: -; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si -@@: -; add new sector to the end of list - mov bx, di - xchg bx, [si+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx - pop bx ds - ret - -include 'fat.inc' -include 'ntfs.inc' - -total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0 -error_too_big db 'file is too big',0 -nodata_string db '$DATA ' -error_not_found db 'not found',0 -noindex_string db '$INDEX_ROOT not found',0 -badname_msg db 'bad name for FAT',0 -invalid_volume_msg db 'invalid volume',0 -mft_string db '$MFT',0 -fragmented_string db 'too fragmented file',0 -invalid_read_request_string db 'cannot read attribute',0 - -kernel_name db 'kord/loader',0 - -align 4 -dat: - -extended_part_start dd 0 ; start sector for main extended partition -extended_part_cur dd ? ; start sector for current extended child -extended_parent dd 0 ; start sector for current extended parent -partition_start dd 0 ; start sector for current logical disk -cur_partition_ofs dw ? ; offset in MBR data for current partition -sect_per_clust dd 0 -; change this variable if you want to boot from other physical drive -boot_drive db 80h -in_callback db 0 - -; uninitialized data -use_lba db ? -cur_chunk_resident db ? -align 2 -heads dw ? -sectors dw ? -cache1head rw 2 -cache1end dw ? -cache1limit dw ? -data_start dd ? -cachelimit dw ? -load_file_ptr dw ? -cur_obj dw ? -missing_slash dw ? -root_clus dd ? -root_start dd ? -get_next_cluster_ptr dw ? -frs_size dw ? -freeattr dw ? -index_root dw ? -index_alloc dw ? -cur_index_seg dw ? -cur_index_cache dw ? -filesize dd ? -filesize_sectors dd ? -cur_cluster dd ? -cur_delta dd ? -num_sectors dd ? -sectors_read dd ? -cur_chunk_ptr dw ? - -rootcache_size dw ? ; must be immediately before foldcache_clus -if $-dat >= 0x80 -warning: - unoptimal data displacement! -end if -foldcache_clus rd 7 -foldcache_mark rw 7 -foldcache_size rw 7 -fat_filename rb 11 - -if $ > 2000h -error: - file is too big -end if - -; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long -repeat 0x2600 - $ - db 2 ; any data can be here; 2 is another nice face in ASCII :) -end repeat diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.txt b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.txt deleted file mode 100644 index 3affd3f39e..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.txt +++ /dev/null @@ -1,391 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Нет повести печальнее на свете, - Чем повесть о заклинившем Reset'е... - -Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает -Windows, для носителей с размером сектора 512 байт. - -===================================================================== - -Требования для работы: -1) Все используемые файлы должны быть читабельны. -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 592K свободной базовой памяти. -4) Пути к используемым файлам не должны содержать символических ссылок NTFS - (жёсткие ссылки допускаются). -5) Используемые файлы не должны быть сжатыми или разреженными файлами - (актуально для NTFS, для FAT выполнено автоматически). - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 08.08.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys - и file://C:/ntldr либо file://C:/bootmgr - неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx - официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx - формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx - -===================================================================== - -Схема используемой памяти: - 600-2000 код загрузчика (и данные) - 2000-3000 стек - 3000-3200 сектор MBR - 3200-3400 бутсектор логического диска - 3400-3C00 информация о кэше для таблиц FAT16/FAT32: - для FAT16 - массив на 0x100 байт, каждый байт равен - 0 или 1 в зависимости от того, загружен ли - соответствующий сектор таблицы FAT16; - для FAT32 - 100h входов по 8 байт: 4 байта - (две ссылки - вперёд и назад) для организации L2-списка - всех прочитанных секторов в порядке возрастания - последнего времени использования + 4 байта для номера - сектора; при переполнении кэша выкидывается элемент из - головы списка, то есть тот, к которому дольше всех - не было обращений - 3400-3440 информация о кэше для файловых записей NTFS в - таком же формате, как и кэш для FAT32, но на 8 входов - 3480-34C0 заголовки для кэшей записей индекса NTFS - 3500-3D00 информация о кэшах записей индекса NTFS: с каждой - файловой записью связан свой кэш для - соответствующего индекса - 4000-8000 место для информации об атрибутах для NTFS - 60000-80000 таблица FAT12 / место под таблицу FAT16 / - кэш для таблицы FAT32 / кэш для структур NTFS - 80000-90000 текущий рассматриваемый кластер - 90000-92000 FAT: кэш для корневой папки - 92000-... FAT: кэш для некорневых папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 7 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется - размещением команды install=c:\kordldr.win в первой строке config.sys; - при этом основной загрузчик системы загружает kordldr.win как обычный - com-файл, в какой-то сегмент по смещению 100h и передаёт управление - в начало кода (xxxx:0100). -0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется - добавлением строки наподобие c:\kordldr.win="KordOS" в секцию - [operating systems] файла boot.ini; если загружаемый файл имеет размер - не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS' - (в случае kordldr.win так и есть), то основной загрузчик каждой из - этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт - управление на адрес 0D00:0256. -0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями - с базой данных основного загрузчика через bcdedit и подробно описана в - инструкции к kordldr.win; основной загрузчик загружает целиком - kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода. -1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная - им программа окажется в свою очередь загрузчиком, и в этом случае - kordldr.win оказывается в условиях, когда основной загрузчик уже - установил какое-то окружение, в частности, перехватил некоторые - прерывания. Поэтому перед остальными действиями загрузчик должен - восстановить систему в начальное состояние. (При загрузке под - NT-линейкой такой проблемы не возникает, поскольку там основной - загрузчик ничего в системе не трогает.) Поэтому перед собственно - инициализацией KordOS при работе из-под DOS/9x производятся - дополнительные действия. Первым делом kordldr проверяет, какой из - случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт - управление не на начало кода): определяет значение ip (команда call - помещает в стек адрес следующей после call инструкции, команда pop si - выталкивает его в регистр si), и если оно равно 100h, то kordldr - загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения - у пользователя (поскольку в этой схеме kordldr загружается всегда, - он должен оставить возможность продолжить загрузку DOS/9x). Если - пользователь хочет продолжить обычную загрузку, kordldr завершается. - Иначе используется тот факт, что при выдаче прерывания перезагрузки - int 19h система предварительно снимает все свои перехваты BIOSовских - прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что - kordldr устанавливает свой обработчик трассировочного прерывания, - устанавливает флаг трассировки и передаёт управление DOSовскому - обработчику. Обработчик трассировочного прерывания ничего не делает - до тех пор, пока следующей инструкцией не оказывается int 19h, а - в этот момент отбирает управление и продолжает загрузку KordOS. - При этом BIOSовские обработчики восстановлены за исключением, - быть может, прерывания таймера int 8, которое, возможно, восстановлено - до команды jmp far на оригинальный обработчик. В последнем случае его - нужно восстановить явно. -2. Загрузчик перемещает свой код на адрес 0000:0600. -3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0, - настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы - все данные можно было адресовать через [bp+N] с однобайтовым N - (в дальнейшем они так и будут адресоваться для освобождения ds и - экономии на размере кода). Разрешает прерывания на случай, если - они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся - с весёлой рожицы (символ с ASCII-кодом 2). -4. Определяет характеристики жёсткого диска, указанного в качестве - загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h), - если LBA не поддерживается, то определяет геометрию - число дорожек - и число секторов на дорожке (функция 8 прерывания 13h), эти параметры - нужны функции чтения с диска. -5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска. - Цель цикла - для каждого логического диска попытаться загрузиться с - него (действия по загрузке с конкретного логического диска начинаются - с метки not_extended), при ошибке загрузки управление передаётся - назад этому циклу (метка next_partition), и поиск подходящего раздела - продолжается. На выходе заполняется одна переменная partition_start, - имеющая смысл начала текущего рассматриваемого логического диска, - но по ходу дела из-за приколов таблиц разделов используются ещё четыре - переменных. cur_partition_ofs - фактически счётчик цикла, формально - указатель на текущий вход в текущей загрузочной записи. Сама - загрузочная запись считывается в память начиная с адреса 3000h. - Три оставшихся нужны для правильной работы с расширенными разделами. - В каждой загрузочной записи помещается не более 4 записей о разделах. - Поэтому главной загрузочной записи, размещающейся в первом физическом - секторе диска, может не хватить, и обычно создаётся так называемый - расширенный раздел с расширенными загрузочными записями, формат - которых почти идентичен главной. Расширенный раздел может быть только - один, но в нём может быть много логических дисков и расширенных - загрузочных записей. Расширенные загрузочные записи организованы - в односвязный список, в каждой такой записи первый вход указывает - на соответствующий логический диск, а второй - на следующую расширенную - загрузочную запись. - При этом в главной загрузочной записи все адреса разделов являются - абсолютными номерами секторов. В расширенных же записях адреса разделов - относительны, причём с разными базами: адрес логического диска - указывается относительно расширенной записи, а адрес следующей - расширенной записи указывается относительно начала расширенного - раздела. Такой разнобой выглядит несколько странно, но имеет место - быть. Три оставшихся переменных содержат: extended_part_start - - начало расширенного раздела; extended_parent - текущая рассматриваемая - расширенная загрузочная запись; extended_part_cur - следующая - загрузочная запись для рассмотрения. - Цикл выглядит так: просматриваются все разделы, указанные в текущей - (главной или расширенной) загрузочной записи; для нормальных разделов - (они же логические диски) происходит переход на not_extended, где - устанавливается partition_start и начинается собственно загрузка - (последующие шаги); при встрече с разделом, тип которого указывает - на расширенность (5 или 0xF), код запоминает начало этого раздела - (в главной загрузочной записи такой тип означает расширенный раздел, - в расширенной - только указатель на следующую расширенную запись, - в обоих случаях он может встретиться только один раз в данной записи); - когда код доходит до конца списка, все нормальные разделы, описываемые - в этой записи, уже просмотрены, так что код с чистой совестью переходит - к следующей расширенной записи. Если он её не встретил, значит, уже - все логические разделы были подвергнуты попыткам загрузиться, и все - безрезультатно, так что выводится ругательство и работа останавливается - (jmp $). - Может возникнуть вопрос, зачем нужна такая сложная схема и почему - нельзя узнать нужный логический диск заранее или хотя бы ограничиться - первым попавшимся логическим диском, не крутя цикл. Так вот, вариант - с предварительным определением нужного раздела в данном случае не - используется, поскольку повлёк бы за собой нетривиальные лишние - действия по установке (в текущем виде установку можно провести вручную, - и она сводится к указанию системному загрузчику на существование - kordldr); кстати, в альтернативной версии загрузки после - Windows-загрузчика, когда установка осуществляется не вручную, а - специальной программой под Windows, используется модифицированная - версия, в которой как раз начальный физический сектор нужного раздела - прописывается установщиком. Сам kordldr не может установить, с какого - раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан - быть файлом на диске C:\). Вариант с первым попавшимся логическим - диском был реализован в первой версии загрузчика, но по ходу дела - обнаружилось, что таки нужно крутить цикл: во-вторых, может быть - приятным, что сама система может стоять вовсе не на системном C:\, а и - на других дисках; во-первых, диск C: может и не быть первым логическим - разделом - Vista любит создавать скрытый первичный раздел перед - системным, и тогда диск C: становится вторым логическим. -6. Извещает пользователя о том, что происходит попытка загрузки с очередного - логического диска. -7. Читает первый сектор логического диска и определяет файловую систему. - И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе - и должно совпадать с характеристикой физического носителя, то есть - 200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число - секторов в кластере и должно быть степенью двойки. - Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со - смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано - быть ненулевым). - Критерий FAT: загрузчик вычисляет число кластеров, определяет - предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению - +38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29). - После определения типа файловой системы извещает пользователя об - определённом типе. Если файловая система не распознана, выдаёт - соответствующее сообщение и переходит к следующему логическому диску. -8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы - - константу '12'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT12-обработчик; считывает в память всю - таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке - чтения пытается использовать другие копии FAT. -8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы - - константу '16'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию - о кэше секторов FAT (массив байт с возможными значениями 0 и 1, - означающими, был ли уже загружен соответствующий сектор - всего в - таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не - загружен, все байты нулевые. -8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы - - константу '32'; устанавливает указатель на функцию получения следующего - в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию - о кэше секторов FAT (формат информации описан выше, в распределении - используемой загрузчиком памяти) - ни один сектор ещё не загружен. -8г. Общее для FAT-томов: определяет значения служебных переменных - root_start (первый сектор корневого каталога в FAT12/16, игнорируется - при обработке FAT32-томов), data_start (начало данных с поправкой, - вводимой для того, чтобы кластер N начинался с сектора - N*sectors_per_cluster+data_start), root_clus (первый кластер корневого - каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию - загрузки файла на FAT-обработчик. -8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы - - константу 'nt'; определяет значение служебной переменной frs_size - (размер в байтах файловой записи, File Record Segment), для полной - корректности проверяет, что это значение (равное 0x400 байт на всех - реальных NTFS-томах - единственный способ изменить его заключается - в пересоздании всех системных структур вручную) не превосходит 0x1000 - и кратно размеру сектора 0x200 байт; инициализирует кэш файловых - записей - ничего ещё не загружено; считывает первый кластер $MFT - и загружает информацию о расположении на диске всей таблицы $MFT - (атрибут 0x80, $Data); устанавливает указатель на функцию загрузки - файла на NTFS-обработчик. -9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного - загрузчика. При обнаружении ошибки переходит на обработчик ошибок с - соответствующим сообщением. -10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск), - ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h), - может быть изменён путём модификации константы в исходнике или - специальным установщиком), bx=идентификатор файловой системы (берётся - из стека, куда ранее был засунут на шаге 8), ds:si=указатель на - callback-функцию. -11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -Чтение файла: -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным - кодом должна указывать на 0:dat. -2. Разбирает переданные параметры и вызывает процедуру загрузки файла. -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры. -Процедура чтения секторов (read): -на входе должно быть установлено: - ss:bp = 0:dat - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор (относительно начала логического диска) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, - флаг CF установлен, если возникла ошибка чтения -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя номер первого сектора логического диска, - найденный при переборе дисков. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура обработки ошибок (find_error_si и find_error_sp): -на входе: указатель на сообщение об ошибке в si либо на верхушке стека -0. Если вызывается find_error_si, она помещает переданный указатель в стек. -1. Если ошибка произошла в процессе работы callback-функции, то - (метка error_in_callback) обработчик просто возвращает управление - вызвавшему коду, рапортуя о ненайденном файле. -2. Если же ошибка произошла до передачи управления вторичному загрузчику, - обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>" - и (восстановив стек) переходит к следующему логическому диску. - -Процедура чтения файла/атрибута по известному размещению на диске - (read_file_chunk): -на входе должно быть установлено: - ds:si = указатель на информацию о размещении - es:bx = указатель на начало буфера, куда будут прочитаны данные - ecx = лимит числа секторов для чтения, старшее слово должно быть 0 -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, - флаг CF установлен, если возникла ошибка чтения -1. Определяет, является ли атрибут резидентным (возможно только в NTFS - и означает, что данные файла/атрибута уже были целиком прочитаны при - обработке информации о файле) или нерезидентным (означает, что данные - хранятся где-то на диске, и имеется информация о том, где именно). -2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует - данные по месту назначения (с учётом указанного лимита). -3. Для нерезидентных атрибутов информация состоит из пар <размер очередного - фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура - читает фрагменты, пока файл не закончится или пока не будет достигнут - указанный лимит. - -Процедура просмотра кэша (cache_lookup): -на входе должно быть установлено: - eax = искомое значение - ss:si = указатель на структуру-заголовок кэша -на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение - было только что добавлено, и сброшен, если оно уже было в кэше. -1. Просматривает кэш в поисках указанного значения. Если значение найдено - (при этом флаг CF оказывается сброшенным), переходит к шагу 4. -2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в - голове двусвязного списка), иначе добавляет к кэшу ещё один вход. -3. Устанавливает в полученном входе указанное значение. Устанавливает флаг - CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5. -4. Удаляет вход из списка. -5. Добавляет сектор в конец списка (самый новый вход). diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/ntfs.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/ntfs.inc deleted file mode 100644 index 2d1353e8d8..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/ntfs.inc +++ /dev/null @@ -1,587 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -restore_usa: -; Update Sequence Array restore -; in: ds:bx -> USA-protected structure - push bx - lea di, [bx+1feh] - mov cx, [bx+6] - add bx, [bx+4] - dec cx -@@: - mov ax, [bx+2] - mov [di], ax - inc bx - inc bx - add di, 200h - loop @b - pop bx - ret - -find_attr: -; in: ds:di->file record, ax=attribute -; out: ds:di->attribute or di=0 if not found - add di, [di+14h] -.1: -; attributes' codes are formally dwords, but all of them fit in word - cmp word [di], -1 - jz .notfound - cmp word [di], ax - jnz .continue -; for $DATA attribute, scan only unnamed - cmp ax, 80h - jnz .found - cmp byte [di+9], 0 - jz .found -.continue: - add di, [di+4] - jmp .1 -.notfound: - xor di, di -.found: - ret - -process_mcb_nonres: -; in: ds:si->attribute, es:di->buffer -; out: es:di->buffer end - pushad - pop di - add si, [si+20h] - xor ebx, ebx -.loop: - lodsb - test al, al - jz .done - push invalid_read_request_string - movzx cx, al - shr cx, 4 - jz find_error_sp - xchg ax, dx - and dx, 0Fh - jz find_error_sp - add si, cx - add si, dx - pop ax - push si - dec si - movsx eax, byte [si] - dec cx - jz .l1e -.l1: - dec si - shl eax, 8 - mov al, [si] - loop .l1 -.l1e: - xchg ebp, eax - dec si - movsx eax, byte [si] - mov cx, dx - dec cx - jz .l2e -.l2: - dec si - shl eax, 8 - mov al, byte [si] - loop .l2 -.l2e: - pop si - add ebx, ebp -; eax=length, ebx=disk block - stosd - mov eax, ebx - stosd - cmp di, 0x8000 - 12 - jbe .loop -..attr_overflow: - mov si, fragmented_string - jmp find_error_si -.done: - xor ax, ax - stosw - stosw - push di - popad - ret - -load_attr: -; in: ax=attribute, ds:bx->base record -; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated, -; edx=size of attribute in bytes -; out: if not found: CF=1 - mov di, [bp + freeattr - dat] - push ss - pop es - mov byte [es:di], 1 - inc di - cmp di, 0x8000 - 12 - ja ..attr_overflow - or edx, -1 ; file size is not known yet -; scan for attribute - push di - mov di, bx - add di, [di+14h] -@@: - call find_attr.1 - test di, di - jz .notfound1 - cmp byte [di+8], 0 - jnz .nonresident - mov si, di - pop di - push ds - jmp .resident -.aux_resident: - mov ax, ds - mov si, di - pop di ds bx ds edx - push ss - pop es - push ds - mov ds, ax -; resident attribute -.resident: - dec di - mov al, 0 - stosb - mov ax, [si+10h] - stosw - push di - add di, ax - cmp di, 0x8000 - 12 - pop di - ja ..attr_overflow - movzx edx, ax ; length of attribute - xchg ax, cx - add si, [si+14h] - rep movsb - mov [bp + freeattr - dat], di - pop ds - ret -.nonresident: -; nonresident attribute - cmp dword [di+10h], 0 - jnz @b -; read start of data - mov si, di - mov edx, [di+30h] ; size of attribute - pop di - call process_mcb_nonres - sub di, 4 - push di -.notfound1: - pop di - push edx -; $ATTRIBUTE_LIST is always in base file record - cmp ax, 20h - jz .nofragmented -; try to load $ATTRIBUTE_LIST = 20h - push ax - mov ax, 20h - push [bp + freeattr - dat] - mov [bp + freeattr - dat], di - push di - call load_attr - pop di - pop [bp + freeattr - dat] - pop ax - jc .nofragmented - push ds bx - pusha - mov si, di - push ss - pop ds - push 0x8100 - pop es - xor ecx, ecx - mov cl, 0x78 - xor bx, bx - push es - call read_file_chunk - pop ds - jc ..found_disk_error - test cx, cx - jz ..attr_overflow - popa - push ss - pop es - xor bx, bx -.1: - cmp [bx], ax - jnz .continue1 -; only unnamed $DATA attributes! - cmp ax, 80h - jnz @f - cmp byte [bx+6], 0 - jnz .continue1 -@@: - cmp dword [bx+10h], 0 - jz .continue1 - cmp dword [bx+8], 0 - jnz @f - dec di - cmp di, [bp + freeattr - dat] - lea di, [di+1] - jnz .continue1 -@@: - push ds di - push ax - mov eax, [bx+10h] - mov ecx, [bx+8] - call read_file_record - pop ax - mov di, [14h] -.2: - call find_attr.1 - cmp byte [di+8], 0 - jz .aux_resident - cmp dword [di+10h], ecx - jnz .2 - mov si, di - mov di, sp - cmp dword [ss:di+8], -1 - jnz @f - push dword [si+30h] ; size of attribute - pop dword [ss:di+8] -@@: - pop di - call process_mcb_nonres - sub di, 4 - pop ds -.continue1: - add bx, [bx+4] - cmp bx, dx - jb .1 - pop bx ds -.nofragmented: - pop edx - dec di - cmp di, [bp + freeattr - dat] - jnz @f - stc - ret -@@: - inc di - xor ax, ax - stosw - stosw - mov [bp + freeattr - dat], di - ret - -read_file_record: -; in: eax = index of record -; out: ds:0 -> record -; find place in cache - push di - push si - mov si, cache1head - call cache_lookup - pop si - pushf - sub di, 3400h - shl di, 10-3 - add di, 0x6000 - mov ds, di - popf - pop di - jnc .noread -; read file record to ds:0 - pushad - push ds - push es - movzx ecx, [bp + frs_size - dat] - shr cx, 9 - mul ecx - push ds - pop es - push ss - pop ds - mov si, 0x4000 - xor bx, bx - push [bp + cur_obj - dat] - mov [bp + cur_obj - dat], mft_string - push es - call read_attr -; initialize cache for $INDEX_ALLOCATION for this record - pop si - push si - sub si, 0x6000 - mov ax, si - shr si, 10-3 - shr ax, 2 - add si, 3480h - add ax, 3500h - mov [si], si - mov [si+2], si - mov [si+4], ax - pop ds - call restore_usa - pop [bp + cur_obj - dat] - pop es - pop ds - popad -.noread: - ret - -read_attr: -; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute - push invalid_read_request_string - cmp byte [si], 0 - jnz .nonresident - cmp eax, 10000h shr 9 - jae find_error_sp - shl ax, 9 - shl cx, 9 - cmp ax, [si+2] - jae find_error_sp - cmp cx, [si+2] - ja find_error_sp - add si, 3 - add si, ax - mov di, bx - rep movsb - pop ax - ret -.nonresident: - inc si -.loop: - mov edx, dword [si] - add si, 8 - test edx, edx - jz find_error_sp - imul edx, [bp + sect_per_clust - dat] - sub eax, edx - jnc .loop - add eax, edx - sub edx, eax - push cx - cmp ecx, edx - jb @f - mov cx, dx -@@: - push bx - mov ebx, [si-4] - imul ebx, [bp + sect_per_clust - dat] - add eax, ebx - pop bx - call read - jc ..found_disk_error - mov dx, cx - pop cx - xor eax, eax - sub cx, dx - jnz .loop - pop ax - ret - -load_file_ntfs: -; in: ss:bp = 0:dat -; in: es:bx = address to load file -; in: ds:si -> ASCIIZ name -; in: cx = limit in sectors -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - push es bx cx - mov eax, 5 ; root cluster - mov [bp + cur_obj - dat], root_string -.parse_dir_loop: - push ds si - call read_file_record -; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP - mov ax, [bp + freeattr - dat] - mov [bp + index_root - dat], ax - mov ax, 90h ; $INDEX_ROOT - xor bx, bx - call load_attr - mov si, noindex_string - jc find_error_si - mov ax, [bp + freeattr - dat] - mov [bp + index_alloc - dat], ax - mov ax, 0A0h ; $INDEX_ALLOCATION - call load_attr - jnc @f - mov [bp + index_alloc - dat], bx -@@: - push ds -; search for entry - mov si, [bp + index_root - dat] - push ss - pop ds - push 0x8100 - pop es - xor ecx, ecx - mov cl, 0x78 - xor bx, bx - push es - call read_file_chunk - pop ds - jc ..found_disk_error - test cx, cx - jz ..attr_overflow - mov si, invalid_read_request_string - cmp word [bx+10], 0 - jnz find_error_si -; calculate number of items in cache - mov di, [bx+8] ; subnode_size - mov ax, 0x4000 - sub ax, word [bp + frs_size - dat] - cwd - div di - test ax, ax - jz find_error_si - mov si, invalid_volume_msg - test di, 0x1FF - jnz find_error_si - pop cx - mov [bp + cur_index_seg - dat], cx - shl ax, 3 - sub cx, 6000h - mov si, cx - shr cx, 2 - shr si, 10-3 - add cx, ax - add si, 3480h - mov [bp + cur_index_cache - dat], si - add cx, 3500h - mov [ss:si+6], cx - mov dx, di - add bx, 10h -.scan_record: - add bx, [bx] -.scan: - test byte [bx+0Ch], 2 - jnz .look_child - movzx cx, byte [bx+50h] ; namelen - lea di, [bx+52h] ; name - push ds - pop es - pop si ds - push ds si - xor ax, ax -.1: - lodsb - cmp al, '/' - jnz @f - mov al, 0 -@@: - cmp al, 'A' - jb .nocapital - cmp al, 'Z' - ja .nocapital - or al, 20h -.nocapital: - cmp al, 'a' - jb .notletter - cmp al, 'z' - ja .notletter - or byte [es:di], 20h -.notletter: - scasw - loopz .1 - jb .look_child - ja @f - cmp byte [si], 0 - jz .file_found - cmp byte [si], '/' - jz .file_found -@@: - push es - pop ds - add bx, [bx+8] - jmp .scan -.look_child: - push es - pop ds - test byte [bx+0Ch], 1 - jz .not_found - mov si, [bp + index_alloc - dat] - test si, si - jz .not_found - add bx, [bx+8] - mov eax, [bx-8] - mov es, [bp + cur_index_seg - dat] - push si - mov si, [bp + cur_index_cache - dat] - call cache_lookup - pop si - pushf - mov bx, di - mov bh, 0 - shr bx, 3 - imul bx, dx - add bx, [bp + frs_size - dat] - popf - jnc .noread - push es - push dx - push ss - pop ds - movzx ecx, dx - shr cx, 9 - mul [bp + sect_per_clust - dat] - call read_attr - pop dx - pop es - push es - pop ds - call restore_usa -.noread: - push es - pop ds - add bx, 18h - jmp .scan_record -.not_found: - pop [bp + cur_obj - dat] - mov si, error_not_found - jmp find_error_si -.file_found: - pop [bp + cur_obj - dat] - pop cx - mov ax, [bp + index_root - dat] - mov [bp + freeattr - dat], ax - mov eax, [es:bx] - test byte [es:bx+48h+3], 10h - jz .regular_file - cmp byte [si], 0 - jz ..directory_error - inc si - jmp .parse_dir_loop -.regular_file: - cmp byte [si], 0 - jnz ..notdir_error -; read entry - call read_file_record - xor bx, bx - mov ax, 80h - call load_attr - mov si, nodata_string - jc find_error_si - mov si, [bp + index_root - dat] - mov [bp + freeattr - dat], si - push ss - pop ds - jmp load_file_common_end diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/build.bat b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/build.bat deleted file mode 100644 index 24948f9fea..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/build.bat +++ /dev/null @@ -1,20 +0,0 @@ -echo off -cls -echo ** bulding after win loader ** -@fasm -m 65535 after_win/kordldr.win.asm after_win/kordldr.win -echo ============================== -echo ** building first loader for cd/dvd ** -@fasm -m 65535 cdfs/bootsect.asm cdfs/bootsect.bin -echo ============================== -echo ** building first loader for fat12/fat16 ** -@fasm -m 65535 fat1x/bootsect.asm fat1x/bootsect.bin -@fasm -m 65535 fat1x/kordldr.f1x.asm fat1x/kordldr.f1x -echo ============================== -echo ** building firs loader for fat32 ** -@fasm -m 65535 fat32/bootsect.asm fat32/bootsect.bin -@fasm -m 65535 fat32/kordldr.f1x.asm fat32/kordldr.f1x -echo ============================== -echo ** make a image of fdd ** -@fasm -m 65535 floppy.asc kord.img - -@pause diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.asm deleted file mode 100644 index 9c0072afbe..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.asm +++ /dev/null @@ -1,1024 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - jmp far 0:real_start -; special text -org $+0x7C00 -real_start: -; initialize - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov es, ax - cld - sti - mov [bootdrive], dl -; check LBA support - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cl, 1 - jz err_ -; get file system information -; scan for Primary Volume Descriptor - db 66h - push 10h-1 - pop eax -pvd_scan_loop: - mov cx, 1 - inc eax - mov bx, 0x1000 - call read_sectors - jnc @f -fatal_read_err: - mov si, aReadError -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -@@: - push ds - pop es - cmp word [bx+1], 'CD' - jnz pvd_scan_loop - cmp word [bx+3], '00' - jnz pvd_scan_loop - cmp byte [bx+5], '1' - jnz pvd_scan_loop -; we have found ISO9660 descriptor, look for type - cmp byte [bx], 1 ; Primary Volume Descriptor? - jz pvd_found - cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator? - jnz pvd_scan_loop -; Volume Descriptor Set Terminator reached, no PVD found - fatal error - mov si, no_pvd - jmp err_ -pvd_found: - add bx, 80h - mov ax, [bx] - mov [lb_size], ax -; calculate number of logical blocks in one sector - mov ax, 800h - cwd - div word [bx] - mov [lb_per_sec], ax -; get location of root directory - mov di, root_location - movzx eax, byte [bx+1Dh] - add eax, [bx+1Eh] - stosd -; get memory size - int 12h - mov si, nomem_str - cmp ax, 71000h / 400h - jb err_ - shr ax, 1 - sub ax, 60000h / 800h - mov [size_rest], ax - mov [free_ptr], 60000h / 800h -; load path table -; if size > 62K => it's very strange, avoid using it -; if size > (size of cache)/2 => avoid using it too - mov ecx, [bx+4] - cmp ecx, 0x10000 - 0x800 - ja nopathtable - shr ax, 1 - cmp ax, 0x20 - jae @f - shl ax, 11 - cmp cx, ax - ja nopathtable -@@: -; size is ok, try to load it - mov [pathtable_size], cx - mov eax, [bx+12] - xor edx, edx - div dword [lb_per_sec] - imul dx, [bx] - mov [pathtable_start], dx - add cx, dx - call cx_to_sectors - xor bx, bx - push 6000h - pop es - call read_sectors - jc nopathtable -; path table has been loaded - inc [use_path_table] - sub [size_rest], cx - add [free_ptr], cx -nopathtable: -; init cache - mov ax, [size_rest] - mov [cache_size], ax - mov ax, [free_ptr] - mov [cache_start], ax -; load secondary loader - mov di, secondary_loader_info - call load_file - test bx, bx - jnz noloader -; set registers for secondary loader - mov ah, [bootdrive] - mov al, 'c' - mov bx, 'is' - mov si, callback - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 - -noloader: - mov si, aKernelNotFound - jmp err_ - -read_sectors: -; es:bx = pointer to data -; eax = first sector -; cx = number of sectors - pushad - push ds -do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - db 66h - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [cs:bootdrive] - mov ah, 42h - int 13h - jc diskreaderr -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 7 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popad - ret -diskreaderr: - add sp, 10h + 2*2 - pop ds - popad - stc -out_string.ret: - ret - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz .ret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aNoLBA db 'The drive does not support LBA!',0 -aReadError db 'Read error',0 -no_pvd db 'Primary Volume Descriptor not found!',0 -nomem_str db 'No memory',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 - -load_file: -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) -; parse path to the file - lea si, [di+6] - mov eax, [cs:root_location] - cmp [cs:use_path_table], 0 - jz parse_dir -; scan for path in path table - push di - push 6000h - pop es - mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table - mov dx, 1 ; dx = number of current entry in path table, start from 1 - mov cx, [cs:pathtable_size] -pathtable_newparent: - mov bx, dx ; bx = number of current parent in path table: root = 1 -scan_path_table_e: - call is_last_component - jnc path_table_scanned -scan_path_table_i: - cmp word [es:di+6], bx - jb .next - ja path_table_notfound - call test_filename1 - jc .next -@@: - lodsb - cmp al, '/' - jnz @b - jmp pathtable_newparent -.next: -; go to next entry - inc dx - movzx ax, byte [es:di] - add ax, 8+1 - and al, not 1 - add di, ax - sub cx, ax - ja scan_path_table_i -path_table_notfound: - pop di - mov ax, -1 - mov dx, ax - mov bx, 2 ; file not found - ret -path_table_scanned: - movzx eax, byte [es:di+1] - add eax, [es:di+2] - pop di -parse_dir: -; eax = logical block, ds:di -> information structure, ds:si -> file name -; was the folder already read? - push di ds - push cs - pop ds - mov [cur_desc_end], 2000h - mov bx, cachelist -.scan1: - mov bx, [bx+2] - cmp bx, cachelist - jz .notfound - cmp [bx+4], eax - jnz .scan1 -.found: -; yes; delete this item from the list (the following code will append this item to the tail) - mov di, [bx] - push word [bx+2] - pop word [di+2] - mov di, [bx+2] - push word [bx] - pop word [di] - mov di, bx - jmp .scan -.notfound: -; no; load first sector of the folder to get its size - push eax - push si - mov si, 1 - call load_phys_sector_for_lb_force - mov bx, si - pop si - pop eax - jnc @f -; read error - return -.readerr: - pop ds -.readerr2: - pop di - mov ax, -1 - mov dx, ax - mov bx, 3 - ret -@@: -; first item of the folder describes the folder itself -; do not cache too big folders: size < 64K and size <= (total cache size)/2 - cmp word [bx+12], 0 - jnz .nocache - mov cx, [cache_size] ; cx = cache size in sectors - shr cx, 1 ; cx = (cache size)/2 - cmp cx, 0x20 - jae @f - shl cx, 11 - cmp [bx+10], cx - ja .nocache -@@: -; we want to cache this folder; get space for it - mov cx, [bx+10] - call cx_to_sectors - jnz .yescache -.nocache: - push dword [bx+10] - pop dword [cur_nocache_len] - call lb_to_sector - push ds - pop es - pop ds -.nocache_loop: - push eax - mov dx, 1800h - call scan_for_filename_in_sector - mov cx, dx - pop eax - jnc .j_scandone - sub cx, bx - sub word [es:cur_nocache_len], cx - sbb word [es:cur_nocache_len+2], 0 - jb .j_scandone - ja @f - cmp word [es:cur_nocache_len], 0 - jz .j_scandone -@@: - mov cx, 1 - inc eax - push es - mov bx, 1000h - call read_sectors - pop es - jc .readerr2 - jmp .nocache_loop -.j_scandone: - jmp .scandone -.yescache: - push bx - mov bx, [cachelist.head] -.freeloop: - cmp cx, [size_rest] - jbe .sizeok -@@: -; if we are here: there is not enough free space, so we must delete old folders' data -; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2). -; one loop iteration: delete data of one folder - pusha - mov dx, [bx+10] - mov es, dx ; es = segment of folder data to be deleted - xor di, di - mov ax, [bx+8] - add ax, 0x7FF - rcr ax, 1 - shr ax, 10 - push ax - shl ax, 11-4 ; get number of paragraphs in folder data to be deleted - mov cx, [cache_size] - add cx, [cache_start] - push ds - push ax - add ax, dx - mov ds, ax - pop ax - shl cx, 11-4 - sub cx, dx ; cx = number of paragraphs to be moved - push si - xor si, si -; move cx paragraphs from ds:si to es:di to get free space in the end of cache -@@: - sub cx, 1000h - jbe @f - push cx - mov cx, 8000h - rep movsw - mov cx, ds - add cx, 1000h - mov ds, cx - mov cx, es - add cx, 1000h - mov es, cx - pop cx - jmp @b -@@: - add cx, 1000h - shl cx, 3 - rep movsw - pop si - pop ds -; correct positions in cache for existing items - mov cx, 80h - mov di, 8400h -.correct: - cmp [di+10], dx - jbe @f - sub [di+10], ax -@@: - add di, 12 - loop .correct -; some additional space is free now - pop ax - add [size_rest], ax - sub [free_ptr], ax -; add cache item to the list of free items - mov dx, [bx] - mov ax, [free_cache_item] - mov [bx], ax - mov [free_cache_item], bx - mov bx, dx -; current iteration done - popa - jmp .freeloop -.sizeok: - mov [cachelist.head], bx - mov word [bx+2], cachelist -; allocate new item in cache - mov di, [free_cache_item] - test di, di - jz .nofree - push word [di] - pop [free_cache_item] - jmp @f -.nofree: - mov di, [last_cache_item] - add [last_cache_item], 12 -@@: - pop bx - push si di -; mov [di+4], eax ; start of folder - scasd - stosd - push ax - mov ax, [free_ptr] - shl ax, 11-4 - mov [di+10-8], ax - mov es, ax - pop ax - add [free_ptr], cx - sub [size_rest], cx -; read folder data -; first sector is already in memory, 0000:bx - pusha - mov cx, [bx+10] - mov [di+8-8], cx ; folder size in bytes - mov si, bx - xor di, di - mov cx, 0x1800 - sub cx, si - rep movsb - pop ax - push di - popa -; read rest of folder - mov esi, dword [lb_per_sec] - add eax, esi - dec si - not si - and ax, si - mov si, word [bx+10] - mov bx, di - pop di - sub si, bx - jbe @f - mov [cur_limit], esi - call read_many_bytes - pop si - jnc .scan - jmp .readerr -@@: - pop si -.scan: -; now we have required cache item; append it to the end of list - mov bx, [cachelist.tail] - mov [cachelist.tail], di - mov [di+2], bx - mov word [di], cachelist - mov [bx], di -; scan for given filename - mov es, [di+10] - mov dx, [di+8] - pop ds - xor bx, bx - call scan_for_filename_in_sector -.scandone: - push cs - pop es - mov bx, 2000h - cmp bx, [es:cur_desc_end] - jnz filefound -j_notfound: - jmp path_table_notfound -filefound: -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b -@@: - mov cl, [es:bx+8] - test al, al - jz @f -; parse next component of file name - test cl, 2 ; directory? - jz j_notfound - mov eax, [es:bx] - pop di - jmp parse_dir -@@: - test cl, 2 ; directory? - jnz j_notfound ; do not allow read directories as regular files -; ok, now load the file - pop di - les bx, [di] - call normalize - movzx esi, word [di+4] ; esi = limit in 4K blocks - shl esi, 12 ; esi = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, 2000h -loadloop: - and [cur_start], 0 -.loadnew: - mov esi, [cur_limit] - mov eax, [cur_start] - add esi, eax - mov [overflow], 1 - sub esi, [di+4] - jb @f - xor esi, esi - dec [overflow] -@@: - add esi, [di+4] ; esi = number of bytes to read - mov [cur_start], esi - sub esi, eax - jz .loadcontinue - xor edx, edx - div dword [lb_size] ; eax = number of logical blocks to skip, - mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block - cmp byte [di+10], 0 - jnz .interleaved - add eax, [di] -; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - jc .readerr3 -.loadcontinue: - mov [cur_chunk], di - add di, 11 - cmp di, [cur_desc_end] - jae @f - cmp [cur_limit], 0 - jnz loadloop -@@: - mov bx, [overflow] -.calclen: -; calculate length of file - xor ax, ax - xor dx, dx - mov di, 2000h -@@: - add ax, [di+4] - adc dx, [di+6] - add di, 11 - cmp di, [cur_desc_end] - jb @b - ret -.interleaved: - mov [cur_unit_limit], esi - push esi -; skip first blocks - movzx ecx, byte [di+9] ; Unit Size - movzx esi, byte [di+10] ; Interleave Gap - add si, cx - mov edx, [di] -@@: - sub eax, ecx - jb @f - add edx, esi - jmp @b -@@: - add ecx, eax ; ecx = number of logical blocks to skip - lea eax, [ecx+edx] ; eax = first logical block - pop esi -.interleaved_loop: -; get number of bytes in current file unit - push eax - movzx eax, byte [di+9] - sub ax, cx - imul eax, dword [lb_size] - cmp eax, esi - ja .i2 -.i1: - xchg esi, eax -.i2: - pop eax - sub [cur_unit_limit], esi - push eax -; read esi bytes from logical block eax to buffer es:bx - call read_many_bytes.with_first - pop eax - jnc @f -.readerr3: - mov bx, 3 - jmp .calclen -@@: - mov esi, [cur_unit_limit] - test esi, esi - jz .loadcontinue - movzx ecx, byte [di+9] ; add Unit Size - add cl, byte [di+10] ; add Interleave Gap - adc ch, 0 - add eax, ecx - xor cx, cx - mov [first_byte], cx - jmp .interleaved_loop - -cx_to_sectors: - add cx, 7FFh - rcr cx, 1 - shr cx, 10 - ret - -is_last_component: -; in: ds:si -> name -; out: CF set <=> current component is not last (=> folder) - push si -@@: - lodsb - test al, al - jz @f - cmp al, '/' - jnz @b - stc -@@: - pop si - ret - -test_filename1: -; in: ds:si -> filename, es:di -> path table item -; out: CF set <=> no match - pusha - mov cl, [es:di] - add di, 8 - jmp test_filename2.start -test_filename2: -; in: ds:si -> filename, es:bx -> directory item -; out: CF set <=> no match - pusha - mov cl, [es:bx+32] - lea di, [bx+33] -.start: - mov ch, 0 -@@: - lodsb - test al, al - jz .test1 - cmp al, '/' - jz .test1 - call toupper - mov ah, al - mov al, [es:di] - call toupper - inc di - cmp al, ah - loopz @b - jnz .next1 -; if we have reached this point: current name is done - lodsb - test al, al - jz .ret - cmp al, '/' - jz .ret -; if we have reached this point: current name is done, but input name continues -; so they do not match - jmp .next1 -.test1: -; if we have reached this point: input name is done, but current name continues -; "filename.ext;version" in ISO-9660 represents file "filename.ext" -; "filename." and "filename.;version" are also possible for "filename" - cmp byte [es:di], '.' - jnz @f - inc di - dec cx - jz .ret -@@: - cmp byte [es:di], ';' - jnz .next1 - jmp .ret -.next1: - stc -.ret: - popa - ret - -toupper: -; in: al=symbol -; out: al=symbol in uppercase - cmp al, 'a' - jb .ret - cmp al, 'z' - ja .ret - sub al, 'a'-'A' -.ret: - ret - -scan_for_filename_in_sector: -; in: ds:si->filename, es:bx->folder data, dx=limit -; out: CF=0 if found - push bx -.loope: - push bx -.loop: - cmp bx, dx - jae .notfound - cmp byte [es:bx], 0 - jz .loopd - test byte [es:bx+25], 4 ; ignore files with Associated bit - jnz .next - call test_filename2 - jc .next - push ds es di - push es - pop ds - push cs - pop es - mov di, [es:cur_desc_end] - movzx eax, byte [bx+1] - add eax, [bx+2] - stosd ; first logical block - mov eax, [bx+10] - stosd ; length - mov al, [bx+25] - stosb ; flags - mov ax, [bx+26] - stosw ; File Unit size, Interleave Gap size - mov [es:cur_desc_end], di - cmp di, 3000h - pop di es ds - jae .done - test byte [es:bx+25], 80h - jz .done -.next: - add bl, [es:bx] - adc bh, 0 - jmp .loop -.loopd: - mov ax, bx - pop bx -@@: - add bx, [cs:lb_size] - jz .done2 - cmp bx, ax - jb @b - jmp .loope -.notfound: - stc -.done: - pop bx -.done2: - pop bx - ret - -lb_to_sector: - xor edx, edx - div dword [lb_per_sec] - ret - -load_phys_sector_for_lb_force: -; in: eax = logical block, ds=0 -; in: si=0 - accept 0 logical blocks, otherwise force read at least 1 -; out: 0000:1000 = physical sector data; si -> logical block -; out: eax = next physical sector -; out: CF=1 if read error -; destroys cx -; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector - call lb_to_sector - or si, dx - jnz @f - mov si, 1800h - jmp .done -@@: - mov si, 1000h - imul dx, [lb_size] - add si, dx - mov cx, 1 - push es bx - push ds - pop es - mov bx, 1000h - call read_sectors - pop bx es - inc eax -.done: - ret - -normalize: -; in: es:bx = far pointer -; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10) - push ax bx - mov ax, es - shr bx, 4 - add ax, bx - mov es, ax - pop bx ax - and bx, 0x0F - ret - -read_many_bytes: - and [first_byte], 0 -read_many_bytes.with_first: -; read esi bytes from logical block dx:ax to buffer es:bx -; out: CF=1 <=> disk error - push di -; load first physical sector - push bx si - mov si, [first_byte] - call load_phys_sector_for_lb_force - jnc @f - pop si bx -.ret: - pop di - ret -@@: - add si, [first_byte] - mov ecx, 1800h - sub cx, si - mov ebx, esi - pop bx - sub ebx, ecx - jnc @f - add cx, bx - xor ebx, ebx -@@: - pop di - sub [cur_limit], ecx - rep movsb - mov esi, ebx - mov bx, di - call normalize -; load other physical sectors -; read esi bytes from physical sector eax to buffer es:bx - test esi, esi - jz .ret - push esi - add esi, 0x7FF - and si, not 0x7FF - cmp esi, [cur_limit] - jbe .okplace -.noplace: - sub esi, 800h -.okplace: - shr esi, 11 ; si = number of sectors - mov cx, si - jz @f - call read_sectors -@@: - pop esi - jc .ret - movzx ecx, cx - add eax, ecx - shl ecx, 11 - sub [cur_limit], ecx - sub esi, ecx - jc .big - jz .nopost - push bx es - push ds - pop es - mov bx, 1000h - mov cx, 1 - call read_sectors - pop es di - jc .ret2 - mov cx, si - mov si, 1000h - sub word [cur_limit], cx - sbb word [cur_limit+2], 0 - rep movsb - mov bx, di - call normalize -.nopost: - clc -.ret2: - pop di - ret -.big: - mov ax, es - sub ax, 80h - mov es, ax - add bx, 800h - add bx, si - call normalize - sub [cur_limit], esi - jmp .nopost - -; Callback function for secondary loader -callback: -; in: ax = function number; only function 1 is defined for now - dec ax - jz callback_readfile - dec ax - jz callback_continueread - stc ; unsupported function - retf - -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file - clc ; function is supported - retf - -callback_continueread: -; function 2: continue to read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - les bx, [di] - call normalize - movzx esi, word [di+4] ; si = limit in 4K blocks - shl esi, 12 ; bp:si = limit in bytes - push cs - pop ds - mov [cur_limit], esi - mov di, [cur_chunk] - call loadloop.loadnew - clc ; function is supported - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kord/loader',0 -aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 - -align 2 -cachelist: -.head dw cachelist -.tail dw cachelist -free_cache_item dw 0 -last_cache_item dw 0x8400 - -use_path_table db 0 -bootdrive db ? -align 2 -lb_size dw ? ; Logical Block size in bytes - dw 0 ; to allow access dword [lb_size] -lb_per_sec dw ? ; Logical Blocks per physical sector - dw 0 ; to allow access dword [lb_per_sec] -free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes) -size_rest dw ? ; free space in cache (in blocks) -cache_size dw ? -cache_start dw ? -pathtable_size dw ? -pathtable_start dw ? -root_location dd ? -cur_desc_end dw ? -cur_nocache_len dd ? -cur_limit dd ? -cur_unit_limit dd ? -overflow dw ? -cur_chunk dw ? -first_byte dw ? -cur_start dd ? - -;times 83FEh-$ db 0 - db 43h -; just to make file 2048 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - - dw 0xAA55 ; this is not required for CD, but to be consistent... diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.txt b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.txt deleted file mode 100644 index 7fedad1772..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.txt +++ /dev/null @@ -1,418 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.? - -Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660. -(ISO-9660 и её расширения - стандарт для CD; DVD может использовать -либо ISO-9660, либо UDF.) - -===================================================================== - -Требования для работы: -1) Сам бутсектор и все используемые файлы должны быть читабельны. -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 452K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 14.09.2008): - стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf - стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Схема используемой памяти: - 1000-1800 временный буфер для чтения одиночных секторов - ...-7C00 стек - 7C00-8400 код бутсектора - 8400-8A00 информация о кэше для папок: массив входов следующего - формата: - dw следующий элемент в L2-списке закэшированных папок, - упорядоченном по времени использования - (голова списка - самый старый); - dw предыдущий элемент в том же списке; - dd первый сектор папки; - dw размер папки в байтах; - dw сегмент кэша - 60000-... содержимое Path Table, если она используется - + кэш для папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip - равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает - дальний прыжок на самого себя с целью получить cs=0 (в некоторых - местах используется адресация переменных загрузчика через cs, поскольку - и ds, и es могут быть заняты под другие сегменты). -2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом) - и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления - и разрешённые прерывания. Сохраняет идентификатор загрузочного диска - в специальную переменную. -3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять - LBA-функции. -4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту - ISO9660 со смещения 10h начинается цепочка описателей тома, - завершающаяся специальным описателем (Volume Descriptor Set - Terminator). Код по очереди считывает все сектора, пока не наткнётся - либо на искомый описатель, либо на терминатор. Во втором случае - выдаётся соответствующее сообщение, и загрузка прекращается. -Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD - располагается в последней сессии. И спецификация ElTorito загрузочного - CD оперирует также с последней сессией. Однако на практике оказывается, - что: во-первых, реальные BIOSы не понимают мультисессионных CD и - всегда используют первую сессию; во-вторых, BIOSовский int 13h просто - не позволяет получить информацию о последней сессии. В связи с этим - загрузчик также использует первую сессию. (В-третьих, в одной из BIOS - обнаружилась заготовка, которая в случае запроса сектора 10h, в котором - во всех нормальных случаях и располагается PVD, перенаправляет его - на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с - последней сессии, то благодаря заготовке загрузчик без всяких - модификаций также читал бы последнюю сессию.) -5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во - внутренние переменные: размер логического блока (согласно спецификации, - должен быть степенью двойки от 512 до размера логического сектора, - равного 2048 для CD и DVD); положение на диске корневой папки; - вычисляет число блоков в секторе (из предыдущего примечания следует, - что оно всегда целое и само является степенью двойки). -6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет - размер пространства, которое может использовать загрузчик (от - адреса 6000:0000 до конца доступной памяти). -7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит - базовую информацию обо всех папках на диске. Если таблица слишком - велика (больше 62K или больше половины доступной памяти), то она - игнорируется. Если таблица путей недоступна, то запрос типа - dir1/dir2/dir3/file приведёт к последовательному разбору корневой - папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать - саму таблицу путей (где записано положение папки dir1/dir2/dir3) - и папку dir3. Если таблица загружена, то соответственно уменьшается - объём оставшейся доступной памяти и увеличивается указатель на - свободную область. -8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7 - доступная память отводится под этот кэш). -9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке - печатает соответствующее сообщение и прекращает загрузку с CD. -10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует - тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is' - идентифицирует файловую систему ISO-9660; ds:si указывает на - callback-функцию, которую может вызывать вторичный загрузчик. -11. Передаёт управление вторичному загрузчику, совершая дальний прыжок - на адрес, куда kord/loader был загружен. - -Функция обратного вызова для вторичного загрузчика (callback): - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -Перенаправляет запрос соответствующей локальной процедуре (load_file при - первом запросе на загрузку файла, loadloop.loadnew при последующих - запросах на продолжение загрузки файла). - -Вспомогательные процедуры. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения секторов (read_sectors): -на входе должно быть установлено: - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор - cx = число секторов -на выходе: - es:bx указывает на конец буфера, в который были прочитаны данные - если произошла ошибка чтения, флаг CF установлен -1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации - число читаемых секторов не превосходило 7Fh (требование спецификации - EDD BIOS). -2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек, - устанавливает CF=1 и выходит из процедуры. - Очищает стек от пакета, сформированного на предыдущем шаге. -5. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 2. - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -Процедура загрузки файла (load_file): -на входе: - ds:di = указатель на информационную структуру, описанную в спецификации - на загрузчик, а также в комментариях к коду -на выходе: - bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть, - 2=файл не найден, 3=ошибка чтения - dx:ax = размер файла, 0xFFFFFFFF, если файл не найден -1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице, - иначе переходит сразу к шагу 4, установив eax = начальный блок - корневой папки. -2. Устанавливает es:di на начало таблицы путей. Ограничение на размер - гарантирует, что вся таблица помещается в сегменте 6000h. - Инициализирует dx (в котором будет хранится номер текущего входа в - таблице, считая с 1), cx (размер оставшегося участка таблицы), - bx (номер входа, соответствующего родительской папке для текущего - рассматриваемого участка пути). -3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы - таблицы путей упорядочены (подробно о порядке написано в спецификации), - так что если родительский элемент для очередного входа больше нужного, - то нужного входа в таблице нет совсем, и в этом случае происходит - выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент, - соответствующий очередной папке в запрошенном пути, то на рассмотрение - выносится следующая компонента пути. Если эта компонента последняя, - то осталось найти файл в папке, и код переходит к пункту 4, - установив eax = начальный блок этой папки. Если же нет, то эта - компонента должна задавать имя папки, и код возвращается к пункту 3, - скорректировав указатель на имя ds:si и номер родительского входа bx. -4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax - и указатель на имя файла относительно этой папки в ds:si. Если - папку искали по таблице путей, то имя файла уже не содержит подпапок; - если же нет, то подпапки вполне возможны. -5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый - из которых задаётся отдельным входом в папке. Информация обо всех - таких кусках при просмотре папки запоминается в области, начинающейся - с адреса 0000:2000. Переменная cur_desc_end содержит указатель на - конец этой области, он же указатель, куда будет помещена информация - при обнаружении следующего входа. (Папки, согласно спецификации, - должны задаваться одним куском.) -6. Код сначала ищет запрошенную папку в кэше папок. -7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка, - отсортированного по давности последнего обращения и код переходит к - п.15. (Следующим действием станет добавление папки в конец списка.) -8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать - с диска. Сначала загружается первый сектор (физический сектор, - содержащий первый логический блок). При ошибке ввода/вывода - происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF. - Первый элемент папки содержит информацию о самой этой папке, конкретно - загрузчик интересуется её размером. -9. Если размер папки слишком большой (больше или равен 64K либо больше половины - общего размера кэша), то кэшироваться она не будет. В этом случае код - считывает папку посекторно во временный буфер (0000:1000) и посекторно - сканирует на наличие запрошенного имени, пока не найдёт такого имени - или пока не кончатся данные. (Цикл начинается со сканирования, - поскольку первая часть данных уже прочитана.) В конце код переходит - к п.17. -10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно - обеспечить достаточное количество свободного места. Для этого может - понадобиться выкинуть какое-то количество старых данных (цикл - parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря, - свободное пространство окажется разорванным на несколько фрагментов. - Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает - все следующие за ней данные назад по памяти и соответственно - корректирует информацию о местонахождении данных в информации о кэше. - При этом новое пространство всегда добавляется в конец доступной - памяти. Цикл выкидывания продолжается, пока не освободится место, - достаточное для хранения папки. Из-за ограничений на размер кэшируемых - папок в конце концов место найдётся. -11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы - организуются в единый список свободных элементов; если он непуст, - то очередной элемент берётся из этого списка; если же пуст, то - берётся совсем новый элемент из области памяти, предназначенной для - элементов кэша. -12. В новом элементе заполняются поля начального блока, сегмента с данными, - размера в байтах. -13. Уже прочитанные данные первого физического сектора пересылаются на - законное место в кэше. -14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся - данные с диска. При ошибке чтения, как и раньше, происходит выход из - процедуры с bx=3, ax=dx=0xFFFF. -15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов - кэша. -16. Загрузчик ищет запрошенное имя в загруженных данных папки. - (Из-за ограничений на размер кэшируемой папки все данные располагаются - в одном сегменте.) -17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено - никаких кусков файла, то cur_desc_end такой же, каким был вначале. - В этом случае процедура рапортует о ненайденном файле и выходит. -18. (filefound) Пропускает текущую компоненту имени. Если она была не последней - (то есть подпапкой, в которой нужно производить дальнейший поиск), - то код проверяет, что найденный вход - действительно подпапка, - устанавливает новый стартовый блок и возвращается к п.4. - Если же последней, то код проверяет, что найденный вход - регулярный - файл и начинает загрузку файла. -19. Нормализует указатель, по которому требуется прочитать файл. Под - нормализацией понимается преобразование типа - 1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса, - но гарантирует отсутствие переполнений: в приведённом примере попытка - переслать 400h байт по rep movsb приведёт к тому, что последние 8 - байт запишутся не в нужное место, а на 64K раньше. Далее нормализация - будет производиться после каждой пересылки. В cur_limit помещает - предельный размер для чтения в байтах. -20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты - (пункты 21-27). -21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое - нужно пропустить с начала фрагмента. -22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего - шага, либо напрямую из callback-процедуры при запросе на продолжение - чтения. Для этого и нужна вышеупомянутая переменная [cur_start] - - при продолжении чтения, прервавшегося из-за конца буфера посередине - фрагмента, там будет записано соответствующее значение. -23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента - и максимальной длины остатка. Если второе строго меньше, то - запоминает, что файл слишком большой и прочитан только частично. - Определяет новое значение числа прочитанных байт во фрагменте - для возможных будущих вызовов [cur_start]. -24. Переводит пропускаемое число байт в число логических блоков и байт - в первом блоке, последнее число записывает в переменную [first_byte], - откуда её позднее достанет read_many_bytes.with_first. -25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код - определяет начальный блок фрагмента и вызывает вспомогательную функцию - чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения) - и выходит из цикла к п.28. -26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала - код пропускает нужное количество непрерывных частей, а потом - в цикле загружает непрерывные части с помощью той же функции, - в промежутках между частями увеличивая номер начального блока. - Пока не кончится фрагмент или пока не наберётся запрошенное число байт. - При ошибке чтения делает то же самое, что и в предыдущем случае. -27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер - ещё не достигнут, переходит к следующему фрагменту и п.20. В противном - случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли - переполнение в п.23. -28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех - фрагментов. - -Процедура проверки, является ли текущая компонента имени файла последней - (is_last_component): -на входе: ds:si = указатель на имя -на выходе: флаг CF установлен, если есть последующие компоненты -В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый, - то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF - и выходит. - -Процедуры проверки на совпадение текущей компоненты имени файла с именем -текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки): -на входе: ds:si = указатель на имя, es:di = указатель на элемент - таблицы путей для test_filename1, папки для test_filename2 -на выходе: CF установлен, если имена не совпадают -В цикле проверяет совпадение приведённых к верхнему регистру очередных символов - имён файла и элемента. Условия выхода из цикла: закончилось имя файла - в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение - возможно только в ситуации типа имени "filename.ext" и элемента - "filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми - именами в папке отсортированы по убыванию версий); - несовпадение символов - означает, что имена не совпадают; - закончилось имя элемента - нужно проверить, закончилось ли при этом имя - файла, и в зависимости от этого принимать решение о совпадении. - -Процедура приведения символа в верхний регистр (toupper): -на входе: ASCII-символ -на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к - нему неприменимо) -Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A', - остальные символы не трогает. - -Процедура поиска файла в данных папки (scan_for_filename_in_sector): -на входе: - ds:si = указатель на имя файла - es:bx = указатель на начало данных папки - es:dx = указатель на конец данных папки -на выходе: - CF сброшен, если найден финальный фрагмент файла - (и дальше сканировать папку не нужно) - в область для информации о фрагментах файла записывается найденное -В цикле просматривает все входы папки, пропуская те, у которых установлен - бит Associated (это специальные входы, дополняющие основные). Если - имя очередного входа совпадает с именем файла, то запоминает новый - фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent), - то код выходит с CF=0. Если достигнут конец данных, то код выходит - с CF=1. Если очередной вход нулевой (первый байт настоящего входа - содержит длину и не может быть нулём), то процедура переходит к - рассмотрению следующего логического блока. При этом потенциально - возможно переполнение при добавлении размера блока; поскольку такой - сценарий означает, что процедура вызвана для кэшированной папки - с размером почти 64K и началом данных bx=0 (это свойство вызывающего - кода), а размер блока - степень двойки, то после переполнения всегда - bx=0, так что это можно обнаружить по взведённому ZF после сложения; - в этом случае также происходит выход (а после переполнения CF=1). - -Процедура перевода логического блока в номер сектора: -на входе: eax = логический блок -на выходе: eax = физический сектор, dx = номер логического блока в секторе -Осуществляет обычное деление 32-битного числа на 32-битное (число логических - блоков в секторе, хранящееся во внутренней переменной). - -Процедура загрузки физического сектора, содержащего указанный логический блок - (load_phys_sector_for_lb_force): -на входе: eax = логический блок; - si - индикатор, задающий, следует ли читать данные в случае, - если логический блок начинается с начала физического: - si = 0 - не нужно, si ненулевой - нужно -на выходе: - физический сектор загружен по адресу 0000:1000 - si указывает на данные логического блока - CF установлен при ошибке чтения -Преобразует предыдущей процедурой номер логического блока в номер физического - сектора и номер логического блока внутри сектора; если последняя - величина нулевая и никаких действий в этом случае не запрошено (si=0), - то ничего и не делает; иначе устанавливает si в соответствии с ней - и читает сектор. - -Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков - (read_many_bytes и read_many_bytes.with_first): -на входе: - eax = логический блок - esi = число байт для чтения - es:bx = указатель на начало буфера, куда будут прочитаны данные - cur_limit = размер буфера (не меньше esi) -на выходе: - es:bx указывает на конец буфера, в который были прочитаны данные - если произошла ошибка чтения, флаг CF установлен - cur_limit соответствующим образом уменьшен -Отличие двух процедур: вторая дополнительно принимает во внимание переменную - [first_byte], начиная чтение первого блока со смещения [first_byte]; - соответственно, первая читает блок с начала, обнуляя [first_byte] - при входе. -1. Отдельно считывает первый физический сектор во временную область 0000:1000, - если первый логический блок начинается не с начала сектора. При - ошибке чтения выходит из процедуры. -2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1, - в буфер. Нормализует указатель на буфер. -3. Если все необходимые данные уже прочитаны, выходит из процедуры. -4. Дальнейшие данные находятся в нескольких физических секторах, при этом, - возможно, последний сектор считывать нужно не целиком. -5. Если в буфере есть место для считывания всех секторов, то сразу читаются - все сектора, после чего указатель на буфер нужным образом уменьшается. -6. Если же нет, то считываются все сектора, кроме последнего, после чего - последний сектор считывается отдельно во временную область, и уже - оттуда нужная часть данных копируется в буфер. diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/build.bat b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/build.bat deleted file mode 100644 index 93b242702f..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.asm deleted file mode 100644 index 033257c541..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.asm +++ /dev/null @@ -1,392 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -use_lba = 0 - org 0x7C00 - jmp start - nop -; FAT parameters, BPB -; note: they can be changed at install, replaced with real values -; these settings are for most typical 1.44M floppies - db 'KOLIBRI ' ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db 1 -BPB_RsvdSecCnt dw 1 -BPB_NumFATs db 2 -BPB_RootEntCnt dw 0xE0 - dw 2880 ; BPB_TotSec16 - db 0xF0 ; BPB_Media -BPB_FATSz16 dw 9 -BPB_SecPerTrk dw 18 -BPB_NumHeads dw 2 -BPB_HiddSec dd 0 - dd 0 ; BPB_TotSec32 -BS_DrvNum db 0 - db 0 ; BS_Reserved1 - db ')' ; BS_BootSig - dd 12344321h ; BS_VolID -filename: - db 'KORD.OS ' ; BS_VolLab - db 'FAT12 ' ; BS_FilSysType -; Used memory map: -; 8000:0000 - current directory -; 9000:0000 - root directory data [cached] -start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - mov [bp+BS_DrvNum-0x7C00], dl -if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cx, 1 - jz err_ -else - mov ah, 8 - int 13h - jc @f ; on error, assume that BPB geometry is valid - mov al, dh - mov ah, 0 - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx -@@: -end if -; get FAT parameters - xor bx, bx - mov al, [bp+BPB_NumFATs-0x7C00] - mov ah, 0 - mul [bp+BPB_FATSz16-0x7C00] - add ax, [bp+BPB_RsvdSecCnt-0x7C00] - adc dx, bx - push dx - push ax ; root directory start = dword [bp-4] - mov cx, [bp+BPB_RootEntCnt-0x7C00] - add cx, 0xF - rcr cx, 1 - shr cx, 3 ; cx = size of root directory in sectors - add ax, cx - adc dx, bx - push dx - push ax ; data start = dword [bp-8] -; load start of root directory (no more than 0x2000 bytes = 0x10 sectors) - cmp cx, 0x10 - jb @f - mov cx, 0x10 -@@: - mov ax, [bp-4] - mov dx, [bp-2] - push 0x9000 - pop es - call read_sectors - add word [bp-4], cx ; dword [bp-4] = start of non-cached root data - adc word [bp-2], bx -; load kordldr.f12 - mov si, main_loader - call lookup_in_root_dir - jc noloader - test byte [es:di+11], 10h ; directory? - jz kordldr_ok -noloader: - mov si, aLoaderNotFound -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -kordldr_ok: - mov ax, [es:di+26] ; get file cluster - mov bx, 0x7E00 - xor cx, cx - mov es, cx - sub ax, 2 - jc noloader - push bx ; save return address: bx = 7E00 - mov cl, [bp+BPB_SecsPerClus-0x7C00] - mul cx -; fall through - 'ret' in read_sectors will return to 7E00 - -read_sectors2: -; same as read_sectors, but dx:ax is relative to start of data - add ax, [bp-8] - adc dx, [bp-6] -read_sectors: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; dx:ax = first sector -; cx = number of sectors - pusha - add ax, word [bp+BPB_HiddSec-0x7C00] - adc dx, word [bp+BPB_HiddSec+2-0x7C00] -if use_lba - push ds -do_read_sectors: - push ax - push cx - push dx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push dx - push ax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp+BS_DrvNum-0x7C00] - mov ah, 42h - int 13h - mov si, aReadError - jc err_ -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - mov si, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop dx - pop cx - pop ax - add ax, si - adc dx, 0 - sub cx, si - jnz do_read_sectors - pop ds - popa - ret -else -do_read_sectors: - pusha - pop di - push bx - -; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx - mov si, ax - xchg ax, dx - xor dx, dx - div [bp+BPB_SecPerTrk-0x7C00] - push ax - mov ax, si - div [bp+BPB_SecPerTrk-0x7C00] - mov bx, dx ; bx=sector-1 - pop dx - -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] - -; number of sectors: read no more than to end of track - push bx - sub bx, [bp+BPB_SecPerTrk-0x7C00] - neg bx - cmp cx, bx - jbe @f - mov cx, bx -@@: - pop bx - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - mov di, cx - mov dh, dl - mov dl, [bp+BS_DrvNum-0x7C00] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err_ -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push di - popa - add ax, di - adc dx, 0 - sub cx, di - jnz do_read_sectors - popa - ret -end if - -scan_for_filename: -; in: ds:si -> 11-bytes FAT name -; in: es:0 -> part of directory data -; in: cx = number of entries -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - xor di, di - push cx -sloop: - cmp byte [es:di], 0 - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone -scont: - add di, 0x20 - loop sloop - inc cx ; clear ZF flag -snotfound: - stc -sdone: - pop cx -lrdret: - ret - -lookup_in_root_dir: -; ss:bp = 0:7C00 -; in: ds:si -> 11-bytes FAT name -; out: if found: CF=0, es:di -> directory entry -; out: if not found: CF=1 - mov cx, [bp+BPB_RootEntCnt-0x7C00] - push cx -; first, look in root directory cache - push 0x9000 - pop es - test ch, ch - jz @f - mov cx, 0x100 -@@: - mov ax, [bp-4] - mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory -lrdloop: - call scan_for_filename - pop bx - jz lrdret - sub bx, cx - mov cx, bx - stc - jz lrdret -; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries - push cx - cmp ch, 0x8 - jb @f - mov cx, 0x800 -@@: - push 0x8000 - pop es - push cx - push es - xor bx, bx - add cx, 0xF - shr cx, 4 - call read_sectors - pop es - add ax, cx - adc dx, bx - pop cx - jmp lrdloop - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz lrdret - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aReadError db 'Read error',0 -if use_lba -aNoLBA db 'The drive does not support LBA!',0 -end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F1X' - -if use_lba - db 0 ; make bootsector 512 bytes in length -end if - -; bootsector signature - dw 0xAA55 - -; display offsets of all procedures used by kordldr.f12.asm -macro show [procedure] -{ - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 -} - -show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.txt b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.txt deleted file mode 100644 index c0449aa693..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.txt +++ /dev/null @@ -1,360 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Встречаются вирус и FAT. - - Привет, ты кто? - - Я? Вирус. - - A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... - -Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт. - -===================================================================== - -Есть две версии в зависимости от того, поддерживает ли носитель LBA, -выбор осуществляется установкой константы use_lba в первой строке исходника. -Требования для работы: -1) Сам бутсектор, первая копия FAT и все используемые файлы -должны быть читабельны. -2) Минимальный процессор - 80186. -3) В системе должно быть как минимум 592K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер -занимает 12 бит в таблице FAT, так что общий размер не превосходит -0x17EE = 6126 байт. Вся таблица помещается в памяти. -Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый -кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит -0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в -этом случае несколько нецелесообразно считывать всю таблицу, поскольку -на практике нужна только небольшая её часть. Поэтому место в памяти -резервируется, но данные считываются только в момент, когда к ним -действительно идёт обращение. - -Схема используемой памяти: - ...-7C00 стек - 7C00-7E00 код бутсектора - 7E00-8200 вспомогательный файл загрузчика (kordldr.f1x) - 8200-8300 список загруженных секторов таблицы FAT16 - (1 = соответствующий сектор загружен) - 60000-80000 загруженная таблица FAT12 / место для таблицы FAT16 - 80000-90000 текущий кластер текущей рассматриваемой папки - 90000-92000 кэш для корневой папки - 92000-... кэш для некорневых папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 7 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед - кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало - бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - - это освобождает ds и экономит на размере кода). -2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h - прерывания 13h. Если нет, переходит на код обработки ошибок с - сообщением об отсутствии LBA. -CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и - записывает полученные данные поверх BPB. Если вызов завершился ошибкой, - предполагает уже существующие данные корректными. -3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки - и начальный сектор данных. Кладёт их в стек; впоследствии они - всегда будут лежать в стеке и адресоваться через bp. -4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых - секторов - минимум из размера корневой папки, указанного в BPB, и 16 - (размер кэша для корневой папки - 2000h байт = 16 секторов). -5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если - он оказывается папкой, или если файл имеет нулевую длину - - переходит на код обработки ошибок с сообщением о - ненайденном загрузчике. - Замечание: на этом этапе загрузки искать можно только в корневой - папке и только имена, заданные в формате файловой системе FAT - (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны - быть заглавными, при необходимости имя и расширение дополняются - пробелами, разделяющей точки нет, завершающего нуля нет). -6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт - ему управление. При этом в регистрах dx:ax оказывается абсолютный - номер первого сектора kordldr.f1x, а в cx - число считанных секторов - (равное размеру кластера). - -Вспомогательные процедуры бутсектора. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения секторов (read_sectors и read_sectors2): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - dx:ax = стартовый сектор (относительно начала логического диска - для read_sectors, относительно начала данных для read_sectors2) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные -0. Если вызывается read_sectors2, она переводит указанный ей номер сектора - в номер относительно начала логического диска, прибавляя номер сектора - начала данных, хранящийся в стеке как [bp-8]. -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя значение соответствующего поля из BPB. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура поиска элемента по имени в уже прочитанных данных папки - (scan_for_filename): -на входе должно быть установлено: - ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя, - 3 на расширение, все буквы заглавные, если имя/расширение - короче, оно дополняется до максимума пробелами) - es = сегмент данных папки - cx = число элементов в прочитанных данных -на выходе: ZF определяет, нужно ли продолжать разбор данных папки - (ZF=1, если либо найден запрошенный элемент, либо достигнут - конец папки); CF определяет, удалось ли найти элемент с искомым именем - (CF=1, если не удалось); если удалось, то es:di указывает на него. -scan_for_filename считает, что данные папки размещаются начиная с es:0. -Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки -проверяет имена. - -Процедура поиска элемента в корневой папке (lookup_in_root_dir): -на входе должно быть установлено: - ss:bp = 0:7C00 - ds:si = указатель на имя файла в формате FAT (см. выше) -на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то - CF сброшен и es:di указывает на элемент папки -Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле - сканирует элементы; если по результатам сканирования обнаруживает, - что нужно читать папку дальше, то считывает не более 0x10000 = 64K - байт (ограничение введено по двум причинам: во-первых, чтобы заведомо - не вылезти за пределы используемой памяти, во-вторых, сканирование - предполагает, что все обрабатываемые элементы располагаются в одном - сегменте) и продолжает цикл. -Сканирование прекращается в трёх случаях: обнаружен искомый элемент; - кончились элементы в папке (судя по числу элементов, указанному в BPB); - очередной элемент папки сигнализирует о конце (первый байт нулевой). - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -===================================================================== - -Работа вспомогательного загрузчика kordldr.f1x: -1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. - В зависимости от этого устанавливает смещения используемых процедур - бутсектора. Критерий проверки: scan_for_filename должна начинаться - с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может - с равным успехом ассемблироваться и как 33 FF, но fasm генерирует - именно такую форму). -2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска - адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с - ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента - место должно быть, отсюда ограничение в 592 Kb (94000h байт). - Замечание: этот размер не может превосходить 0A0000h байт и - на практике оказывается немного (на 1-2 килобайта) меньшим из-за - наличия дополнительной области данных BIOS "вверху" базовой памяти. -3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной - спецификации от Microsoft (версия 1.03 спецификации датирована, - к слову, 06 декабря 2000 года), разрядность FAT определяется - исключительно числом кластеров: максимальное число кластеров на - FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12 - может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2, - а число 0xFF7 не может быть корректным номером кластера. - Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается - по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает - явно неверно, считая, что 0xFF6 (или меньше) кластеров означает - FAT12-том, в результате получается, что последний кластер - (в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe - [встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик - [бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы - лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили - в соответствии со спецификацией. Linux при определении FAT12/FAT16 - честно следует спецификации. - Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT - Microsoft если и будет исправлять ошибки, то согласно собственному - описанию. -4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000. - Если размер, указанный в BPB, превосходит 12 секторов, - это означает, что заявленный размер слишком большой (это не считается - ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12 - заведомо влезает в такой объём данных). -Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор - FAT не загружен (они будут подгружаться позднее, когда понадобятся - и только те, которые понадобятся). -5. Если кластер равен сектору, то бутсектор загрузил только часть файла - kordldr.f1x, и загрузчик подгружает вторую свою часть, используя - значения регистров на входе в kordldr.f1x. -6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не - найден, или оказался папкой, или оказался слишком большим, то переходит - на код обработки ошибок из бутсектора с сообщением - "Fatal error: cannot load the secondary loader". - Замечание: на этом этапе имя файла уже можно указывать вместе с путём - и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов - по-прежнему нет. -7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. - Это нужно, чтобы последующие обращения к коду бутсектора в случае - ошибок чтения не выводил соответствующее сообщение с последующей - перезагрузкой, а рапортовал об ошибке чтения, которую мог бы - как-нибудь обработать вторичный загрузчик. -8. Если загрузочный диск имеет идентификатор меньше 0x80, - то устанавливает al='f' ("floppy"), ah=идентификатор диска, - иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). - Устанавливает bx='12', если тип файловой системы - FAT12, и - bx='16' в случае FAT16. Устанавливает si=смещение функции обратного - вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес. -9. Передаёт управление по адресу 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным - кодом должна указывать на 0:7C00, а -8 берётся от того, что - инициализирующий код бутсектора уже поместил в стек 2 двойных слова, - и они должны сохраняться в неизменности. -2. Разбирает переданные параметры, выясняет, какое действие запрошено, - и вызывает нужную вспомогательную процедуру. -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры kordldr.f1x. -Процедура получения следующего кластера в FAT (get_next_cluster): -1. Вспоминает разрядность FAT, вычисленную ранее. -Для FAT12: -2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана - вся таблица FAT. -3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте - слова, задающего следующий кластер. Загружает слово по этому адресу. -4. Если кластер имеет нечётный номер, то соответствующий ему элемент - располагается в старших 12 битах слова, и слово нужно сдвинуть вправо - на 4 бита; в противном случае - в младших 12 битах, и делать ничего не - надо. -5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7: - номера нормальных кластеров меньше, и флаг CF устанавливается; - специальные значения EOF и BadClus сбрасывают флаг CF. -Для FAT16: -2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных - в таблице FAT. -3. Если сектор ещё не загружен, то загружает его. -4. Вычисляет смещение данных для конкретного кластера относительно начала - сектора. -5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3. -6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг - CF устанавливается; специальные значения EOF и BadClus сбрасывают CF. - -Процедура загрузки файла (load_file): -1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. -2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты - разделяются символом '/') в FAT-формат 8+3. Если это невозможно - (больше 8 символов в имени, больше 3 символов в расширении или - больше одной точки), возвращается с ошибкой. -3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой - папки используется процедура из бутсектора. Для остальных папок: - a) Проверяет, есть ли такая папка в кэше некорневых папок. - (Идентификация папок осуществляется по номеру начального кластера.) - Если такой папки ещё нет, добавляет её в кэш; если тот переполняется, - выкидывает папку, к которой дольше всего не было обращений. (Для - каждого элемента кэша хранится метка от 0 до (размер кэша)-1, - определяющая его номер при сортировке по давности последнего обращения. - При обращении к какому-то элементу его метка становится нулевой, - а те метки, которые меньше старого значения, увеличиваются на единицу.) - б) Просматривает в поисках запрошенного имени все элементы из кэша, - используя процедуру из бутсектора. Если обнаруживает искомый элемент, - переходит к шагу 4. Если обнаруживает конец папки, возвращается из - процедуры с ошибкой. - в) В цикле считывает папку посекторно. При этом пропускает начальные - секторы, которые уже находятся в кэше и уже были просмотрены. Каждый - прочитанный сектор копирует в кэш, если там ещё остаётся место, - и просматривает в нём все элементы. Работает, пока не случится одно из - трёх событий: найден искомый элемент; кончились кластеры (судя по - цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце - (первый байт нулевой). В двух последних случаях возвращается с ошибкой. -4. Проверяет тип найденного элемента (файл/папка): последний элемент в - запрошенном имени должен быть файлом, все промежуточные - папками. - Если текущий компонент имени - промежуточный, продвигает текущую - рассматриваемую папку и возвращается к пункту 2. -5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный - при вызове буфер последовательными вызовами функции бутсектора; - при этом если несколько кластеров файла расположены на диске - последовательно, то их чтение объединяется в одну операцию. - Следит за тем, чтобы не превысить указанный при вызове процедуры - лимит числа секторов для чтения. - -Процедура продолжения загрузки файла (continue_load_file): встроена - внутрь шага 5 load_file; загружает в регистры нужные значения (ранее - сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/build.bat b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/build.bat deleted file mode 100644 index 17c30cac18..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@fasm -m 65535 kordldr.f1x.asm kordldr.f1x -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm deleted file mode 100644 index 903bb18adc..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm +++ /dev/null @@ -1,668 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - org 0x7E00 -; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here -; ss:bp = 0:7C00 -virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? -BPB_TotSec16 dw ? - db ? ; BPB_Media -BPB_FATSz16 dw ? -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? -BPB_TotSec32 dd ? -BS_DrvNum db ? -fat_type db ? ; this is BS_Reserved1, - ; we use it to save FS type: 0=FAT12, 1=FAT16 - db ? ; BS_BootSig -num_sectors dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 3 ; BS_FilSysType, first 3 bytes -read_sectors dw ? -read_sectors2 dw ? -lookup_in_root_dir dw ? -scan_for_filename dw ? -err_ dw ? -noloader dw ? -cachelimit dw ? -filesize: ; will be used to save file size - rb 5 ; BS_FilSysType, last 5 bytes -; following variables are located in the place of starting code; -; starting code is no more used at this point -sect_per_clus dw ? -cur_cluster dw ? -next_cluster dw ? -flags dw ? -cur_delta dd ? -end virtual - -; procedures from boot sector -; LBA version -lba_read_sectors = 7CE2h -lba_read_sectors2 = 7CDCh -lba_lookup_in_root_dir = 7D4Fh -lba_scan_for_filename = 7D2Dh -lba_err = 7CB5h -lba_noloader = 7CB2h -; CHS version -chs_read_sectors = 7CDEh -chs_read_sectors2 = 7CD8h -chs_lookup_in_root_dir = 7D70h -chs_scan_for_filename = 7D4Eh -chs_err = 7CB1h -chs_noloader = 7CAEh - - push ax cx ; save our position on disk - push ss - pop es -; determine version of bootsector (LBA vs CHS) -; mov [read_sectors], chs_read_sectors -; mov [read_sectors2], chs_read_sectors2 -; mov [lookup_in_root_dir], chs_lookup_in_root_dir -; mov [scan_for_filename], chs_scan_for_filename -; mov [err], chs_err -; mov [noloader], chs_noloader - lea di, [read_sectors] - mov si, chs_proc_addresses - mov cx, 6*2 - cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di' - jz @f - add si, cx -; mov [read_sectors], lba_read_sectors -; mov [read_sectors2], lba_read_sectors2 -; mov [lookup_in_root_dir], lba_lookup_in_root_dir -; mov [scan_for_filename], lba_scan_for_filename -; mov [err], lba_err -; mov [noloader], lba_noloader -@@: - rep movsb - mov cl, [BPB_SecsPerClus] - mov [sect_per_clus], cx - xor bx, bx -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 94000h / 1024 - jae @f -nomem: - mov si, nomem_str - jmp [err_] -@@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 -; get type of file system - FAT12 or FAT16? -; calculate number of clusters - mov ax, [BPB_TotSec16] - xor dx, dx - test ax, ax - jnz @f - mov ax, word [BPB_TotSec32] - mov dx, word [BPB_TotSec32+2] -@@: - sub ax, [bp-8] ; dword [bp-8] = first data sector - sbb dx, [bp-6] - jb j_noloader - div [sect_per_clus] -; ax = number of clusters -; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes - mov [fat_type], ch - cmp ax, 0xFF5 - jb init_fat12 - inc [fat_type] -init_fat16: -; no sectors loaded - mov di, 0x8200 - xor ax, ax - mov cx, 0x100/2 - rep stosw - jmp init_fat_done -init_fat12: -; read FAT - push 0x6000 - pop es - mov ax, [BPB_RsvdSecCnt] - mov cx, [BPB_FATSz16] - cmp cx, 12 - jb @f - mov cx, 12 -@@: - xor dx, dx - call [read_sectors] -init_fat_done: -; if cluster = sector, we need to read second part of our file -; (bootsector loads only first cluster of kordldr.f1x) - pop cx ax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub ax, [bp-8] - inc ax - inc ax ; ax = first cluster of kordldr.f12 - call get_next_cluster - jc @f -j_noloader: - jmp [noloader] -@@: - dec ax - dec ax - push 0x800 - pop es - call [read_sectors2] -kordldr_full: -; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err_] - jz @f - mov si, aKernelNotFound - jmp bx -@@: -; for subsequent calls to callback function, hook error handler -; mov byte [bx], 0xE9 ; 'jmp' opcode -; mov ax, hooked_err - 3 -; sub ax, bx -; mov word [bx+1], ax -; push hooked_err / ret - mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8) - mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8) -; set registers for secondary loader - mov ah, [BS_DrvNum] - mov al, 'f' - test ah, ah - jns @f - sub ah, 80h - mov al, 'h' -@@: - mov bx, '12' - cmp [fat_type], 0 - jz @f - mov bh, '6' -@@: - mov si, callback ; ds:si = far pointer to callback procedure - jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000 - -nomem_str db 'No memory',0 - -chs_proc_addresses: - dw chs_read_sectors - dw chs_read_sectors2 - dw chs_lookup_in_root_dir - dw chs_scan_for_filename - dw chs_err - dw chs_noloader -lba_proc_addresses: - dw lba_read_sectors - dw lba_read_sectors2 - dw lba_lookup_in_root_dir - dw lba_scan_for_filename - dw lba_err - dw lba_noloader - -get_next_cluster: -; in: ax = cluster -; out: if there is next cluster: CF=1, ax = next cluster -; out: if there is no next cluster: CF=0 - push si - cmp [fat_type], 0 - jnz gnc16 -; for FAT12 - push ds - push 0x6000 - pop ds - mov si, ax - shr si, 1 - add si, ax - test al, 1 - lodsw - jz @f - shr ax, 4 -@@: - and ax, 0xFFF - cmp ax, 0xFF7 - pop ds si - ret -; for FAT16 -gnc16: -; each sector contains 200h bytes = 100h FAT entries -; so ah = # of sector, al = offset in sector - mov si, ax - mov ah, 0 - shr si, 8 -; calculate segment for this sector of FAT table -; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si) -; segment = 6000 + 20*si, offset = 0 - push es - push si - shl si, 5 - add si, 0x6000 - mov es, si - pop si - cmp byte [ss:0x8200+si], ah ; sector already loaded? - jnz @f -; load corresponding sector - pusha - push es - xor bx, bx - mov ax, [BPB_RsvdSecCnt] - xor dx, dx - add ax, si - adc dx, bx - mov cx, 1 ; read 1 sector - call [read_sectors] - pop es - popa -@@: - mov si, ax - add si, si -; mov ax, [es:si] - lods word [es:si] - pop es - cmp ax, 0xFFF7 - pop si - ret - -if $ > 0x8000 -error 'get_next_cluster must fit in first sector of kordldr.f1x!' -end if - -load_file: -; in: ss:bp = 0:7C00 -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - xor ax, ax ; start from root directory - mov dx, -1 - mov word [filesize], dx - mov word [filesize+2], dx ; initialize file size with invalid value - lea si, [di+6] -parse_dir_loop: -; convert name to FAT name - push di - push ax - push ss - pop es -; convert ASCIIZ filename to FAT name - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp nameloop -namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop -namedone: -; scan directory - pop ax ; ax = cluster of directory or 0 for root - push ds - push si - push es - pop ds - mov si, filename ; ds:si -> filename in FAT style - test ax, ax - jnz lookup_in_notroot_dir -; for root directory, use the subroutine from bootsector - call [lookup_in_root_dir] - jmp lookup_done -lookup_in_notroot_dir: -; for other directories, read a folder sector-by-sector and scan -; first, try to use the cache - push ds - push cs - pop ds - mov bx, [cachelimit] - add bx, bx - mov di, foldcache_mark -@@: - mov dx, [foldcache_clus+di-foldcache_mark+bx] - cmp dx, ax - jz cacheok - test dx, dx - jz cacheadd ; the cache has place for new entry - dec bx - dec bx - jns @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov dx, [cachelimit] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b -cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - mov [foldcache_clus+di-foldcache_mark+bx], ax - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet -cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di -cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 - pop ds -; mov dx, bx -; shl dx, 8 ; dx = (position in cache)*0x2000/0x10 -; add dx, 0x9200 - lea dx, [bx+0x92] - xchg dl, dh - mov es, dx - jcxz not_in_cache - call [scan_for_filename] - jz lookup_done -not_in_cache: -; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -folder_next_cluster: -; internal loop: scan sectors in cluster - mov cx, [sect_per_clus] - push ax - dec ax - dec ax - mul cx - add ax, [bp-8] - adc dx, [bp-6] ; dx:ax = absolute sector -folder_next_sector: -; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - call [read_sectors] -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - push si di - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache - pop di si -@@: - push es - push 0x8000 - pop es - push cs - pop ds - mov cx, 0x10 - call [scan_for_filename] - pop es - pop cx - jz lookup_done_pop -folder_skip_sector: - inc ax - jnz @f - inc dx -@@: - loop folder_next_sector - pop ax ; ax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push ax -lookup_done_pop: - pop ax -lookup_done: - pop si - pop ds -; CF=1 <=> failed - jnc found -notfound: - pop di - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret -notfound_pop: - pop ax - jmp notfound -found: - mov ax, [es:di+26] ; get cluster - test byte [es:di+11], 10h ; directory? - jz regular_file - cmp byte [si-1], 0 - jz notfound ; don't read directories as a regular files -; ok, we have found a directory and the caller requested a file into it - pop di - jmp parse_dir_loop ; restart with new cluster in ax -regular_file: - cmp byte [si-1], 0 - jnz notfound ; file does not contain another files -; ok, we have found a regular file and the caller requested it -; save file size - mov dx, [es:di+28] - mov [filesize], dx - mov dx, [es:di+30] - mov [filesize+2], dx - pop di - mov si, [di+4] - shl si, 3 - push si ; [ds:di+4] = limit in 4K blocks - les bx, [di] ; es:bx -> buffer -clusloop: -; ax = first cluster, top of stack contains limit in sectors - mov si, ax ; remember current cluster - xor cx, cx ; cx will contain number of consecutive clusters - mov word [cur_delta], cx - mov word [cur_delta+2], cx - mov di, ax -clusfind: - inc di - inc cx - call get_next_cluster - jnc clusread - cmp ax, di - jz clusfind - stc -clusread: - pop di ; limit in sectors - push ax ; save next cluster - pushf ; save flags -; read cx clusters, starting from si -; calculate number of sectors - xchg ax, cx - mul [sect_per_clus] -; dx:ax = number of sectors; compare with limit - mov word [num_sectors], ax - mov word [num_sectors+2], dx - jmp @f -continue_load_file: - les bx, [di] ; es:bx -> buffer - mov di, [di+4] ; ds:di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov ax, word [num_sectors] - mov dx, word [num_sectors+2] - mov si, [cur_cluster] - push [next_cluster] - push [flags] - or ax, dx - jz nextclus -@@: - test dx, dx - jnz clusdecrease - push dx ; limit was not exceeded - cmp ax, di - jbe @f - pop ax -clusdecrease: - push 1 ; limit was exceeded - mov ax, di -@@: - sub di, ax ; calculate new limit - sub word [num_sectors], ax - sbb word [num_sectors+2], 0 -; calculate starting sector - xchg ax, cx - lea ax, [si-2] - mul [sect_per_clus] - add ax, word [cur_delta] - adc dx, word [cur_delta+2] - add word [cur_delta], cx - adc word [cur_delta+2], 0 -; read - call [read_sectors2] - pop dx -; next cluster? -nextclus: - popf - pop ax - mov [cur_cluster], si - mov [next_cluster], ax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 ; dh=0 in any case - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue -hooked_err: - mov sp, 7C00h-12-2 ; restore stack - mov dx, 3 ; return: read error -@@: - mov bx, dx - mov ax, [filesize] - mov dx, [filesize+2] - ret - -; Callback function for secondary loader -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-8 - mov bp, 7C00h - push dx - push cx -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret -; function 2: continue loading file -; can be called only after function 1 returned value bx=1 (only part of file was loaded) -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file -callback_ret_succ: - clc ; function is supported -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kord/loader',0 -aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 - -foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache -foldcache_mark rw 7 -foldcache_size rw 7 -filename rb 11 -if $ > 0x8200 -error: - table overwritten -end if diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.asm deleted file mode 100644 index eb0b7c936b..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.asm +++ /dev/null @@ -1,358 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -use_lba = 0 - org 0x7C00 - jmp start - nop -; FAT parameters, BPB -; they must be changed at install, replaced with real values - rb 8 ; BS_OEMName, ignored - dw 200h ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? - dw ? ; BPB_FSInfo -BPB_BkBootSec dw ? - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID - rb 11 ; BS_VolLab - rb 8 ; - -curseg dw 0x8000 - -start: - xor ax, ax - mov ss, ax - mov sp, 0x7C00 - mov ds, ax - mov bp, sp - cld - sti - push dx ; byte [bp-2] = boot drive -if use_lba - mov ah, 41h - mov bx, 55AAh - int 13h - mov si, aNoLBA - jc err_ - cmp bx, 0AA55h - jnz err_ - test cl, 1 - jz err_ -else - mov ah, 8 - int 13h - jc @f - movzx ax, dh - inc ax - mov [bp+BPB_NumHeads-0x7C00], ax - and cx, 3Fh - mov [bp+BPB_SecPerTrk-0x7C00], cx -@@: -end if -; get FAT parameters - xor bx, bx - movzx eax, [bp+BPB_NumFATs-0x7C00] - mul [bp+BPB_FATSz32-0x7C00] - movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00] - push ecx ; FAT start = dword [bp-6] - add eax, ecx - push eax ; data start = dword [bp-10] - ;push dword -1 ; dword [bp-14] = current sector for FAT cache - db 66h - push -1 ; dword [bp-14] = current sector for FAT cache - mov eax, [bp+BPB_RootClus-0x7C00] - mov si, main_loader - call lookup_in_dir - jnc kordldr_ok -noloader: - mov si, aLoaderNotFound -err_: - call out_string - mov si, aPressAnyKey - call out_string - xor ax, ax - int 16h - int 18h - jmp $ -kordldr_ok: - mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster) - mov ax, [es:di+26] ; loword(eax) = loword(cluster) - mov es, bx ; es = 0 - mov bx, 0x7E00 - push bx ; save return address: bx = 7E00 -; fall through - 'ret' in read_cluster will return to 7E00 - -read_cluster: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; eax = cluster - sub eax, 2 - movzx ecx, [bp+BPB_SecsPerClus-0x7C00] - mul ecx - -read_sectors2: -; same as read_sectors32, but eax is relative to start of data - add eax, [bp-10] -read_sectors32: -; ss:bp = 0:7C00 -; es:bx = pointer to data -; eax = first sector -; cx = number of sectors -; some high words of 32-bit registers are destroyed! - pusha - add eax, [bp+BPB_HiddSec-0x7C00] -if use_lba - push ds -do_read_sectors: - push ax - push cx - cmp cx, 0x7F - jbe @f - mov cx, 0x7F -@@: -; create disk address packet on the stack -; dq starting LBA - push 0 - push 0 - push eax -; dd buffer - push es - push bx -; dw number of blocks to transfer (no more than 0x7F) - push cx -; dw packet size in bytes - push 10h -; issue BIOS call - push ss - pop ds - mov si, sp - mov dl, [bp-2] - mov ah, 42h - int 13h - mov si, aReadError - jc err_ -; restore stack - add sp, 10h -; increase current sector & buffer; decrease number of sectors - movzx esi, cx - mov ax, es - shl cx, 5 - add ax, cx - mov es, ax - pop cx - pop ax - add eax, esi - sub cx, si - jnz do_read_sectors - pop ds - popa - ret -else -do_read_sectors: - pusha - pop edi ; loword(edi) = di, hiword(edi) = si - push bx - -; eax / (SectorsPerTrack) -> eax, remainder bx - movzx esi, [bp+BPB_SecPerTrk-0x7C00] - xor edx, edx - div esi - mov bx, dx ; bx=sector-1 - -; eax -> dx:ax - push eax - pop ax - pop dx -; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx - div [bp+BPB_NumHeads-0x7C00] - -; number of sectors: read no more than to end of track - sub si, bx - cmp cx, si - jbe @f - mov cx, si -@@: - - inc bx -; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format - movzx edi, cx - mov dh, dl - mov dl, [bp-2] - shl ah, 6 - mov ch, al - mov al, cl - mov cl, bl - or cl, ah - pop bx - mov si, 3 - mov ah, 2 -@@: - push ax - int 13h - jnc @f - xor ax, ax - int 13h ; reset drive - pop ax - dec si - jnz @b - mov si, aReadError - jmp err_ -@@: - pop ax - mov ax, es - mov cx, di - shl cx, 5 - add ax, cx - mov es, ax - push edi - popa - add eax, edi - sub cx, di - jnz do_read_sectors - popa - ret -end if - -lookup_in_dir: -; in: ds:si -> 11-bytes FAT name -; in: eax = cluster -; in: bx = 0 -; out: if found: CF=0, es:di -> directory entry -; out: if not found: CF=1 -; push 0x8000 -; pop es -; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000 - mov es, [bp-7C00h + curseg] - push es - push eax - call read_cluster - mov ax, es - cmp ah, 82h - jb @f - mov ax, 8200h -@@: - mov [bp-7C00h + curseg], ax - pop eax - pop es -; scan for filename - shl cx, 4 - xor di, di -sloop: - cmp byte [es:di], bl - jz snotfound - test byte [es:di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmpsb - popa - jz sdone -scont: - add di, 0x20 - loop sloop -; next cluster - push 0x6000 - pop es - push es ax - shr eax, 7 - cmp eax, [bp-14] - mov [bp-14], eax - jz @f - add eax, [bp-6] - mov cx, 1 - call read_sectors32 -@@: - pop di es - and di, 0x7F - shl di, 2 - and byte [es:di+3], 0x0F - mov eax, [es:di] - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - jb lookup_in_dir -snotfound: - stc -sdone: - ret - -out_string: -; in: ds:si -> ASCIIZ string - lodsb - test al, al - jz sdone - mov ah, 0Eh - mov bx, 7 - int 10h - jmp out_string - -aReadError db 'Read error',0 -if use_lba -aNoLBA db 'The drive does not support LBA!',0 -end if -aLoaderNotFound db 'Loader not found',0 -aPressAnyKey db 13,10,'Press any key...',13,10,0 -main_loader db 'KORDLDR F32' - - db 56h -; just to make file 512 bytes long :) - db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd' - -; bootsector signature - dw 0xAA55 - -; display offsets of all procedures used by kordldr.f12.asm -macro show [procedure] -{ - bits = 16 - display `procedure,' = ' - repeat bits/4 - d = '0' + procedure shr (bits - %*4) and 0Fh - if d > '9' - d = d + 'A'-'9'-1 - end if - display d - end repeat - display 13,10 -} - -show read_sectors32, read_sectors2, err_, noloader diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.txt b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.txt deleted file mode 100644 index caabcb33f9..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.txt +++ /dev/null @@ -1,333 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - Читай между строк - там никогда не бывает опечаток. - -Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт. - -===================================================================== - -Есть две версии в зависимости от того, поддерживает ли носитель LBA, -выбор осуществляется установкой константы use_lba в первой строке исходника. -Требования для работы: -1) Сам бутсектор, первая копия FAT и все используемые файлы -должны быть читабельны. (Если дело происходит на носителе с разбиением на -разделы и загрузочный код в MBR достаточно умный, то читабельности резервной -копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности -самого бутсектора). -2) Минимальный процессор - 80386. -3) В системе должно быть как минимум 584K свободной базовой памяти. - -===================================================================== - -Документация в тему (ссылки проверялись на валидность 15.05.2008): - официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx - в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf - русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip - официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf - то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf - описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html - официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf - -===================================================================== - -Схема используемой памяти: - ...-7C00 стек - 7C00-7E00 код бутсектора - 7E00-8200 вспомогательный файл загрузчика (kordldr.f32) - 8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8 - байт: 4 байта (две ссылки - вперёд и назад) для - организации L2-списка всех прочитанных секторов в - порядке возрастания последнего времени использования - + 4 байта для номера сектора; при переполнении кэша - выкидывается элемент из головы списка, то есть тот, - к которому дольше всех не было обращений - 60000-80000 кэш для таблицы FAT (100h секторов) - 80000-90000 текущий кластер текущей рассматриваемой папки - 90000-... кэш для содержимого папок (каждой папке отводится - 2000h байт = 100h входов, одновременно в кэше - может находиться не более 8 папок; - точный размер определяется размером доступной - физической памяти - как правило, непосредственно - перед A0000 размещается EBDA, Extended BIOS Data Area) - -===================================================================== - -Основной процесс загрузки. -Точка входа (start): получает управление от BIOS при загрузке, при этом - dl содержит идентификатор диска, с которого идёт загрузка -1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед - кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало - бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - - это освобождает ds и экономит на размере кода). Сохраняет в стеке - идентификатор загрузочного диска для последующего обращения - через byte [bp-2]. -2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h - прерывания 13h. Если нет, переходит на код обработки ошибок с - сообщением об отсутствии LBA. -CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и - записывает полученные данные поверх BPB. Если вызов завершился ошибкой, - предполагает уже существующие данные корректными. -3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего - обращения через dword [bp-10]. В процессе вычисления узнаёт начало - первой FAT, сохраняет и его в стек для последующего обращения через - dword [bp-6]. -4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1 - для последующего обращения через dword [bp-14] - инициализация - переменной, содержащей текущий сектор, находящийся в кэше FAT - (-1 не является валидным значением для номера сектора FAT). -5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на - код обработки ошибок с сообщением о ненайденном загрузчике. - Замечание: на этом этапе загрузки искать можно только в корневой - папке и только имена, заданные в формате файловой системе FAT - (8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны - быть заглавными, при необходимости имя и расширение дополняются - пробелами, разделяющей точки нет, завершающего нуля нет). -6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт - ему управление. При этом в регистре eax оказывается абсолютный - номер первого сектора kordldr.f32, а в cx - число считанных секторов - (равное размеру кластера). - -Вспомогательные процедуры бутсектора. -Код обработки ошибок (err): -1. Выводит строку с сообщением об ошибке. -2. Выводит строку "Press any key...". -3. Ждёт нажатия any key. -4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. -5. Для подстраховки зацикливается. - -Процедура чтения кластера (read_cluster): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = номер кластера -на выходе: ecx = число прочитанных секторов (размер кластера), - es:bx указывает на конец буфера, в который были прочитаны данные, - eax и старшие слова других 32-битных регистров разрушаются -Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора -и переходит к следующей процедуре. - -Процедура чтения секторов (read_sectors32 и read_sectors2): -на входе должно быть установлено: - ss:bp = 0:7C00 - es:bx = указатель на начало буфера, куда будут прочитаны данные - eax = стартовый сектор (относительно начала логического диска - для read_sectors32, относительно начала данных - для read_sectors2) - cx = число секторов (должно быть больше нуля) -на выходе: es:bx указывает на конец буфера, в который были прочитаны данные - старшие слова 32-битных регистров могут разрушиться -0. Если вызывается read_sectors2, она переводит указанный ей номер сектора - в номер относительно начала логического диска, прибавляя номер сектора - начала данных, хранящийся в стеке как [bp-10]. -1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на - устройстве, прибавляя значение соответствующего поля из BPB. -2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации - CHS-версия: все читаемые секторы были на одной дорожке. - LBA-версия: число читаемых секторов не превосходило 7Fh (требование - спецификации EDD BIOS). -CHS-версия: -3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как - единица плюс остаток от деления абсолютного номера на число секторов - на дорожке; дорожка рассчитывается как остаток от деления частного, - полученного на предыдущем шаге, на число дорожек, а цилиндр - как - частное от этого же деления. Если число секторов для чтения больше, - чем число секторов до конца дорожки, уменьшает число секторов для - чтения. -4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, - dh=головка, (младшие 6 бит cl)=сектор, - (старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска - и повторяет попытку чтения, всего делается не более трёх попыток - (несколько попыток нужно в случае дискеты для гарантии того, что - мотор раскрутился). Если все три раза происходит ошибка чтения, - переходит на код обработки ошибок с сообщением "Read error". -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. -LBA-версия: -3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей - итерации) до 7Fh. -4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами - push, причём в обратном порядке: стек - структура LIFO, и данные в - стеке хранятся в обратном порядке по отношению к тому, как их туда - клали). -5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки - ошибок с сообщением "Read error". Очищает стек от пакета, - сформированного на предыдущем шаге. -6. В соответствии с числом прочитанных на текущей итерации секторов - корректирует текущий сектор, число оставшихся секторов и указатель на - буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает - работу, иначе возвращается на шаг 3. - -Процедура поиска элемента в папке (lookup_in_dir): -на входе должно быть установлено: - ss:bp = 0:7C00 - ds:si = указатель на имя файла в формате FAT (см. выше) - eax = начальный кластер папки - bx = 0 -на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то - CF сброшен и es:di указывает на элемент папки -В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных -данных. Для чтения кластера использует уже описанную процедуру read_clusters, -для продвижения по цепочке кластеров - описанную далее процедуру -get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса -8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше, -если чтение прервётся раньше) не перекрываются последующими чтениями -(это будет использовано позднее, в системе кэширования из kordldr.f32). -Выход осуществляется в любом из следующих случаев: найден запрошенный элемент; -кончились элементы в папке (первый байт очередного элемента нулевой); -кончились данные папки в соответствии с цепочкой кластеров из FAT. - -Процедура вывода на экран ASCIIZ-строки (out_string): -на входе: ds:si -> строка -В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. - -===================================================================== - -Работа вспомогательного загрузчика kordldr.f32: -1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. - В зависимости от этого устанавливает смещения используемых процедур - бутсектора. Критерий проверки: в CHS-версии по адресу err находится - байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу - находится байт 0x14, а адрес процедуры err другой. -2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска - адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с - ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента - место должно быть, отсюда ограничение в 592 Kb (94000h байт). - Замечание: этот размер не может превосходить 0A0000h байт и - на практике оказывается немного (на 1-2 килобайта) меньшим из-за - наличия дополнительной области данных BIOS "вверху" базовой памяти. -3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть - данных корневой папки; копирует загруженные данные в кэш и запоминает, - что в кэше есть корневая папка. -4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только - том случае, когда ему приходится загружать данные корневой папки, - не поместившиеся в один кластер. В этом случае в памяти присутствует - один сектор FAT (если было несколько обращений - последний из - использованных). -5. Если кластер равен сектору, то бутсектор загрузил только часть файла - kordldr.f32, и загрузчик подгружает вторую свою часть, используя - значения регистров на входе в kordldr.f32. -6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не - найден, или оказался папкой, или оказался слишком большим, то переходит - на код обработки ошибок из бутсектора с сообщением - "Fatal error: cannot load the secondary loader". - Замечание: на этом этапе имя файла уже можно указывать вместе с путём - и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов - по-прежнему нет. -7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. - Это нужно, чтобы последующие обращения к коду бутсектора в случае - ошибок чтения не выводил соответствующее сообщение с последующей - перезагрузкой, а рапортовал об ошибке чтения, которую могло бы - как-нибудь обработать ядро. -8. Если загрузочный диск имеет идентификатор меньше 0x80, - то устанавливает al='f' ("floppy"), ah=идентификатор диска, - иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). - (Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но - уверены ли Вы, что нет загрузочных устройств, подобных дискетам, - но большего размера, и для которых BIOS-идентификатор меньше 0x80?) - Устанавливает bx='32' (тип файловой системы - FAT32). - Устанавливает si=смещение функции обратного вызова. Поскольку в этот - момент ds=0, то ds:si образуют полный адрес. -9. Передаёт управление по адресу 1000:0000. - -Функция обратного вызова для вторичного загрузчика: - предоставляет возможность чтения файла. -Вход и выход описаны в спецификации на загрузчик. -1. Сохраняет стек вызывающего кода и устанавливает свой стек: - ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным - кодом должна указывать на 0:7C00, а -10 берётся от того, что - инициализирующий код бутсектора уже поместил в стек 10 байт параметров, - и они должны сохраняться в неизменности. (Значение [ebp-14], - "текущий сектор, находящийся в кэше FAT", не используется после - инициализации кэширования в kordldr.f32.) -2. Разбирает переданные параметры и вызывает нужную из вспомогательных - процедур (загрузки файла либо продолжения загрузки файла). -3. Восстанавливает стек вызывающего кода и возвращает управление. - -Вспомогательные процедуры kordldr.f32. -Процедура получения следующего кластера в FAT (get_next_cluster): -1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент. - (В секторе 0x200 байт, каждый вход занимает 4 байта.) -2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4. -3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен, - выделяет очередной элемент в конце кэша. Если заполнен, удаляет - самый старый элемент (тот, к которому дольше всего не было обращений); - для того, чтобы отслеживать порядок элементов по времени последнего - обращения, все (выделенные) элементы кэша связаны в двусвязный список, - в котором первым элементом является самый старый, а ссылки вперёд - указывают на следующий по времени последнего обращения. -4. Читает соответствующий сектор FAT с диска. -5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции, - где он находится, и добавляется в конец. (В случае со свежедобавленными - в кэш элементами удаления не делается, поскольку их в списке ещё нет.) -6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита. -7. Сравнивает прочитанное значение с пределом: если оно строго меньше - 0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке; - в противном случае цепочка закончилась. - -Процедура загрузки файла (load_file): -1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. -2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты - разделяются символом '/') в FAT-формат 8+3. Если это невозможно - (больше 8 символов в имени, больше 3 символов в расширении или - больше одной точки), возвращается с ошибкой. -3. Ищет элемент с таким именем в текущей рассматриваемой папке. - а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок - осуществляется по номеру начального кластера.) Если такой папки ещё - нет, добавляет её в кэш; если тот переполняется, выкидывает папку, - к которой дольше всего не было обращений. (Для каждого элемента кэша - хранится метка от 0 до (размер кэша)-1, определяющая его номер при - сортировке по давности последнего обращения. При обращении к какому-то - элементу его метка становится нулевой, а те метки, которые меньше - старого значения, увеличиваются на единицу.) - б) Просматривает в поисках запрошенного имени все элементы из кэша, - используя процедуру из бутсектора. Если обнаруживает искомый элемент, - переходит к шагу 4. Если обнаруживает конец папки, возвращается из - процедуры с ошибкой. - в) В цикле считывает папку посекторно. При этом пропускает начальные - секторы, которые уже находятся в кэше и уже были просмотрены. Каждый - прочитанный сектор копирует в кэш, если там ещё остаётся место, - и просматривает в нём все элементы. Работает, пока не случится одно из - трёх событий: найден искомый элемент; кончились кластеры (судя по - цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце - (первый байт нулевой). В двух последних случаях возвращается с ошибкой. -4. Проверяет тип найденного элемента (файл/папка): последний элемент в - запрошенном имени должен быть файлом, все промежуточные - папками. - Если текущий компонент имени - промежуточный, продвигает текущую - рассматриваемую папку и возвращается к пункту 2. -5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный - при вызове буфер последовательными вызовами функции бутсектора; - при этом если несколько кластеров файла расположены на диске - последовательно, то их чтение объединяется в одну операцию. - Следит за тем, чтобы не превысить указанный при вызове процедуры - лимит числа секторов для чтения. - -Процедура продолжения загрузки файла (continue_load_file): встроена - внутрь шага 5 load_file; загружает в регистры нужные значения (ранее - сохранённые из load_file) и продолжает шаг 5. diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/build.bat b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/build.bat deleted file mode 100644 index 267c29375b..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@fasm -m 65535 bootsect.asm bootsect.bin -@fasm -m 65535 kordldr.f32.asm kordldr.f32 -@pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/kordldr.f32.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/kordldr.f32.asm deleted file mode 100644 index fa7d73baee..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/kordldr.f32.asm +++ /dev/null @@ -1,672 +0,0 @@ -; Copyright (c) 2008-2009, diamond -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - - org 0x7E00 -; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here -; ss:bp = 0:7C00 -; ds = 0 -virtual at bp - rb 3 ; BS_jmpBoot - rb 8 ; BS_OEMName, ignored - dw ? ; BPB_BytsPerSec -BPB_SecsPerClus db ? -BPB_RsvdSecCnt dw ? -BPB_NumFATs db ? -BPB_RootEntCnt dw ? - dw ? ; BPB_TotSec16 - db ? ; BPB_Media - dw ? ; BPB_FATSz16 = 0 for FAT32 -BPB_SecPerTrk dw ? -BPB_NumHeads dw ? -BPB_HiddSec dd ? - dd ? ; BPB_TotSec32 -BPB_FATSz32 dd ? -BPB_ExtFlags dw ? - dw ? ; BPB_FSVer -BPB_RootClus dd ? -filesize: - dw ? ; BPB_FSInfo - dw ? ; BPB_BkBootSec - rb 12 ; BPB_Reserved -BS_DrvNum db ? - db ? ; BS_Reserved1 - db ? ; BS_BootSig - dd ? ; BS_VolID -; rb 11 ; BS_VolLab -; rb 5 ; BS_FilSysType, first 5 bytes -read_sectors32 dw ? -read_sectors2 dw ? -err_ dw ? -noloader dw ? -cachelimit dw ? -fatcachehead rw 2 -fatcacheend dw ? - rb 3 ; BS_FilSysType, last 3 bytes -curseg dw ? -num_sectors dd ? -cur_cluster dd ? -next_cluster dd ? -flags dw ? -cur_delta dd ? -end virtual - -; procedures from boot sector -; LBA version -lba_read_sectors2 = 7CD6h -lba_err = 7CAAh -lba_noloader = 7CA7h ; = lba_err - 3 -; CHS version -chs_read_sectors2 = 7CD2h -chs_err = 7CA6h -chs_noloader = 7CA3h ; = chs_err - 3 - - push eax cx ; save our position on disk -; determine version of bootsector (LBA vs CHS) - mov [read_sectors2], chs_read_sectors2 - mov bx, chs_err - mov [err_], bx -; mov [noloader], chs_noloader - cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version - jz @f - add [read_sectors2], lba_read_sectors2 - chs_read_sectors2 - add [err_], lba_err - chs_err -; mov [noloader], lba_noloader -@@: - xor bx, bx -; determine size of cache for folders - int 12h ; ax = size of available base memory in Kb - sub ax, 92000h / 1024 - jae @f -nomem: - mov si, nomem_str - jmp [err_] -@@: - shr ax, 3 - mov [cachelimit], ax ; size of cache - 1 - mov es, bx -; no folders in cache yet - mov di, foldcache_clus - mov cx, 8*4/2 + 1 - xor ax, ax - rep stosw -; bootsector code caches one FAT sector, [bp-14], in 6000:0000 -; initialize our (more advanced) FAT caching from this - mov di, 8400h - mov cx, di - lea si, [fatcachehead] - mov [si], si ; no sectors in cache: - mov [si+2], si ; 'prev' & 'next' links point to self - mov [fatcacheend], di ; first free item = 8400h - stosw ; 'next cached sector' link - stosw ; 'prev cached sector' link - mov eax, [bp-14] - stosd ; first sector number in cache - test eax, eax - js @f - mov [si], cx ; 'first cached sector' link = 8400h - mov [si+2], cx ; 'next cached sector' link = 8400h - mov [fatcacheend], di ; first free item = 8406h -@@: -; if cluster = sector, we need to read second part of our file -; (bootsector loads only first cluster of kordldr.f32) - pop cx eax ; restore our position on disk - cmp cx, 1 - ja kordldr_full - sub eax, [bp-10] - inc eax - inc eax ; eax = first cluster of kordldr.f32 - call get_next_cluster - jc @f -; jmp [noloader] - mov ax, [err_] - sub ax, 3 - jmp ax -@@: - dec eax - dec eax - push 0x800 - pop es - call [read_sectors2] -kordldr_full: -; bootsector code has read some data of root directory to 8000:0000 -; initialize our folder caching from this - mov eax, [BPB_RootClus] - mov [foldcache_clus], eax - mov cx, [curseg] - mov ax, 8000h - sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes) - shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes) - mov [foldcache_size], cx - shl cx, 4 - push ds - mov ds, ax - push 0x9000 - pop es - xor si, si - xor di, di - rep movsw - pop ds -; ...continue loading... - mov di, secondary_loader_info - call load_file - test bx, bx - mov bx, [err_] - jz @f - mov si, aKernelNotFound - jmp bx -@@: -; for subsequent calls to callback function, hook error handler -; push hooked_err / ret - mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24) -; set registers for secondary loader - mov ah, [bp-2] ; drive id - mov al, 'f' - btr ax, 15 - jnc @f - mov al, 'h' -@@: - mov bx, '32' - mov si, callback - jmp far [si+secondary_loader_info-callback] - -nomem_str db 'No memory',0 - -cluster2sector: - sub eax, 2 -clustersz2sectorsz: - movzx ecx, [BPB_SecsPerClus] - mul ecx - ret - -get_next_cluster: -; in: eax = cluster -; out: if there is next cluster: CF=1, eax = next cluster -; out: if there is no next cluster: CF=0 - push di bx - push ds - push ss - pop ds - push ax - shr eax, 7 -; eax = FAT sector number; look in cache - mov di, 8400h -.cache_lookup: - cmp di, [fatcacheend] - jae .not_in_cache - scasd - scasd - jnz .cache_lookup -.in_cache: - sub di, 8 -; delete this sector from the list - push si - mov si, [di] - mov bx, [di+2] - mov [si+2], bx - mov [bx], si - pop si - jmp @f -.not_in_cache: -; cache miss -; cache is full? - mov di, [fatcacheend] - cmp di, 8C00h - jnz .cache_not_full -; yes, delete the oldest entry - mov di, [fatcachehead] - mov bx, [di] - mov [fatcachehead], bx - push word [di+2] - pop word [bx+2] - jmp .cache_append -.cache_not_full: -; no, allocate new sector - add [fatcacheend], 8 -.cache_append: -; read FAT - mov [di+4], eax - push es - pushad - lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM - shl cx, 9-3 - mov es, cx - xor bx, bx - mov cx, 1 - add eax, [bp-6] ; FAT start - sub eax, [bp-10] - call [read_sectors2] - popad - pop es -@@: -; add new sector to the end of list - mov bx, di - xchg bx, [fatcachehead+2] - push word [bx] - pop word [di] - mov [bx], di - mov [di+2], bx -; get requested item - lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] - pop di - and di, 0x7F - shl di, 2 - shl ax, 9-3 - mov ds, ax - and byte [di+3], 0x0F - mov eax, [di] - pop ds - pop bx di - ;and eax, 0x0FFFFFFF - cmp eax, 0x0FFFFFF7 - ret - -if $ > 0x8000 -error 'get_next_cluster must fit in first sector of kordldr.f32!' -end if - -load_file: -; in: ss:bp = 0:7C00 -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found -; out: dx:ax = file size (0xFFFFFFFF if file not found) - mov eax, [BPB_RootClus] ; start from root directory - or dword [filesize], -1 ; initialize file size with invalid value - lea si, [di+6] -parse_dir_loop: -; convert name to FAT name - push di - push ax - push ss - pop es -; convert ASCIIZ filename to FAT name -filename equ bp - mov di, filename - push di - mov cx, 8+3 - mov al, ' ' - rep stosb - pop di - mov cl, 8 ; 8 symbols per name - mov bl, 1 -nameloop: - lodsb - test al, al - jz namedone - cmp al, '/' - jz namedone - cmp al, '.' - jz namedot - dec cx - js badname - cmp al, 'a' - jb @f - cmp al, 'z' - ja @f - sub al, 'a'-'A' -@@: - stosb - jmp nameloop -namedot: - inc bx - jp badname - add di, cx - mov cl, 3 - jmp nameloop -badname: ; do not make direct js/jp to notfound_pop: - ; this generates long forms of conditional jumps and results in longer code - jmp notfound_pop -namedone: -; scan directory - pop ax ; eax = cluster of directory - ; high word of eax is preserved by operations above - push ds - push si -; read a folder sector-by-sector and scan -; first, try to use the cache - push ss - pop ds - mov di, foldcache_mark - xor bx, bx - mov cx, [cachelimit] -@@: - lea si, [di+bx] - mov edx, dword [foldcache_clus+si-foldcache_mark+bx] - cmp edx, eax - jz cacheok - test edx, edx - jz cacheadd ; the cache has place for new entry - inc bx - inc bx - dec cx - jns @b -; the folder is not present in the cache, so add it -; the cache is full; find the oldest entry and replace it with the new one - mov bx, -2 - mov dx, [cachelimit] -@@: - inc bx - inc bx - cmp word [di+bx], dx ; marks have values 0 through [cachelimit] - jnz @b - lea si, [di+bx] -cacheadd: - or word [di+bx], 0xFFFF ; very big value, it will be changed soon - and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet - mov dword [foldcache_clus+si-foldcache_mark+bx], eax -cacheok: -; update cache marks - mov dx, [di+bx] - mov cx, [foldcache_size+di-foldcache_mark+bx] - mov di, [cachelimit] - add di, di -cacheupdate: - cmp [foldcache_mark+di], dx - adc [foldcache_mark+di], 0 - dec di - dec di - jns cacheupdate - and [foldcache_mark+bx], 0 -; done, bx contains (position in cache)*2 - ;mov dx, bx - ;shl dx, 8 ; dx = (position in cache)*0x2000/0x10 - ;add dx, 0x9000 - lea dx, [bx + 0x90] - xchg dl, dh - mov ds, dx - mov si, filename ; ss:si -> filename in FAT style - call scan_for_filename - jz lookup_done -; cache miss, read folder data from disk - mov bx, cx - shr bx, 4 - shl cx, 5 - mov di, cx ; es:di -> free space in cache entry -; external loop: scan clusters -folder_next_cluster: -; internal loop: scan sectors in cluster - push eax - call cluster2sector -folder_next_sector: -; skip first bx sectors - dec bx - jns folder_skip_sector - push cx - push es di - push 0x8000 - pop es - xor bx, bx - mov cx, 1 - push es - push eax - call [read_sectors2] - pop eax -; copy data to the cache... - pop ds - pop di es - cmp di, 0x2000 ; ...if there is free space, of course - jae @f - pusha - mov cx, 0x100 - xor si, si - rep movsw - mov di, es - shr di, 8 - add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache - popa -@@: - push es - mov cl, 0x10 ; ch=0 at this point - call scan_for_filename - pop es - pop cx - jz lookup_done_pop -folder_skip_sector: - inc eax - loop folder_next_sector - pop eax ; eax = current cluster - call get_next_cluster - jc folder_next_cluster - stc - push eax -lookup_done_pop: - pop eax -lookup_done: - pop si -; CF=1 <=> failed - jnc found - pop ds -notfound: - pop di -notfound2: - mov bx, 2 ; file not found - mov ax, 0xFFFF - mov dx, ax ; invalid file size - ret -notfound_pop: - pop ax - jmp notfound -found: - mov eax, [di+20-2] - mov edx, [di+28] - mov ax, [di+26] ; get cluster - test byte [di+11], 10h ; directory? - pop ds - pop di - jz regular_file - cmp byte [si-1], 0 - jz notfound2 ; don't read directories as regular files -; ok, we have found a directory and the caller requested a file into it - jmp parse_dir_loop ; restart with new cluster in ax -regular_file: - cmp byte [si-1], 0 - jnz notfound2 ; file does not contain another files -; ok, we have found a regular file and the caller requested it -; save file size - mov [filesize], edx - mov si, [di+4] ; [ds:di+4] = limit in 4K blocks - shl si, 3 - push si - les bx, [di] ; es:bx -> buffer -clusloop: -; eax = first cluster, top of stack contains limit in sectors - mov esi, eax ; remember current cluster - xor ecx, ecx ; ecx will contain number of consecutive clusters - mov [cur_delta], ecx - mov edi, eax -clusfind: - inc edi - inc ecx - call get_next_cluster - jnc clusread - cmp eax, edi - jz clusfind - stc -clusread: - pop di ; limit in sectors - movzx edi, di - push eax ; save next cluster - pushf ; save flags -; read cx clusters, starting from si -; calculate number of sectors - xchg eax, ecx - call clustersz2sectorsz - mov [num_sectors], eax - jmp @f -continue_load_file: - les bx, [di] ; es:bx -> buffer - movzx edi, word [di+4] ; di = limit in 4K blocks - shl di, 3 ; now di = limit in sectors - mov eax, [num_sectors] - mov esi, [cur_cluster] - push [next_cluster] - push [flags] - test eax, eax - jz nextclus -@@: -; eax = number of sectors; compare with limit - cmp eax, edi - seta dl - push dx ; limit was exceeded? - jbe @f - mov eax, edi -@@: - sub di, ax ; calculate new limit - sub [num_sectors], eax - mov [cur_cluster], esi -; calculate starting sector - push ax - xchg eax, esi - call cluster2sector - pop cx - add eax, [cur_delta] - add [cur_delta], ecx -; read - call [read_sectors2] - pop dx -; next cluster? -nextclus: - popf - pop eax - mov [next_cluster], eax - pushf - pop [flags] - jnc @f ; no next cluster => return - mov dl, 1 ; dh=0 in any case - test di, di - jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded - push di - jmp clusloop ; all is ok, continue -hooked_err: - mov sp, 7C00h-14-2 ; restore stack - mov dx, 3 ; return: read error -@@: - mov bx, dx - mov ax, [filesize] - mov dx, [filesize+2] - ret - -scan_for_filename: -; in: ss:si -> 11-bytes FAT name -; in: ds:0 -> part of directory data -; in: cx = number of entries -; in: bh = 0 -; out: if found: CF=0, ZF=1, es:di -> directory entry -; out: if not found, but continue required: CF=1 and ZF=0 -; out: if not found and zero item reached: CF=1 and ZF=1 - push ds - pop es - xor di, di - push cx - jcxz snoent -sloop: - cmp byte [di], bh - jz snotfound - test byte [di+11], 8 ; volume label? - jnz scont ; ignore volume labels - pusha - mov cx, 11 - repz cmps byte [ss:si], byte [es:di] - popa - jz sdone -scont: - add di, 0x20 - loop sloop -snoent: - inc cx ; clear ZF flag -snotfound: - stc -sdone: - pop cx -lrdret: - ret - -; Callback function for secondary loader -callback: -; in: ax = function number; only functions 1 and 2 are defined for now -; save caller's stack - mov dx, ss - mov cx, sp -; set our stack (required because we need ss=0) - xor si, si - mov ss, si - mov sp, 7C00h-10 - mov bp, 7C00h - push dx - push cx -; call our function - stc ; unsupported function - dec ax - jz callback_readfile - dec ax - jnz callback_ret -; function 2: continue loading file -; can be called only after function 1 returned value bx=1 (only part of file was loaded) -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error -; out: dx:ax = file size - call continue_load_file - jmp callback_ret_succ -callback_readfile: -; function 1: read file -; in: ds:di -> information structure -; dw:dw address -; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100) -; ASCIIZ name -; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error -; out: dx:ax = file size (0xFFFFFFFF if file was not found) - call load_file -callback_ret_succ: - clc ; function is supported -callback_ret: -; restore caller's stack - pop cx - pop ss - mov sp, cx -; return to caller - retf - -secondary_loader_info: - dw 0, 0x1000 - dw 0x30000 / 0x1000 - db 'kord/loader',0 -aKernelNotFound db 'Fatal error: cannot load the secondary loader',0 - -;if $ > 0x8200 -;error 'total size of kordldr.f32 must not exceed 1024 bytes!' -;end if - -;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache -;foldcache_mark dw 0 -; rw 7 -;foldcache_size rw 8 -foldcache_clus rd 8 -foldcache_mark rw 8 -foldcache_size rw 8 diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/floppy.asc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/floppy.asc deleted file mode 100644 index 7d2ba1bfd7..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/floppy.asc +++ /dev/null @@ -1,49 +0,0 @@ -include "mkfloppy.inc" -;// insert boot sect -file "fat1x/bootsect.bin", 512 - -; fat1 -db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0 -; fat2 -db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0 - -; root -dent kordldr, "KORDLDR F1X", FA_ARC -dent kord, "KORD ",FA_DIR -dent kolibri, "KOLIBRI ",FA_DIR -; ... - -rb 33*512-$ -;/////////////////////////// -defdir kord -{ -dent loader, "LOADER ", FA_ARC -dent ini,"STARTOS INI", FA_ARC -} - -defdir kolibri -{ -dent kolibri_ldm, "KOLIBRI LDM", FA_ARC -} - - -; data -stof kordldr, "fat1x/kordldr.f1x" -stod kord,root - -stof loader, "../loader" -stof ini,"../startos.ini" - -store dword ini_base/512+1 at ini_base+1F8h -store word (ini_size+511)/512-1 at ini_base+1FCh -store word 220h at ini_base+1FEh - -stod kolibri,root -stof kolibri_ldm, "../kolibri_ldm/bin/kolibri.ldm" -store dword kolibri_ldm_base/512+1 at kolibri_ldm_base+1F8h -store word (kolibri_ldm_size+511)/512-1 at kolibri_ldm_base+1FCh -store word 220h at kolibri_ldm_base+1FEh - - -; ... -rb 2*80*18*512-$ \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/mkfloppy.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/mkfloppy.inc deleted file mode 100644 index dc132164f6..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/mkfloppy.inc +++ /dev/null @@ -1,91 +0,0 @@ -; --------------------------------------------------------------------------- -; mkfloppy.inc -; --------------------------------------------------------------------------- -; Created by Phantom-84 -; --------------------------------------------------------------------------- - -FA_RO equ 01h -FA_HID equ 02h -FA_SYS equ 04h -FA_VOL equ 08h -FA_DIR equ 10h -FA_ARC equ 20h - -DSTAMP equ 28C1h -TSTAMP equ 6000h - -root_size=0 - -macro reset id -{ -local count, cur, disp, val, var -times 511-($+511) mod 512 db 0 -if id#_size>0 -count=(id#_size+511)/512 -cur=id#_base/512-(33-2) -repeat count -if %=count -val=0FFFh -else -val=cur+1 -end if -if cur and 1 -val=val shl 4 -end if -disp=(cur*3)/2 -load var word from 512+disp -var=var or val -store word var at 512+disp -store word var at 10*512+disp -cur=cur+1 -end repeat -end if -} - -macro dent id, name, attr -{ -@@ db name -times @b+11-$ db 32 -db attr -dw 0, TSTAMP, DSTAMP, DSTAMP, 0, TSTAMP, DSTAMP -if id#_size=0 -dw 0 -else -dw id#_base/512-(33-2) -end if -if (attr) and FA_DIR -dd 0 -else -dd id#_size -end if -} - -macro orgdir id, parentid -{ -id#_base: -dent id, ".", FA_DIR -dent parentid, "..", FA_DIR -} - -macro findir id -{ -id#_size=$-id#_base -reset id -} - -macro stod id, parentid -{ -orgdir id, parentid -id -findir id -} - -macro stof id, name -{ -id#_base: - file name -id#_size=$-id#_base -reset id -} - -defdir fix macro diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot_st.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot_st.inc deleted file mode 100644 index 3abf541a0e..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot_st.inc +++ /dev/null @@ -1,68 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -;====================================================================== -; -; BOOT DATA -; -;====================================================================== - - -version db 'Secondary Loader v 0.010',0 -version_end: - -select_section db 'Select section:' -select_section_end: -section_description db 'Section description:' -section_description_end: -soft_mes db 'Soft (c) 2008-2009' -soft_mes_end: - -badprocessor db '>Fatal - CPU 586+ required.',0 -error_ini_f1 db '>Error: cannot load ini file, buffer is full',0 -error_ini_f2 db '>Error: ini file not found',0 -error_ini_f3 db '>Error: cannot read ini file',0 -error_ini_nf db '>Error: unrecognized error when loading ini file',0 -not_found_sec_loader db '>Not found section [loader]',0 -not_found_def_sect db '>Not found value default in section [loader]',0 -default_eq_loader db '>Error in section [loader] parametr default=loader',0 -found_equal_default db '>Found equal parametr default will be use first value',0 -found_equal_timeout db '>Found equal parametr timeout will be use first value',0 -set_default_timeout_val db '>Section timeout has incorrect value, will be use default value',0 -error_ini_common db ">I will use predefined settings and try to boot. Let's hope for the best..." - db 13,10,"Press any key to continue...",0 -load_ini db '>Ini file loaded successfully',0 -parse_ini_end db '>End parsing ini file',0 -point_to_default_sec_not_found db '>Point to default section is not found in ini file',0 -incorect_section_define db ">Incorect section define not found ']'",0 -default_section_name db '"Section unname"' - -start_msg db "Press any key to change default section, press [Enter] to continue booting" -start_msg_e: -time_msg db "or wait 4 seconds before default continuation" -time_msg_e: -time_str db "seconds before default continuation" -time_str_e: diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/build_ru.bat b/kernel/branches/Kolibri-acpi/sec_loader/trunk/build_ru.bat deleted file mode 100644 index e326deed73..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/build_ru.bat +++ /dev/null @@ -1,4 +0,0 @@ -@fasm -m 65535 loader.asm loader -@echo off -REM @fasm -m 65535 loader.asm loader > loader.lst -REM @pause \ No newline at end of file diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/debug_msg.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/debug_msg.inc deleted file mode 100644 index a0d8dff676..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/debug_msg.inc +++ /dev/null @@ -1,77 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -;Тут определены все сообщения, которые нужны в процессе отладки, и совсем не нужны в рабочей копии программы. -If DEBUG -cseg_msg db ' - Adress of code segment',0 -stack_msg db 'Set stack & segments is have completed',0 -show_string db 'Have loaded size:' -show_decode db ' ',0 -show_db1 db ' -Message debug1',0 -show_db2 db ' -Message debug2',0 - - -lm_l_found db '[loader] is found',0 -lm_lf_timeout db 'timeout is found',0 -lm_lf_default db 'name default is found and end parsing section',0 -lm_lf_section db 'found section [',0 -lm_lf_default_f db 'found default parametr',0 -lm_l_end db 'section [loader] is end',0 -show_all_sect db 'SHOW ALL Sections',0 -no_show_only_w db 'Not show sections - only work on default sect',0 -_not_found db '[ not found',0 -_found_1 db '[] found',0 -_found_2 db '[ found',0 -say_hello db 'Hello $)',0 -ramdiskFS_st db 'Start use_RamdiskFS macros',0 -free_memory_msg db ' -Kb availability system free memory',0 -RamdiskSize_msg db ' -Kb equal RamdiskSize',0 -RamdiskSector_msg db ' -byts RamdiskSector',0 -RamdiskCluster_msg db ' -RamdiskCluster',0 -RamdiskFile_msg db ' -size RamdiskFile',0 -fat_create_msg db ' -first create fat table, point to next block',0 -BPB_msg db ' -in byte, why we get data from move BPB struct',0 -firstDataSect_msg db ' -first data sector, offset to data in sectors',0 -size_root_dir_msg db ' -size root dir in sectrors',0 -DataClasters_msg db ' -size data in Clasters',0 -first_entry_in_fat db ' -data segment in FIRST entry FAT',0 -check_root_fat_ db ' : --------------',0 -check_name_fat_msg_y db 'Name is present that is BAD',0 -check_name_fat_msg_n db 'Name is not present that is GOOD',0 -name_of_seg_get_64 db ' -name of seg where we get 64 Kb of data',0 -convertion_file_name_msg_y db '->Destination name of file is GOOD',0 -convertion_file_name_msg_n db '->Destination name of file is BAD',0 -alarm_msg db '%%%%%%%% WARNING: MISS THE FILE %%%%%%%%%%%',0 -start_making_FAT12_msg db '>>>>>> Begin make a RAMDISK and FS after 1 Mb <<<<<<<',0 -make_fat12_RFS_msg db '-Make FAT12 Ram FS',0 -get_type_FS_msg db '-End make RamDisk',0 -seg_where_get_data db ' - Segment where we get data for move up file',0 -return_code_af_move db ' -return code after 0x87 int 0x15, move block',0 -return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc',0 - - - -end if diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/listing.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/listing.inc deleted file mode 100644 index faf2e09bc9..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/listing.inc +++ /dev/null @@ -1,635 +0,0 @@ -; Listing generator -; LocoDelAssembly 2007.06.01 - -INSTRUCTIONS equ bt in ja jb jc je jg jl jo jp js jz or \ - aaa aad aam aas adc add and bsf bsr btc btr bts cbw cdq clc \ - cld cli cmc cmp cqo cwd daa das dec div fld fst hlt inc ins \ - int jae jbe jge jle jmp jna jnb jnc jne jng jnl jno jnp jns \ - jnz jpe jpo lar lds lea les lfs lgs lsl lss ltr mov mul neg \ - nop not out pop por rcl rcr ret rol ror rsm sal sar sbb shl \ - shr stc std sti str sub ud2 xor \ - arpl call cdqe clgi clts cmps cwde emms fabs fadd fbld fchs \ - fcom fcos fdiv feni fild fist fld1 fldz fmul fnop fsin fstp \ - fsub ftst fxam fxch idiv imul insb insd insw int1 int3 into \ - invd iret jcxz jnae jnbe jnge jnle lahf lgdt lidt lldt lmsw \ - lods loop movd movq movs orpd orps outs pand popa popd popf \ - popq popw push pxor retd retf retn retq retw sahf salc scas \ - seta setb setc sete setg setl seto setp sets setz sgdt shld \ - shrd sidt sldt smsw stgi stos test verr verw wait xadd xchg \ - xlat \ - addpd addps addsd addss andpd andps bound bswap cmova cmovb \ - cmovc cmove cmovg cmovl cmovo cmovp cmovs cmovz cmppd cmpps \ - cmpsb cmpsd cmpsq cmpss cmpsw cpuid divpd divps divsd divss \ - enter f2xm1 faddp fbstp fclex fcomi fcomp fdisi fdivp fdivr \ - femms ffree fiadd ficom fidiv fimul finit fistp fisub fldcw \ - fldpi fmulp fneni fprem fptan fsave fsqrt fstcw fstsw fsubp \ - fsubr fucom fwait fyl2x icebp iretd iretq iretw jecxz jrcxz \ - lddqu leave lodsb lodsd lodsq lodsw loopd loope loopq loopw \ - loopz maxpd maxps maxsd maxss minpd minps minsd minss movsb \ - movsd movsq movss movsw movsx movzx mulpd mulps mulsd mulss \ - mwait outsb outsd outsw pabsb pabsd pabsw paddb paddd paddq \ - paddw pandn pause pavgb pavgw pf2id pf2iw pfacc pfadd pfmax \ - pfmin pfmul pfrcp pfsub pi2fd pi2fw popad popaw popfd popfq \ - popfw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb \ - psubd psubq psubw pusha pushd pushf pushq pushw rcpps rcpss \ - rdmsr rdpmc rdtsc retfd retfq retfw retnd retnq retnw scasb \ - scasd scasq scasw setae setbe setge setle setna setnb setnc \ - setne setng setnl setno setnp setns setnz setpe setpo stosb \ - stosd stosq stosw subpd subps subsd subss vmrun vmxon wrmsr \ - xlatb xorpd xorps \ - andnpd andnps cmovae cmovbe cmovge cmovle cmovna cmovnb cmovnc\ - cmovne cmovng cmovnl cmovno cmovnp cmovns cmovnz cmovpe cmovpo\ - comisd comiss fcmovb fcmove fcmovu fcomip fcompp fdivrp ffreep\ - ficomp fidivr fisttp fisubr fldenv fldl2e fldl2t fldlg2 fldln2\ - fnclex fndisi fninit fnsave fnstcw fnstsw fpatan fprem1 frstor\ - frstpm fscale fsetpm fstenv fsubrp fucomi fucomp fxsave haddpd\ - haddps hsubpd hsubps invlpg lfence looped loopeq loopew loopne\ - loopnz loopzd loopzq loopzw mfence movapd movaps movdqa movdqu\ - movhpd movhps movlpd movlps movnti movntq movsxd movupd movups\ - paddsb paddsw pextrw pfnacc pfsubr phaddd phaddw phsubd phsubw\ - pinsrw pmaxsw pmaxub pminsw pminub pmulhw pmullw psadbw pshufb\ - pshufd pshufw psignb psignd psignw pslldq psrldq psubsb psubsw\ - pswapd pushad pushaw pushfd pushfq pushfw rdmsrq rdtscp setalc\ - setnae setnbe setnge setnle sfence shufpd shufps skinit sqrtpd\ - sqrtps sqrtsd sqrtss swapgs sysret vmcall vmload vmread vmsave\ - vmxoff wbinvd wrmsrq \ - clflush cmovnae cmovnbe cmovnge cmovnle cmpeqpd cmpeqps \ - cmpeqsd cmpeqss cmplepd cmpleps cmplesd cmpless cmpltpd \ - cmpltps cmpltsd cmpltss cmpxchg fcmovbe fcmovnb fcmovne \ - fcmovnu fdecstp fincstp fnstenv frndint fsincos fucomip \ - fucompp fxrstor fxtract fyl2xp1 invlpga ldmxcsr loopned \ - loopneq loopnew loopnzd loopnzq loopnzw monitor movddup \ - movdq2q movhlps movlhps movntdq movntpd movntps movq2dq \ - paddusb paddusw palignr pavgusb pcmpeqb pcmpeqd pcmpeqw \ - pcmpgtb pcmpgtd pcmpgtw pfcmpeq pfcmpge pfcmpgt pfpnacc \ - pfrsqrt phaddsw phsubsw pmaddwd pmulhrw pmulhuw pmuludq \ - pshufhw pshuflw psubusb psubusw rsqrtps rsqrtss stmxcsr \ - syscall sysexit sysretq ucomisd ucomiss vmclear vmmcall \ - vmptrld vmptrst vmwrite \ - addsubpd addsubps cmpneqpd cmpneqps cmpneqsd cmpneqss cmpnlepd\ - cmpnleps cmpnlesd cmpnless cmpnltpd cmpnltps cmpnltsd cmpnltss\ - cmpordpd cmpordps cmpordsd cmpordss cvtdq2pd cvtdq2ps cvtpd2dq\ - cvtpd2pi cvtpd2ps cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi\ - cvtsd2si cvtsd2ss cvtsi2sd cvtsi2ss cvtss2sd cvtss2si fcmovnbe\ - maskmovq movmskpd movmskps movshdup movsldup packssdw packsswb\ - packuswb pfrcpit1 pfrcpit2 pfrsqit1 pmovmskb pmulhrsw prefetch\ - sysenter sysexitq unpckhpd unpckhps unpcklpd unpcklps vmlaunch\ - vmresume \ - cmpxchg8b cvttpd2dq cvttpd2pi cvttps2dq cvttps2pi cvttsd2si \ - cvttss2si pmaddubsw prefetchw punpckhbw punpckhdq punpckhwd \ - punpcklbw punpckldq punpcklwd \ - cmpunordpd cmpunordps cmpunordsd cmpunordss cmpxchg16b \ - loadall286 loadall386 maskmovdqu prefetcht0 prefetcht1 \ - prefetcht2 punpckhqdq punpcklqdq prefetchnta - -PREFIXES equ rep lock repe repz repne repnz - -DATA_DEFINITORS equ db dw du dd dp df dq dt file -DATA_RESERVERS equ rb rw rd rp rf rq rt - -CRLF equ 13, 10 ; Remove 13 for Linux -MAX_BYTES equ 13 - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODE MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -macro use16 -{ -use16 - _USE = 16 -} - -macro use32 -{ -use32 - _USE = 32 -} - -macro use64 -{ -use64 - _USE = 64 -} - -macro detect_mode -{ -local aux - - _USE = 32 - - virtual at 0 - xchg eax, eax - load aux byte from 0 - - if aux = $66 - _USE = 16 - else if aux = $87 - _USE = 64 - end if - end virtual -} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAYING MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -macro display_address address* -{ -local aux, digit - - aux = address - - repeat _USE / 4 - digit = aux shr (_USE - 4 * %) and $F - - display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F - end repeat - - display ': ' -} - -macro display_bytes pointer -{ -local aux, size, digit - - size = $ - pointer - - if size > MAX_BYTES - size = MAX_BYTES - end if - - repeat size - load aux byte from pointer+%-1 - - digit = aux shr 4 - display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F - - digit = aux and $F - display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F - - - display ' ' - end repeat - - repeat MAX_BYTES - size - display ' ' - end repeat -} - -; The macro below in some situations doesn't adds a space to separate things unfortunatelly, so for readability ensurance -; another one will be used instead... -;macro display_args [args] -;{ -;common -; aux = 1 -; -;forward -; if ~args eq -; if aux -; display ' ' -; else -; display ', ' -; end if -; -; aux = 0 -; -; match =ON, _RESOLVE_EQUATES -; \{ -; match args, args -; \\{ -; irps arg, args -; \\\{ -; display \\\`arg -; \\\} -; \\} -; \} -; match =OFF, _RESOLVE_EQUATES -; \{ -; irps arg, args -; \\{ -; display \\`arg -; \\} -; -; \} -; end if -;} - -; This one separates everything with one space. A very ugly listing but at least you will not see things -; like "push ebxesiedi" nor "ret word0" - -macro display_args [args] -{ -common - aux = 1 - -forward - if ~args eq - if ~aux - display ',' - end if - - aux = 0 - - match =ON, _RESOLVE_EQUATES - \{ - match args, args - \\{ - if ~args eqtype "" - irps arg, args - \\\{ - display ' ', \\\`arg - \\\} - else - display " '", args, "'" - end if - \\} - \} - match =OFF, _RESOLVE_EQUATES - \{ - if ~args eqtype "" - irps arg, args - \\{ - display ' ', \\`arg - \\} - else - display " '", args, "'" - end if - \} - end if -} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;; INSTRUCTIONS & PREFIXES MACROSES ;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -macro prefix mnemonic -{ -local aux - - macro mnemonic [args] - \{ - \common - match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} - match =equ, args\\{_LISTING equ 0\\} - match =equ any, args\\{_LISTING equ 0\\} - - match =1, _LISTING - \\{ - display_address $ - aux = $ - \\} - - mnemonic - - match =1, _LISTING - \\{ - display_bytes aux - - display \`mnemonic - display CRLF - \\} - - match =1, _ON_VIRTUAL\\{restore _LISTING\\} - match =equ, args\\{restore _LISTING\\} - match =equ any, args\\{restore _LISTING\\} - - def_prefix mnemonic - args - purge mnemonic - \} -} - -macro def_prefix mnemonic -{ - macro def_prefix mnemonic - \{ - prefix mnemonic - \} - def_prefix mnemonic -} - -macro instruction mnemonic -{ -local aux - - macro mnemonic [args] - \{ - \common - match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} - match =equ, args\\{_LISTING equ 0\\} - match =equ any, args\\{_LISTING equ 0\\} - - match =1, _LISTING - \\{ - display_address $ - aux = $ - \\} - - mnemonic args - - match =1, _LISTING - \\{ - display_bytes aux - - display \`mnemonic - - virtual at 0 - db \`mnemonic - repeat 11 - $ - display ' ' - end repeat - end virtual - - display_args args - display CRLF - \\} - - match =1, _ON_VIRTUAL\\{restore _LISTING\\} - match =equ, args\\{restore _LISTING\\} - match =equ any, args\\{restore _LISTING\\} - \} -} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -macro data_define mnemonic -{ -local aux - macro mnemonic [args] - \{ - \common - match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} - match =equ, args\\{_LISTING equ 0\\} - match =equ any, args\\{_LISTING equ 0\\} - - match =1, _LISTING - \\{ - display_address $ - aux = $ - \\} - - mnemonic args - - match =1, _LISTING - \\{ - display_bytes aux - - display \`mnemonic - - display_args args - display CRLF - - aux = aux + MAX_BYTES - - repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES - display_address aux - display_bytes aux - display CRLF - - aux = aux + MAX_BYTES - end repeat - \\} - - match =1, _ON_VIRTUAL\\{restore _LISTING\\} - match =equ, args\\{restore _LISTING\\} - match =equ any, args\\{restore _LISTING\\} - \} - - struc mnemonic [args] - \{ - \common - match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} - match =equ, args\\{_LISTING equ 0\\} - match =equ any, args\\{_LISTING equ 0\\} - - match =1, _LISTING - \\{ - display_address $ - aux = $ - \\} - - . mnemonic args - - match =1, _LISTING - \\{ - display_bytes aux - - display \`., ' ', \`mnemonic - - display_args args - display CRLF - - aux = aux + MAX_BYTES - - repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES - display_address aux - display_bytes aux - display CRLF - - aux = aux + MAX_BYTES - end repeat - \\} - - match =1, _ON_VIRTUAL\\{restore _LISTING\\} - match =equ, args\\{restore _LISTING\\} - match =equ any, args\\{restore _LISTING\\} - \} -} - -macro data_reserve mnemonic -{ -local aux - macro mnemonic [args] - \{ - \common - match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} - match =equ, args\\{_LISTING equ 0\\} - match =equ any, args\\{_LISTING equ 0\\} - - match =1, _LISTING - \\{ - display_address $ - aux = $ - \\} - - mnemonic args - - match =1, _LISTING - \\{ - times MAX_BYTES display ' ' - - display \`mnemonic - - display_args args - display CRLF - \\} - - match =1, _ON_VIRTUAL\\{restore _LISTING\\} - match =equ, args\\{restore _LISTING\\} - match =equ any, args\\{restore _LISTING\\} - \} - - struc mnemonic [args] - \{ - \common - match =1, _ON_VIRTUAL\\{_LISTING equ 0\\} - match =equ, args\\{_LISTING equ 0\\} - match =equ any, args\\{_LISTING equ 0\\} - - match =1, _LISTING - \\{ - display_address $ - aux = $ - \\} - - . mnemonic args - - match =1, _LISTING - \\{ - times MAX_BYTES display ' ' - - display \`., ' ', \`mnemonic - - display_args args - display CRLF - \\} - - match =1, _ON_VIRTUAL\\{restore _LISTING\\} - match =equ, args\\{restore _LISTING\\} - match =equ any, args\\{restore _LISTING\\} - \} -} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;; LISTING CONTROL MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -macro virtual [args] -{ -common - _ON_VIRTUAL equ 1 - - virtual args -} - -macro end [args] -{ -common - match =virtual, args\{restore _ON_VIRTUAL\} - - end args -} - -macro enable_listing -{ - detect_mode - - match =0, _MACROSES_INSTALLED - \{ - match instructions, INSTRUCTIONS - \\{ - irps ins, instructions - \\\{ - instruction ins - \\\} - \\} - - match prefixes, PREFIXES - \\{ - irps prefix, prefixes - \\\{ - def_prefix prefix - \\\} - \\} - - match data_definitors, DATA_DEFINITORS - \\{ - irps def, data_definitors - \\\{ - data_define def - \\\} - \\} - - match data_reservers, DATA_RESERVERS - \\{ - irps def, data_reservers - \\\{ - data_reserve def - \\\} - \\} - \} - - _MACROSES_INSTALLED equ 1 - _LISTING equ 1 -} - -macro disable_listing -{ - _LISTING equ 0 -} - -macro enable [feature*] -{ -forward - UNKNOWN equ 1 - - match =resolve_equates, feature - \{ - restore _RESOLVE_EQUATES - _RESOLVE_EQUATES equ ON - UNKNOWN equ 0 - \} - - match =listing, feature - \{ - enable_listing - UNKNOWN equ 0 - \} - - match =1, UNKNOWN - \{ - display 'ERROR: Unknown "',`feature, '" feature', 13, 10 - err - \} - - restore UNKNOWN - restore UNKNOWN -} - -macro disable [feature*] -{ - UNKNOWN equ 1 - - match =resolve_equates, feature - \{ - restore _RESOLVE_EQUATES - _RESOLVE_EQUATES equ OFF - UNKNOWN equ 0 - \} - - match =listing, feature - \{ - disable_listing - UNKNOWN equ 0 - \} - - match =1, UNKNOWN - \{ - display 'ERROR: Unknown "',`feature, '" feature', 13, 10 - err - \} - - restore UNKNOWN - restore UNKNOWN -} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -_MACROSES_INSTALLED equ 0 -_ON_VIRTUAL equ 0 - -disable resolve_equates diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.asm b/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.asm deleted file mode 100644 index 4489ac94c0..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.asm +++ /dev/null @@ -1,317 +0,0 @@ -; Copyright (c) 2008-2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -;start of the project 13.02.2008 year. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;Secondary Loader copyright Alexey Teplov nickname -;if you need log preproc -;///////////// -;include 'listing.inc' -;enable listing -;//////////// -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;start of code: ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -use16 - org 0x0 - jmp start -include 'sl_equ.inc' ; в файле размещены все equ предопределения -include 'boot_st.inc' -include 'debug_msg.inc' ;here is message from debug -include 'parse_dat.inc' -include 'sl_proc.inc' -include 'parse.inc' -include 'parse_loader.inc' -include 'parse_any.inc' -include 'parse_def_sect.inc' -include 'parse_err.inc' - -file_data dw 0x0,ini_data_ ;формат: смещение: сегмент т.к. используется les -size_data dw 16 ;16 блоков по 4 кб т.е предел до 64 кб -name_ini_f db 'kord/startos.ini',0 - -;//////////// -loader_callback dd ? -load_drive dw ? -load_ft dw ? -;Start code - -start: -; Save far pointer to callback procedure, ds:si is point - mov word [cs:loader_callback], si - mov word [cs:loader_callback+2], ds -; Save type of drive - mov word [cs:load_drive], ax -; Save type of FT - mov word [cs:load_ft], bx -; set up stack - mov ax, cs - mov ss, ax - xor sp, sp -; set up segment registers - mov ds, ax - mov es, ax -; just to be sure: force DF=0, IF=1 - cld - sti - -; set videomode - mov ax, 3 - int 0x10 - - mov si, version - call printplain - mov al, '#' - mov cx, 80 -;input cx=size al=char будет вывден символ сколько раз указано в cx -@@: - call putchar - loop @b - - if DEBUG - pushad - mov ax, cs - shl eax, 4 ; в десятичной системе адрес сегмента - mov cx, 0xa - mov di, cseg_msg - call decode -;*************** - mov si, cseg_msg - call printplain - popad - end if - - - if DEBUG - mov si, stack_msg - call printplain - end if - -; Require 586 or higher processor (cpuid and rdtsc,rdmsr/wrmsr commands) -; install int 6 (#UD) handler - xor bx, bx - mov ds, bx - push word [bx+6*4+2] - push word [bx+6*4] - mov word [bx+6*4], ud16 - mov word [bx+6*4+2], cs -; issue CPUID command - xor eax, eax ; N.B.: will cause #UD before 386 - cpuid ; N.B.: will cause #UD before later 486s - test eax, eax - jz cpubad -; get processor features - xor eax, eax - inc ax - cpuid - test dl, 10h ; CPUID[1].edx[4] - TSC support - jz cpubad - test dl, 20h ; CPUID[1].edx[5] - MSR support - jnz cpugood - -ud16: ; #UD handler, called if processor did not recognize some commands -cpubad: -; restore int 6 (#UD) handler - pop word [6*4] - pop word [6*4+2] -; say error - push cs - pop ds - mov si, badprocessor -sayerr: - call printplain - jmp $ - -cpugood: -; restore int 6 (#UD) handler - pop dword [6*4] - push cs - pop ds - -; set up esp - movzx esp, sp - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; init memory -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - - -; Load startos.ini - mov cx, loop_read_startos_file ;кол-во попыток чтения файла конфигурации startos.ini -align 4 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Load startos.ini ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -load_startos_file: - - xor ax, ax - mov di, file_data - inc ax ;function 1 - read file - push cx - call far dword [loader_callback] - pop cx - push cs - push cs - pop ds - pop es - - test bx, bx - jz check_conf_file - dec cx - jnz load_startos_file - -;SET DEFAULT Not use ini file -error_ini: - mov si, error_ini_f1 ;Error: cannot load ini file, buffer is full - dec bx - jz err_show_ini - mov si, error_ini_f2 ;Error: ini file not found - dec bx - jz err_show_ini - mov si, error_ini_f3 ;Error: cannot read ini file - dec bx - jz err_show_ini - - mov si, error_ini_nf ;Error: unrecognized error when loading ini file -err_show_ini: - call printplain - mov si, error_ini_common - call printplain -; wait for keypress - xor ax, ax - int 16h - -ini_loaded: - - jmp $ - -align 4 -check_conf_file: -;Check config file in current dir - push ax ;save size file - if DEBUG - mov cx, 0x0a - mov di, show_decode - call decode -;Show size - mov si, show_string - call printplain - end if - - -;Show message - mov si, load_ini - call printplain - - pop cx ;restore size file -use_parse ;parsing startos.ini -; - jmp ini_loaded - -;;;;;;;;;;;;;;;;;;;;;;;;;;; -;DATA -;;;;;;;;;;;;;;;;;;;;;;;;;;; -; table for move to extended memory (int 15h, ah=87h) -align 4 -table_15_87: - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - - db 0xff,0xff - db 0x0,0x10 - db 0x00,0x93,0x0,0x0 - - db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 - - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 - -fat12_buffer: -.BS_jmpBoot db 0x90,0x90,0x90 ;3 байта NOP инструкция - ничего не делать -.BS_OEMName db 'K SyS 64' ;8 байт -.BPB_BytsPerSec dw 512 ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта -.BPB_SecPerClus db 0x1 ;кол-во секторов в кластере -.BPB_RsvdSecCnt dw 0x1 ;для FAt12/16 только 1, для FAT32 обычно 32 -.BPB_NumFATs db 0x1 ;кол-во фат таблиц, на тот случай если будет сброс на дискету образа рам диска -.BPB_RootEntCnt dw 512 ;для мак совместимости с fat16 -.BPB_TotSec16 dw 0x0 ;кл-во секторов -.BPB_Media db 0xF0 -.BPB_FATSz16 dw 0x0 -.BPB_SecPerTrk dw 0x0 ;содержит геометрию диска для RAMFS на как бы без разницы, пока пустое поле, позже внести реальные значения. -.BPB_NumHeads dw 0x0 -.BPB_HiddSec dd 0x0 ;кол-во скрытых секторов -.BPB_TotSec32 dd 0x0 -.BS_DrvNum db 'R' ;от слова RAM -.BS_Reserved1 db 0x0 -.BS_BootSig db 0x29 -.BS_VolID db 'RFKS' -.BS_VolLab db 'RAM DISK FS' ;11 символов -.BS_FilSysType db 'FAT12 ' ;8 символов -;62 байта структура fat12. -db (512-($-fat12_buffer))dup(0x90) - - - -;структура для дирректории fat -struc FAT_32_entry ;Byte Directory Entry Structure -{ -.DIR_Name rb 11 -.DIR_Attr db ? -.DIR_NTRes db ? -.DIR_CrtTimeTenth db ? -.DIR_CrtTime dw ? -.DIR_CrtDate dw ? -.DIR_LstAccDate dw ? -.DIR_FstClusHI dw ? -.DIR_WrtTime dw ? -.DIR_WrtDate dw ? -.DIR_FstClusLO dw ? -.DIR_FileSize dd ? - - -} -;Тут будут распологатсья данные, которые затруднительно распологать в стековой области.... -;;; -;timer -shot_name_fat rb 11 ;временный буфер для fat12, в нем храняться имена файлов приведенные к правилам FAT /* вдальнейшем перенести в стэк - -if DEBUG - rb 1 ;нужен для отладки и вывода имени файла после преобразования -dest_name_fat db 24 dup('_');12 -db 0x0 -end if - -value_timeout rw 1 ;value to timeout -old_timer rd 1 ;старое значение вектора таймера -start_timer rd 1 ;значение таймера -timer_ rd 1 ;новое значение вектора таймера т.е. SL -start_stack rw 1 ;save stack -save_bp_from_timer rw 1 ;save bp from timer - diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.lst b/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.lst deleted file mode 100644 index e3e51fc987..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.lst +++ /dev/null @@ -1,2147 +0,0 @@ -flat assembler version 1.68 (65535 kilobytes memory) -0000: E9 E1 0A jmp start -0003: 53 65 63 6F 6E 64 61 72 79 20 4C 6F 61 version db 'Secondary Loader v 0.009', 0 -0010: 64 65 72 20 76 20 30 2E 30 30 39 00 -001C: 53 65 6C 65 63 74 20 73 65 63 74 69 6F select_section db 'Select section:' -0029: 6E 3A -002B: 53 65 63 74 69 6F 6E 20 64 65 73 63 72 section_description db 'Section description:' -0038: 69 70 74 69 6F 6E 3A -003F: 53 6F 66 74 20 28 63 29 20 32 30 30 38 soft_mes db 'Soft (c) 2008' -004C: 3E 46 61 74 61 6C 20 2D 20 43 50 55 20 badprocessor db '>Fatal - CPU 586+ required.', 0 -0059: 35 38 36 2B 20 72 65 71 75 69 72 65 64 -0066: 2E 00 -0068: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f1 db '>Error: cannot load ini file, buffer is full', 0 -0075: 74 20 6C 6F 61 64 20 69 6E 69 20 66 69 -0082: 6C 65 2C 20 62 75 66 66 65 72 20 69 73 -008F: 20 66 75 6C 6C 00 -0095: 3E 45 72 72 6F 72 3A 20 69 6E 69 20 66 error_ini_f2 db '>Error: ini file not found', 0 -00A2: 69 6C 65 20 6E 6F 74 20 66 6F 75 6E 64 -00AF: 00 -00B0: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f3 db '>Error: cannot read ini file', 0 -00BD: 74 20 72 65 61 64 20 69 6E 69 20 66 69 -00CA: 6C 65 00 -00CD: 3E 45 72 72 6F 72 3A 20 75 6E 72 65 63 error_ini_nf db '>Error: unrecognized error when loading ini file', 0 -00DA: 6F 67 6E 69 7A 65 64 20 65 72 72 6F 72 -00E7: 20 77 68 65 6E 20 6C 6F 61 64 69 6E 67 -00F4: 20 69 6E 69 20 66 69 6C 65 00 -00FE: 3E 4E 6F 74 20 66 6F 75 6E 64 20 73 65 not_found_sec_loader db '>Not found section [loader]', 0 -010B: 63 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 -0118: 5D 00 -011A: 3E 4E 6F 74 20 66 6F 75 6E 64 20 76 61 not_found_def_sect db '>Not found value default in section [loader]', 0 -0127: 6C 75 65 20 64 65 66 61 75 6C 74 20 69 -0134: 6E 20 73 65 63 74 69 6F 6E 20 5B 6C 6F -0141: 61 64 65 72 5D 00 -0147: 3E 45 72 72 6F 72 20 69 6E 20 73 65 63 default_eq_loader db '>Error in section [loader] parametr default=loader', 0 -0154: 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 5D -0161: 20 70 61 72 61 6D 65 74 72 20 64 65 66 -016E: 61 75 6C 74 3D 6C 6F 61 64 65 72 00 -017A: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_default db '>Found equal parametr default will be use first value', 0 -0187: 70 61 72 61 6D 65 74 72 20 64 65 66 61 -0194: 75 6C 74 20 77 69 6C 6C 20 62 65 20 75 -01A1: 73 65 20 66 69 72 73 74 20 76 61 6C 75 -01AE: 65 00 -01B0: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_timeout db '>Found equal parametr timeout will be use first value', 0 -01BD: 70 61 72 61 6D 65 74 72 20 74 69 6D 65 -01CA: 6F 75 74 20 77 69 6C 6C 20 62 65 20 75 -01D7: 73 65 20 66 69 72 73 74 20 76 61 6C 75 -01E4: 65 00 -01E6: 3E 53 65 63 74 69 6F 6E 20 74 69 6D 65 set_default_timeout_val db '>Section timeout has incorrect value, will be use default value', 0 -01F3: 6F 75 74 20 68 61 73 20 69 6E 63 6F 72 -0200: 72 65 63 74 20 76 61 6C 75 65 2C 20 77 -020D: 69 6C 6C 20 62 65 20 75 73 65 20 64 65 -021A: 66 61 75 6C 74 20 76 61 6C 75 65 00 -0226: 3E 49 20 77 69 6C 6C 20 75 73 65 20 70 error_ini_common db '>I will use predefined settings and try to boot. Let's hope for the best...' -0233: 72 65 64 65 66 69 6E 65 64 20 73 65 74 -0240: 74 69 6E 67 73 20 61 6E 64 20 74 72 79 -024D: 20 74 6F 20 62 6F 6F 74 2E 20 4C 65 74 -025A: 27 73 20 68 6F 70 65 20 66 6F 72 20 74 -0267: 68 65 20 62 65 73 74 2E 2E 2E -0271: 0D 0A 50 72 65 73 73 20 61 6E 79 20 6B db 13, 10, 'Press any key to continue...', 0 -027E: 65 79 20 74 6F 20 63 6F 6E 74 69 6E 75 -028B: 65 2E 2E 2E 00 -0290: 3E 49 6E 69 20 66 69 6C 65 20 6C 6F 61 load_ini db '>Ini file loaded successfully', 0 -029D: 64 65 64 20 73 75 63 63 65 73 73 66 75 -02AA: 6C 6C 79 00 -02AE: 3E 45 6E 64 20 70 61 72 73 69 6E 67 20 parse_ini_end db '>End parsing ini file', 0 -02BB: 69 6E 69 20 66 69 6C 65 00 -02C4: 3E 50 6F 69 6E 74 20 74 6F 20 64 65 66 point_to_default_sec_not_found db '>Point to default section is not found in ini file', 0 -02D1: 61 75 6C 74 20 73 65 63 74 69 6F 6E 20 -02DE: 69 73 20 6E 6F 74 20 66 6F 75 6E 64 20 -02EB: 69 6E 20 69 6E 69 20 66 69 6C 65 00 -02F7: 3E 49 6E 63 6F 72 65 63 74 20 73 65 63 incorect_section_define db '>Incorect section define not found ']'', 0 -0304: 74 69 6F 6E 20 64 65 66 69 6E 65 20 6E -0311: 6F 74 20 66 6F 75 6E 64 20 27 5D 27 00 -031E: 22 53 65 63 74 69 6F 6E 20 75 6E 6E 61 default_section_name db '"Section unname"' -032B: 6D 65 22 -032E: 50 72 65 73 73 20 61 6E 79 20 6B 65 79 start_msg db 'Press any key to change default section, press [Enter] to continue booting' -033B: 20 74 6F 20 63 68 61 6E 67 65 20 64 65 -0348: 66 61 75 6C 74 20 73 65 63 74 69 6F 6E -0355: 2C 20 70 72 65 73 73 20 5B 45 6E 74 65 -0362: 72 5D 20 74 6F 20 63 6F 6E 74 69 6E 75 -036F: 65 20 62 6F 6F 74 69 6E 67 -0378: 6F 72 20 77 61 69 74 20 34 20 73 65 63 time_msg db 'or wait 4 seconds before default continuation' -0385: 6F 6E 64 73 20 62 65 66 6F 72 65 20 64 -0392: 65 66 61 75 6C 74 20 63 6F 6E 74 69 6E -039F: 75 61 74 69 6F 6E -03A5: 73 65 63 6F 6E 64 73 20 62 65 66 6F 72 time_str db 'seconds before default continuation' -03B2: 65 20 64 65 66 61 75 6C 74 20 63 6F 6E -03BF: 74 69 6E 75 61 74 69 6F 6E -03C8: 53 65 74 20 73 74 61 63 6B 20 26 20 73 stack_msg db 'Set stack & segments is have completed', 0 -03D5: 65 67 6D 65 6E 74 73 20 69 73 20 68 61 -03E2: 76 65 20 63 6F 6D 70 6C 65 74 65 64 00 -03EF: 48 61 76 65 20 6C 6F 61 64 65 64 20 73 show_string db 'Have loaded size:' -03FC: 69 7A 65 3A -0400: 20 20 20 20 20 20 00 show_decode db ' ', 0 -0407: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db1 db ' -Message debug1', 0 -0414: 67 65 20 64 65 62 75 67 31 00 -041E: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db2 db ' -Message debug2', 0 -042B: 67 65 20 64 65 62 75 67 32 00 -0435: 5B 6C 6F 61 64 65 72 5D 20 69 73 20 66 lm_l_found db '[loader] is found', 0 -0442: 6F 75 6E 64 00 -0447: 74 69 6D 65 6F 75 74 20 69 73 20 66 6F lm_lf_timeout db 'timeout is found', 0 -0454: 75 6E 64 00 -0458: 6E 61 6D 65 20 64 65 66 61 75 6C 74 20 lm_lf_default db 'name default is found and end parsing section', 0 -0465: 69 73 20 66 6F 75 6E 64 20 61 6E 64 20 -0472: 65 6E 64 20 70 61 72 73 69 6E 67 20 73 -047F: 65 63 74 69 6F 6E 00 -0486: 66 6F 75 6E 64 20 73 65 63 74 69 6F 6E lm_lf_section db 'found section [', 0 -0493: 20 5B 00 -0496: 66 6F 75 6E 64 20 64 65 66 61 75 6C 74 lm_lf_default_f db 'found default parametr', 0 -04A3: 20 70 61 72 61 6D 65 74 72 00 -04AD: 73 65 63 74 69 6F 6E 20 5B 6C 6F 61 64 lm_l_end db 'section [loader] is end', 0 -04BA: 65 72 5D 20 69 73 20 65 6E 64 00 -04C5: 53 48 4F 57 20 41 4C 4C 20 53 65 63 74 show_all_sect db 'SHOW ALL Sections', 0 -04D2: 69 6F 6E 73 00 -04D7: 4E 6F 74 20 73 68 6F 77 20 73 65 63 74 no_show_only_w db 'Not show sections - only work on default sect', 0 -04E4: 69 6F 6E 73 20 2D 20 6F 6E 6C 79 20 77 -04F1: 6F 72 6B 20 6F 6E 20 64 65 66 61 75 6C -04FE: 74 20 73 65 63 74 00 -0505: 5B 20 6E 6F 74 20 66 6F 75 6E 64 00 _not_found db '[ not found', 0 -0511: 5B 5D 20 66 6F 75 6E 64 00 _found_1 db '[] found', 0 -051A: 5B 20 66 6F 75 6E 64 00 _found_2 db '[ found', 0 -0522: 48 65 6C 6C 6F 20 24 29 00 say_hello db 'Hello $)', 0 -052B: 53 74 61 72 74 20 75 73 65 5F 52 61 6D ramdiskFS_st db 'Start use_RamdiskFS macros', 0 -0538: 64 69 73 6B 46 53 20 6D 61 63 72 6F 73 -0545: 00 -0546: 20 20 20 20 20 20 20 2D 4B 62 20 61 76 free_memory_msg db ' -Kb availability system free memory', 0 -0553: 61 69 6C 61 62 69 6C 69 74 79 20 73 79 -0560: 73 74 65 6D 20 66 72 65 65 20 6D 65 6D -056D: 6F 72 79 00 -0571: 20 20 20 20 20 20 20 2D 4B 62 20 65 71 RamdiskSize_msg db ' -Kb equal RamdiskSize', 0 -057E: 75 61 6C 20 52 61 6D 64 69 73 6B 53 69 -058B: 7A 65 00 -058E: 20 20 20 20 20 20 20 20 2D 62 79 74 73 RamdiskSector_msg db ' -byts RamdiskSector', 0 -059B: 20 52 61 6D 64 69 73 6B 53 65 63 74 6F -05A8: 72 00 -05AA: 20 20 20 20 20 20 20 2D 52 61 6D 64 69 RamdiskCluster_msg db ' -RamdiskCluster', 0 -05B7: 73 6B 43 6C 75 73 74 65 72 00 -05C1: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 RamdiskFile_msg db ' -size RamdiskFile', 0 -05CE: 52 61 6D 64 69 73 6B 46 69 6C 65 00 -05DA: 20 20 20 20 20 20 20 2D 66 69 72 73 74 fat_create_msg db ' -first create fat table, point to next block', 0 -05E7: 20 63 72 65 61 74 65 20 66 61 74 20 74 -05F4: 61 62 6C 65 2C 20 70 6F 69 6E 74 20 74 -0601: 6F 20 6E 65 78 74 20 62 6C 6F 63 6B 00 -060E: 20 20 20 20 20 20 20 2D 69 6E 20 62 79 BPB_msg db ' -in byte, why we get data from move BPB struct', 0 -061B: 74 65 2C 20 77 68 79 20 77 65 20 67 65 -0628: 74 20 64 61 74 61 20 66 72 6F 6D 20 6D -0635: 6F 76 65 20 42 50 42 20 73 74 72 75 63 -0642: 74 00 -0644: 20 20 20 20 20 20 20 2D 66 69 72 73 74 firstDataSect_msg db ' -first data sector, offset to data in sectors', 0 -0651: 20 64 61 74 61 20 73 65 63 74 6F 72 2C -065E: 20 6F 66 66 73 65 74 20 74 6F 20 64 61 -066B: 74 61 20 69 6E 20 73 65 63 74 6F 72 73 -0678: 00 -0679: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 size_root_dir_msg db ' -size root dir in sectrors', 0 -0686: 72 6F 6F 74 20 64 69 72 20 69 6E 20 73 -0693: 65 63 74 72 6F 72 73 00 -069B: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 DataClasters_msg db ' -size data in Clasters', 0 -06A8: 64 61 74 61 20 69 6E 20 43 6C 61 73 74 -06B5: 65 72 73 00 -06B9: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 check_name_fat_msg db ' -if -1 name is present, else 0 then not present name', 0 -06C6: 20 6E 61 6D 65 20 69 73 20 70 72 65 73 -06D3: 65 6E 74 2C 20 65 6C 73 65 20 30 20 74 -06E0: 68 65 6E 20 6E 6F 74 20 70 72 65 73 65 -06ED: 6E 74 20 6E 61 6D 65 00 -06F5: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 convertion_file_name_msg db ' -if -1, then destination name is bad', 0 -0702: 2C 20 74 68 65 6E 20 64 65 73 74 69 6E -070F: 61 74 69 6F 6E 20 6E 61 6D 65 20 69 73 -071C: 20 62 61 64 00 -0721: 2D 4D 61 6B 65 20 46 41 54 31 32 20 52 make_fat12_RFS_msg db '-Make FAT12 Ram FS', 0 -072E: 61 6D 20 46 53 00 -0734: 2D 45 6E 64 20 6D 61 6B 65 20 52 61 6D get_type_FS_msg db '-End make RamDisk', 0 -0741: 44 69 73 6B 00 -0746: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_move db ' -return code after 0x87 int 0x15, move block', 0 -0753: 6F 64 65 20 61 66 74 65 72 20 30 78 38 -0760: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D -076D: 6F 76 65 20 62 6C 6F 63 6B 00 -0777: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc', 0 -0784: 6F 64 65 20 61 66 74 65 72 20 30 78 38 -0791: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D -079E: 6F 76 65 20 66 61 74 20 73 74 72 75 63 -07AB: 00 -07AC: 5B 6C 6F 61 64 65 72 5D parse_loader db '[loader]' -07B4: 74 69 6D 65 6F 75 74 parse_l_timeout db 'timeout' -07BB: 64 65 66 61 75 6C 74 parse_l_default db 'default' -07C2: 61 6D 65 parse_name db 'ame' -07C5: 64 65 73 63 72 69 70 74 parse_descript db 'descript' -07CD: 4C 6F 61 64 65 72 4D 6F 64 75 6C 65 parse_LoaderModule db 'LoaderModule' -07D9: 52 61 6D 64 69 73 6B 53 69 7A 65 parse_RamdiskSize db 'RamdiskSize' -07E4: 52 61 6D 64 69 73 6B 46 53 parse_RamdiskFS db 'RamdiskFS' -07ED: 52 61 6D 64 69 73 6B 53 65 63 74 6F 72 parse_RamdiskSector db 'RamdiskSector' -07FA: 52 61 6D 64 69 73 6B 43 6C 75 73 74 65 parse_RamdiskCluster db 'RamdiskCluster' -0807: 72 -0808: 46 41 54 parse_RFS_FAT db 'FAT' -080B: 4B 52 46 53 parse_RFS_KRFS db 'KRFS' -080F: 4C 6F 61 64 65 72 49 6D 61 67 65 parse_Loader_Image db 'LoaderImage' -081A: 52 61 6D 64 69 73 6B 46 69 6C 65 parse_RamdiskFile db 'RamdiskFile' -0825: 66 39 C8 cmp eax, ecx -0828: 72 0D jb @f -082A: 66 31 D2 xor edx, edx -082D: 66 F7 F1 div ecx -0830: 66 52 push edx -0832: E8 F0 FF call decode -0835: 66 58 pop eax -0837: 0C 30 or al, 0x30 -0839: 88 05 mov [ ds : di ], al -083B: 47 inc di -083C: C3 ret -083D: B4 0E mov ah, 0Eh -083F: B7 00 mov bh, 0 -0841: CD 10 int 10h -0843: C3 ret -0844: 60 pusha -0845: AC lodsb -0846: E8 F4 FF call putchar -0849: AC lodsb -084A: 3C 00 cmp al, 0 -084C: 75 F8 jnz @b -084E: B0 0D mov al, 13 -0850: E8 EA FF call putchar -0853: B0 0A mov al, 10 -0855: E8 E5 FF call putchar -0858: 61 popa -0859: C3 ret -085A: B4 00 mov ah, 0 -085C: CD 16 int 16h -085E: 38 D8 cmp al, bl -0860: 72 F8 jb getkey -0862: 38 F8 cmp al, bh -0864: 77 F4 ja getkey -0866: 50 push ax -0867: E8 D3 FF call putchar -086A: 58 pop ax -086B: 83 E0 0F and ax, 0Fh -086E: 75 02 jnz @f -0870: B0 0A mov al, 10 -0872: C3 ret -0873: 26 8A 05 mov al, byte [ es : di ] -0876: 47 inc di -0877: 49 dec cx -0878: E3 20 jcxz .exit -087A: 3C 0A cmp al, 0xa -087C: 74 0A jz ._entry -087E: 3C 3B cmp al, ';' -0880: 75 F1 jnz .start -0882: B0 0A mov al, 0xa -0884: F2 repnz -0885: AE scasb -0886: E3 12 jcxz .exit -0888: 26 8A 05 mov al, byte [ es : di ] -088B: 3C 20 cmp al, ' ' -088D: 75 07 jnz .not_space -088F: F3 repe -0890: AE scasb -0891: 4F dec di -0892: 41 inc cx -0893: 26 8A 05 mov al, byte [ es : di ] -0896: 3C 3B cmp al, ';' -0898: 74 E8 jz .first_com -089A: C3 ret -089B: 56 push si -089C: 68 00 20 push ini_data_ -089F: 07 pop es -08A0: B0 5D mov al, ']' -08A2: F2 repnz -08A3: AE scasb -08A4: 85 C9 test cx, cx -08A6: 0F 84 0F 02 jz error.incorect_section_def -08AA: B0 6E mov al, 'n' -08AC: F2 repnz -08AD: AE scasb -08AE: E3 69 jcxz .not_name_sec_fb -08B0: BE C2 07 mov si, parse_name -08B3: 51 push cx -08B4: 57 push di -08B5: B9 03 00 mov cx, parse_name_e - parse_name -08B8: F3 repe -08B9: A6 cmpsb -08BA: 5F pop di -08BB: 59 pop cx -08BC: 74 02 jz .yaaa_find_value -08BE: EB EC jmp .find_val_name_fb -08C0: 83 E9 03 sub cx, parse_name_e - parse_name -08C3: 83 C7 03 add di, parse_name_e - parse_name -08C6: B8 20 3D mov ax, 0x3d20 -08C9: F3 repe -08CA: AE scasb -08CB: 85 C9 test cx, cx -08CD: 74 4A jz .not_name_sec_fb -08CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -08D3: 75 D5 jnz .find_val_name_fb1 -08D5: F3 repe -08D6: AE scasb -08D7: 41 inc cx -08D8: 4F dec di -08D9: 06 push es -08DA: 1F pop ds -08DB: 68 00 B8 push 0xb800 -08DE: 07 pop es -08DF: 31 C0 xor ax, ax -08E1: B8 20 07 mov ax, 0x0720 -08E4: B9 27 00 mov cx, 39 -08E7: 89 FE mov si, di -08E9: 89 D7 mov di, dx -08EB: 83 EF 02 sub di, 2 -08EE: F3 rep -08EF: AB stosw -08F0: 89 D7 mov di, dx -08F2: B4 0F mov ah, color_sym_white -08F4: B9 24 00 mov cx, 36 -08F7: AC lodsb -08F8: 83 EF 02 sub di, 2 -08FB: 3C 22 cmp al, '"' -08FD: 74 04 jz @f -08FF: 3C 27 cmp al, ''' -0901: 75 12 jnz .end_sh_name_sec -0903: AC lodsb -0904: AB stosw -0905: AC lodsb -0906: 3C 22 cmp al, '"' -0908: 74 0B jz .end_sh_name_sec -090A: 3C 27 cmp al, ''' -090C: 74 07 jz .end_sh_name_sec -090E: E2 F4 loop @b -0910: B0 7D mov al, '}' -0912: B4 0E mov ah, color_sym_yellow -0914: AB stosw -0915: 0E push cs -0916: 1F pop ds -0917: 5E pop si -0918: C3 ret -0919: 0E push cs -091A: 1F pop ds -091B: BF 1E 03 mov di, default_section_name -091E: EB BB jmp .def_sect_name -0920: 8B 7E F4 mov di, point_default -0923: 68 00 20 push ini_data_ -0926: 07 pop es -0927: 89 F9 mov cx, di -0929: 89 CB mov bx, cx -092B: FD std -092C: B0 0A mov al, 0xa -092E: F2 repnz -092F: AE scasb -0930: E3 25 jcxz .go_ -0932: 89 7E C6 mov find_sec_di, di -0935: 89 F9 mov cx, di -0937: 29 CB sub bx, cx -0939: 89 D9 mov cx, bx -093B: FC cld -093C: E8 34 FF call get_firs_sym -093F: E3 0D jcxz ._not_section -0941: 3B 7E F6 cmp di, point_loader -0944: 74 08 jz ._not_section -0946: 3C 5B cmp al, '[' -0948: 75 04 jnz ._not_section -094A: 89 7E F4 mov point_default, di -094D: C3 ret -094E: 8B 7E C6 mov di, find_sec_di -0951: 89 F9 mov cx, di -0953: 89 CB mov bx, cx -0955: EB D4 jmp .find_start_section -0957: FC cld -0958: 89 D9 mov cx, bx -095A: 26 8A 05 mov al, byte [ es : di ] -095D: 68 6A 09 push word .f_go -0960: 3C 20 cmp al, ' ' -0962: 74 03 jz @f -0964: E9 2F FF jmp get_firs_sym.not_space -0967: E9 21 FF jmp get_firs_sym.first_sp -096A: E3 E1 jcxz .exit_scan_sect -096C: 3B 7E F6 cmp di, point_loader -096F: 74 DC jz .exit_scan_sect -0971: 3C 5B cmp al, '[' -0973: 75 D8 jnz .exit_scan_sect -0975: 89 7E F4 mov point_default, di -0978: C3 ret -0979: 8B 7E F4 mov di, point_default -097C: 68 00 20 push ini_data_ -097F: 07 pop es -0980: 8B 4E FE mov cx, save_cx -0983: 29 F9 sub cx, di -0985: EB 17 jmp .let_s_go -0987: 68 00 20 push ini_data_ -098A: 07 pop es -098B: 8B 4E FE mov cx, save_cx -098E: 26 8A 05 mov al, byte [ es : di ] -0991: 68 A1 09 push word .let_s_go_ret -0994: 3C 20 cmp al, ' ' -0996: 74 03 jz @f -0998: E9 FB FE jmp get_firs_sym.not_space -099B: E9 ED FE jmp get_firs_sym.first_sp -099E: E8 D2 FE call get_firs_sym -09A1: E3 0C jcxz .exit_scan_sect -09A3: 3C 5B cmp al, '[' -09A5: 75 F7 jnz .let_s_go -09A7: 3B 7E F6 cmp di, point_loader -09AA: 74 F2 jz .let_s_go -09AC: 89 7E F4 mov point_default, di -09AF: C3 ret -09B0: 8D 76 F2 lea si, point_to_hframe -09B3: BF 22 03 mov di, 962 - 160 -09B6: 8B 56 F4 mov dx, point_default -09B9: B9 12 00 mov cx, 18 -09BC: 8B 1C mov bx, [ si ] -09BE: 81 C7 A0 00 add di, 160 -09C2: 39 D3 cmp bx, dx -09C4: 74 05 jz .clean_cursor_ -09C6: 83 EE 02 sub si, 2 -09C9: E2 F1 loop .clean_show_cur -09CB: 68 00 B8 push 0xb800 -09CE: 07 pop es -09CF: 50 push ax -09D0: 89 76 CA mov point_to_point_def, si -09D3: 31 C0 xor ax, ax -09D5: B8 20 07 mov ax, 0x0720 -09D8: AB stosw -09D9: 83 C7 44 add di, 68 -09DC: AB stosw -09DD: 58 pop ax -09DE: C3 ret -09DF: B4 00 mov ah, 0 -09E1: CD 1A int 1Ah -09E3: 91 xchg ax, cx -09E4: 66 C1 E0 10 shl eax, 10h -09E8: 92 xchg ax, dx -09E9: C3 ret -09EA: 1E push ds -09EB: 0E push cs -09EC: 1F pop ds -09ED: 9C pushf -09EE: FF 1E D4 1A call far dword [ old_timer ] -09F2: 66 60 pushad -09F4: E8 E8 FF call gettime -09F7: 66 2B 06 D8 1A sub eax, dword [ start_timer ] -09FC: 8B 1E D2 1A mov bx, word [ value_timeout ] -0A00: 6B DB 12 imul bx, 18 -0A03: 29 C3 sub bx, ax -0A05: 76 1F jbe .timergo -0A07: 06 push es -0A08: 68 00 B8 push 0xb800 -0A0B: 07 pop es -0A0C: 89 D8 mov ax, bx -0A0E: BB 12 00 mov bx, 18 -0A11: 31 D2 xor dx, dx -0A13: F7 F3 div bx -0A15: BB 0A 00 mov bx, 10 -0A18: BF 96 0E mov di, 3734 -0A1B: E8 24 00 call .decode -0A1E: 31 C0 xor ax, ax -0A20: AB stosw -0A21: 07 pop es -0A22: 66 61 popad -0A24: 1F pop ds -0A25: CF iret -0A26: 6A 00 push 0 -0A28: 07 pop es -0A29: 66 A1 D4 1A mov eax, dword [ old_timer ] -0A2D: 26 66 A3 20 00 mov [ es : 8 * 4 ], eax -0A32: 66 A3 DC 1A mov dword [ timer_ ], eax -0A36: 8B 26 E0 1A mov sp, word [ start_stack ] -0A3A: 8B 2E E2 1A mov bp, word [ save_bp_from_timer ] -0A3E: FB sti -0A3F: E9 D8 06 jmp parse_start.parse_run_only -0A42: 39 D8 cmp ax, bx -0A44: 72 09 jb @f -0A46: 31 D2 xor dx, dx -0A48: F7 F3 div bx -0A4A: 52 push dx -0A4B: E8 F4 FF call .decode -0A4E: 58 pop ax -0A4F: 0C 30 or al, 0x30 -0A51: 50 push ax -0A52: B4 09 mov ah, 9 -0A54: AB stosw -0A55: 58 pop ax -0A56: C3 ret -0A57: 8B 5E C8 mov bx, point_to_eframe -0A5A: 8D 76 F2 lea si, point_to_hframe -0A5D: BA C6 03 mov dx, 966 -0A60: 39 DE cmp si, bx -0A62: 72 12 jb ._show_space_fb -0A64: 8B 3C mov di, [ si ] -0A66: 83 EE 02 sub si, 2 -0A69: 8B 0C mov cx, [ si ] -0A6B: 29 F9 sub cx, di -0A6D: E8 2B FE call show_name_section -0A70: 81 C2 A0 00 add dx, 160 -0A74: EB EA jmp .home_show_fb -0A76: 83 EA 04 sub dx, 4 -0A79: 68 00 B8 push 0xb800 -0A7C: 07 pop es -0A7D: 81 FA 64 0E cmp dx, 0xE64 -0A81: 77 12 ja .exit_show_fb -0A83: 89 D7 mov di, dx -0A85: 31 C0 xor ax, ax -0A87: B8 20 07 mov ax, 0x0720 -0A8A: B9 27 00 mov cx, 39 -0A8D: F3 rep -0A8E: AB stosw -0A8F: 81 C2 A0 00 add dx, 160 -0A93: EB E8 jmp @b -0A95: C3 ret -0A96: 89 C7 mov di, ax -0A98: 89 D9 mov cx, bx -0A9A: FF 66 FC jmp ret_on_ch -0A9D: C9 leave -0A9E: BE 1A 01 mov si, not_found_def_sect -0AA1: E9 F4 00 jmp err_show_ini -0AA4: C9 leave -0AA5: BE FE 00 mov si, not_found_sec_loader -0AA8: E9 ED 00 jmp err_show_ini -0AAB: C9 leave -0AAC: BE 47 01 mov si, default_eq_loader -0AAF: E9 E6 00 jmp err_show_ini -0AB2: C9 leave -0AB3: BE C4 02 mov si, point_to_default_sec_not_found -0AB6: E9 DF 00 jmp err_show_ini -0AB9: C9 leave -0ABA: BE F7 02 mov si, incorect_section_define -0ABD: E9 D8 00 jmp err_show_ini -0AC0: 68 00 B8 push word 0xb800 -0AC3: 07 pop es -0AC4: C3 ret -0AC5: 00 00 00 20 file_data dw 0x0, ini_data_ -0AC9: 10 00 size_data dw 16 -0ACB: 6B 6F 72 64 2F 73 74 61 72 74 6F 73 2E name_ini_f db 'kord/startos.ini', 0 -0AD8: 69 6E 69 00 -0ADC: 00 00 00 00 loader_callback dd ? -0AE0: 00 00 load_drive dw ? -0AE2: 00 00 load_ft dw ? -0AE4: 2E 89 36 DC 0A mov word [ cs : loader_callback ], si -0AE9: 2E 8C 1E DE 0A mov word [ cs : loader_callback + 2 ], ds -0AEE: 2E A3 E0 0A mov word [ cs : load_drive ], ax -0AF2: 2E 89 1E E2 0A mov word [ cs : load_ft ], bx -0AF7: 8C C8 mov ax, cs -0AF9: 8E D0 mov ss, ax -0AFB: 31 E4 xor sp, sp -0AFD: 8E D8 mov ds, ax -0AFF: 8E C0 mov es, ax -0B01: FC cld -0B02: FB sti -0B03: B8 03 00 mov ax, 3 -0B06: CD 10 int 0x10 -0B08: BE 03 00 mov si, version -0B0B: E8 36 FD call printplain -0B0E: B0 23 mov al, '#' -0B10: B9 50 00 mov cx, 80 -0B13: E8 27 FD call putchar -0B16: E2 FB loop @b -0B18: BE C8 03 mov si, stack_msg -0B1B: E8 26 FD call printplain -0B1E: 31 DB xor bx, bx -0B20: 8E DB mov ds, bx -0B22: FF 77 1A push word [ bx + 6 * 4 + 2 ] -0B25: FF 77 18 push word [ bx + 6 * 4 ] -0B28: C7 47 18 4A 0B mov word [ bx + 6 * 4 ], ud16 -0B2D: 8C 4F 1A mov word [ bx + 6 * 4 + 2 ], cs -0B30: 66 31 C0 xor eax, eax -0B33: 0F A2 cpuid -0B35: 66 85 C0 test eax, eax -0B38: 74 10 jz cpubad -0B3A: 66 31 C0 xor eax, eax -0B3D: 40 inc ax -0B3E: 0F A2 cpuid -0B40: F6 C2 10 test dl, 10h -0B43: 74 05 jz cpubad -0B45: F6 C2 20 test dl, 20h -0B48: 75 12 jnz cpugood -0B4A: 8F 06 18 00 pop word [ 6 * 4 ] -0B4E: 8F 06 1A 00 pop word [ 6 * 4 + 2 ] -0B52: 0E push cs -0B53: 1F pop ds -0B54: BE 4C 00 mov si, badprocessor -0B57: E8 EA FC call printplain -0B5A: EB FE jmp $ -0B5C: 66 8F 06 18 00 pop dword [ 6 * 4 ] -0B61: 0E push cs -0B62: 1F pop ds -0B63: 66 0F B7 E4 movzx esp, sp -0B67: B9 03 00 mov cx, loop_read_startos_file -0B6C: 31 C0 xor ax, ax -0B6E: BF C5 0A mov di, file_data -0B71: 40 inc ax -0B72: 51 push cx -0B73: FF 1E DC 0A call far dword [ loader_callback ] -0B77: 59 pop cx -0B78: 0E push cs -0B79: 0E push cs -0B7A: 1F pop ds -0B7B: 07 pop es -0B7C: 85 DB test bx, bx -0B7E: 74 28 jz check_conf_file -0B80: 49 dec cx -0B81: 75 E9 jnz load_startos_file -0B83: BE 68 00 mov si, error_ini_f1 -0B86: 4B dec bx -0B87: 74 0F jz err_show_ini -0B89: BE 95 00 mov si, error_ini_f2 -0B8C: 4B dec bx -0B8D: 74 09 jz err_show_ini -0B8F: BE B0 00 mov si, error_ini_f3 -0B92: 4B dec bx -0B93: 74 03 jz err_show_ini -0B95: BE CD 00 mov si, error_ini_nf -0B98: E8 A9 FC call printplain -0B9B: BE 26 02 mov si, error_ini_common -0B9E: E8 A3 FC call printplain -0BA1: 31 C0 xor ax, ax -0BA3: CD 16 int 16h -0BA5: EB FE jmp $ -0BA8: 50 push ax -0BA9: B9 0A 00 mov cx, 0x0a -0BAC: BF 00 04 mov di, show_decode -0BAF: E8 73 FC call decode -0BB2: BE EF 03 mov si, show_string -0BB5: E8 8C FC call printplain -0BB8: BE 90 02 mov si, load_ini -0BBB: E8 86 FC call printplain -0BBE: 59 pop cx -0BBF: C8 00 01 00 enter 256, 0 -0BC3: 89 2E E2 1A mov word [ save_bp_from_timer ], bp -0BC7: 89 4E FE mov save_cx, cx -0BCA: C4 3E C5 0A les di, dword [ file_data ] -0BCE: 31 C0 xor ax, ax -0BD0: 89 46 F8 mov status_flag, ax -0BD3: C7 46 C4 00 30 mov info_real_mode_size, ini_data_ + 0x1000 -0BD8: FC cld -0BD9: C7 46 FC EE 0B mov ret_on_ch, .start -0BDE: 26 8A 05 mov al, byte [ es : di ] -0BE1: 68 F1 0B push word .first_ret -0BE4: 3C 20 cmp al, ' ' -0BE6: 74 03 jz .first_sp_1 -0BE8: E9 AB FC jmp get_firs_sym.not_space -0BEB: E9 9D FC jmp get_firs_sym.first_sp -0BEE: E8 82 FC call get_firs_sym -0BF1: 85 C9 test cx, cx -0BF3: 0F 84 AD FE jz error.not_loader -0BF7: 3C 5B cmp al, '[' -0BF9: 74 02 jz .parse_loader -0BFB: EB F1 jmp .start -0BFD: 89 CB mov bx, cx -0BFF: 89 F8 mov ax, di -0C01: BE AC 07 mov si, parse_loader -0C04: B9 08 00 mov cx, parse_loader_e - parse_loader -0C07: F3 repe -0C08: A6 cmpsb -0C09: 0F 85 89 FE jnz error.rest_value -0C0D: 89 46 F6 mov point_loader, ax -0C10: 83 EB 08 sub bx, parse_loader_e - parse_loader -0C13: 01 CB add bx, cx -0C15: 89 D9 mov cx, bx -0C17: 60 pusha -0C18: BE 35 04 mov si, lm_l_found -0C1B: E8 26 FC call printplain -0C1E: 61 popa -0C1F: 89 FA mov dx, di -0C21: E8 4F FC call get_firs_sym -0C24: E3 04 jcxz .loader_f_end -0C26: 3C 5B cmp al, '[' -0C28: 75 F7 jnz @b -0C2A: 29 CB sub bx, cx -0C2C: 89 D7 mov di, dx -0C2E: 89 D9 mov cx, bx -0C30: C7 46 FC 35 0C mov ret_on_ch, .get_next_str -0C35: E8 3B FC call get_firs_sym -0C38: 85 C9 test cx, cx -0C3A: 0F 84 57 01 jz .end_loader -0C3E: 3C 74 cmp al, 't' -0C40: 0F 84 DE 00 jz .loader_timeout -0C44: 3C 64 cmp al, 'd' -0C46: 75 ED jnz .get_next_str -0C48: 89 CB mov bx, cx -0C4A: 89 F8 mov ax, di -0C4C: BE BB 07 mov si, parse_l_default -0C4F: B9 07 00 mov cx, parse_l_default_e - parse_l_default -0C52: F3 repe -0C53: A6 cmpsb -0C54: 0F 85 3E FE jnz error.rest_value -0C58: 83 EB 07 sub bx, parse_l_default_e - parse_l_default -0C5B: 01 CB add bx, cx -0C5D: 89 D9 mov cx, bx -0C5F: F7 46 F8 01 00 test status_flag, flag_found_default -0C64: 74 08 jz .correct_is_not_set -0C66: BE 7A 01 mov si, found_equal_default -0C69: E8 D8 FB call printplain -0C6C: EB C7 jmp .get_next_str -0C6E: B8 20 3D mov ax, 0x3d20 -0C71: F3 repe -0C72: AE scasb -0C73: 85 C9 test cx, cx -0C75: 0F 84 1C 01 jz .end_loader -0C79: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -0C7D: 75 B6 jnz .get_next_str -0C7F: F3 repe -0C80: AE scasb -0C81: 41 inc cx -0C82: 4F dec di -0C83: 89 CB mov bx, cx -0C85: 89 FA mov dx, di -0C87: 26 8A 05 mov al, byte [ es : di ] -0C8A: 47 inc di -0C8B: 49 dec cx -0C8C: 85 C9 test cx, cx -0C8E: 0F 84 0B FE jz error.error_get_size_d_sect -0C92: 3C 20 cmp al, ' ' -0C94: 74 F1 jz @b -0C96: 3C 0D cmp al, 0xd -0C98: 74 04 jz .found_size_d_sect -0C9A: 3C 0A cmp al, 0xa -0C9C: 75 E9 jnz @b -0C9E: 41 inc cx -0C9F: 89 D8 mov ax, bx -0CA1: 29 CB sub bx, cx -0CA3: 89 5E FA mov save_cx_d, bx -0CA6: 89 D7 mov di, dx -0CA8: 89 D9 mov cx, bx -0CAA: 89 C3 mov bx, ax -0CAC: 89 D0 mov ax, dx -0CAE: BE AC 07 mov si, parse_loader -0CB1: 46 inc si -0CB2: F3 repe -0CB3: A6 cmpsb -0CB4: 75 03 jnz .check_section -0CB6: E9 F2 FD jmp error.default_eq_loader -0CB9: 89 D9 mov cx, bx -0CBB: 89 C7 mov di, ax -0CBD: 89 FE mov si, di -0CBF: 57 push di -0CC0: 51 push cx -0CC1: 8B 4E FE mov cx, save_cx -0CC4: C4 3E C5 0A les di, dword [ file_data ] -0CC8: 26 8A 05 mov al, byte [ es : di ] -0CCB: 68 DB 0C push word .first_ret_d -0CCE: 3C 20 cmp al, ' ' -0CD0: 74 03 jz .first_sp_1_d -0CD2: E9 C1 FB jmp get_firs_sym.not_space -0CD5: E9 B3 FB jmp get_firs_sym.first_sp -0CD8: E8 98 FB call get_firs_sym -0CDB: E3 38 jcxz .correct_exit -0CDD: 3C 5B cmp al, '[' -0CDF: 74 02 jz .found_sect_d -0CE1: EB F5 jmp .start_d -0CE3: 89 CB mov bx, cx -0CE5: 89 F8 mov ax, di -0CE7: 56 push si -0CE8: 8B 4E FA mov cx, save_cx_d -0CEB: 06 push es -0CEC: 1F pop ds -0CED: 47 inc di -0CEE: F3 repe -0CEF: A6 cmpsb -0CF0: 0E push cs -0CF1: 1F pop ds -0CF2: 5E pop si -0CF3: 75 1A jnz .not_compare_d_s -0CF5: 26 80 3D 5D cmp byte [ es : di ], ']' -0CF9: 75 14 jnz .not_compare_d_s -0CFB: 83 4E F8 01 or status_flag, flag_found_default -0CFF: 59 pop cx -0D00: 5F pop di -0D01: 89 46 F4 mov point_default, ax -0D04: 60 pusha -0D05: BE 96 04 mov si, lm_lf_default_f -0D08: E8 39 FB call printplain -0D0B: 61 popa -0D0C: E9 26 FF jmp .get_next_str -0D0F: 89 D9 mov cx, bx -0D11: 89 C7 mov di, ax -0D13: EB C3 jmp .start_d -0D15: 59 pop cx -0D16: 5F pop di -0D17: 60 pusha -0D18: BE 58 04 mov si, lm_lf_default -0D1B: E8 26 FB call printplain -0D1E: 61 popa -0D1F: E9 13 FF jmp .get_next_str -0D22: 89 CB mov bx, cx -0D24: 89 F8 mov ax, di -0D26: BE B4 07 mov si, parse_l_timeout -0D29: B9 07 00 mov cx, parse_l_timeout_e - parse_l_timeout -0D2C: F3 repe -0D2D: A6 cmpsb -0D2E: 0F 85 64 FD jnz error.rest_value -0D32: 83 EB 07 sub bx, parse_l_timeout_e - parse_l_timeout -0D35: 01 CB add bx, cx -0D37: 89 D9 mov cx, bx -0D39: F7 46 F8 02 00 test status_flag, flag_found_timeout -0D3E: 74 09 jz .correct_is_not_set_t -0D40: BE B0 01 mov si, found_equal_timeout -0D43: E8 FE FA call printplain -0D46: E9 EC FE jmp .get_next_str -0D49: B8 20 3D mov ax, 0x3d20 -0D4C: F3 repe -0D4D: AE scasb -0D4E: E3 35 jcxz .timeout_sec_end_d -0D50: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -0D54: 0F 85 DD FE jnz .get_next_str -0D58: F3 repe -0D59: AE scasb -0D5A: 41 inc cx -0D5B: 4F dec di -0D5C: 51 push cx -0D5D: 31 DB xor bx, bx -0D5F: B9 02 00 mov cx, 2 -0D62: 26 8A 05 mov al, byte [ es : di ] -0D65: 3C 30 cmp al, '0' -0D67: 72 0B jb .end_get_val_t -0D69: 3C 39 cmp al, '9' -0D6B: 77 07 ja .end_get_val_t -0D6D: 6B DB 0A imul bx, 10 -0D70: 34 30 xor al, 0x30 -0D72: 00 C3 add bl, al -0D74: 47 inc di -0D75: E2 EB loop @b -0D77: 89 1E D2 1A mov word [ value_timeout ], bx -0D7B: 60 pusha -0D7C: BE 47 04 mov si, lm_lf_timeout -0D7F: E8 C2 FA call printplain -0D82: 61 popa -0D83: EB 0C jmp @f -0D85: C7 06 D2 1A 05 00 mov word [ value_timeout ], default_timeout_value -0D8B: BE E6 01 mov si, set_default_timeout_val -0D8E: E8 B3 FA call printplain -0D91: 59 pop cx -0D92: E9 A0 FE jmp .get_next_str -0D95: 60 pusha -0D96: BE AD 04 mov si, lm_l_end -0D99: E8 A8 FA call printplain -0D9C: 61 popa -0D9D: 31 C0 xor ax, ax -0D9F: CD 16 int 16h -0DA1: 60 pusha -0DA2: A1 D2 1A mov ax, word [ value_timeout ] -0DA5: B9 0A 00 mov cx, 0x0a -0DA8: BF 07 04 mov di, show_db1 -0DAB: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' -0DB2: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' -0DB7: E8 6B FA call decode -0DBA: BE 07 04 mov si, show_db1 -0DBD: E8 84 FA call printplain -0DC0: 61 popa -0DC1: 85 C0 test ax, ax -0DC3: 0F 84 53 03 jz .parse_run_only -0DC7: 60 pusha -0DC8: BE C5 04 mov si, show_all_sect -0DCB: E8 76 FA call printplain -0DCE: 61 popa -0DCF: B0 F6 mov al, 0xf6 -0DD1: E6 60 out 0x60, al -0DD3: 31 C9 xor cx, cx -0DD5: E4 64 in al, 64h -0DD7: 24 02 and al, 00000010b -0DD9: E0 FA loopnz .wait_loop -0DDB: B0 F3 mov al, 0xf3 -0DDD: E6 60 out 0x60, al -0DDF: 31 C9 xor cx, cx -0DE1: E4 64 in al, 64h -0DE3: A8 02 test al, 2 -0DE5: E0 FA loopnz @b -0DE7: B0 00 mov al, 0 -0DE9: E6 60 out 0x60, al -0DEB: 31 C9 xor cx, cx -0DED: E4 64 in al, 64h -0DEF: A8 02 test al, 2 -0DF1: E0 FA loopnz @b -0DF3: E8 E9 FB call gettime -0DF6: 66 A3 D8 1A mov dword [ start_timer ], eax -0DFA: C7 06 DC 1A EA 09 mov word [ timer_ ], newtimer -0E00: 8C 0E DE 1A mov word [ timer_ + 2 ], cs -0E04: FA cli -0E05: 6A 00 push 0 -0E07: 07 pop es -0E08: 26 66 FF 36 20 00 push dword [ es : 8 * 4 ] -0E0E: 66 8F 06 D4 1A pop dword [ old_timer ] -0E13: 66 FF 36 DC 1A push dword [ timer_ ] -0E18: 26 66 8F 06 20 00 pop dword [ es : 8 * 4 ] -0E1E: FB sti -0E1F: C7 46 BE 12 00 mov save_descript_size, 18 -0E24: 31 C0 xor ax, ax -0E26: B8 20 07 mov ax, 0x0720 -0E29: 68 00 B8 push 0xb800 -0E2C: 07 pop es -0E2D: 31 FF xor di, di -0E2F: B9 D0 07 mov cx, 25 * 80 -0E32: F3 rep -0E33: AB stosw -0E34: BF A4 00 mov di, 164 -0E37: BE 03 00 mov si, version -0E3A: B9 19 00 mov cx, version_end - version -0E3D: B4 0E mov ah, color_sym_yellow -0E3F: AC lodsb -0E40: AB stosw -0E41: E2 FC loop @b -0E43: BF 1E 01 mov di, 286 -0E46: B4 0C mov ah, color_sym_pink -0E48: B0 4B mov al, 'K' -0E4A: AB stosw -0E4B: B0 20 mov al, ' ' -0E4D: AB stosw -0E4E: B4 07 mov ah, color_sym_lightgray -0E50: BE 3F 00 mov si, soft_mes -0E53: B9 0D 00 mov cx, soft_mes_end - soft_mes -0E56: AC lodsb -0E57: AB stosw -0E58: E2 FC loop @b -0E5A: BF E0 01 mov di, 480 -0E5D: B4 0E mov ah, color_sym_yellow -0E5F: B0 C4 mov al, 0xC4 -0E61: B9 3D 00 mov cx, 61 -0E64: F3 rep -0E65: AB stosw -0E66: BF 24 03 mov di, 804 -0E69: BE 1C 00 mov si, select_section -0E6C: B9 0F 00 mov cx, select_section_end - select_section -0E6F: B4 07 mov ah, color_sym_lightgray -0E71: AC lodsb -0E72: AB stosw -0E73: E2 FC loop @b -0E75: BF 70 03 mov di, 880 -0E78: BE 2B 00 mov si, section_description -0E7B: B9 14 00 mov cx, section_description_end - section_description -0E7E: AC lodsb -0E7F: AB stosw -0E80: E2 FC loop @b -0E82: 8B 4E FE mov cx, save_cx -0E85: C4 3E C5 0A les di, dword [ file_data ] -0E89: 89 FE mov si, di -0E8B: 89 CB mov bx, cx -0E8D: BA 12 00 mov dx, size_show_section -0E90: 26 8A 05 mov al, byte [ es : di ] -0E93: 68 B9 0E push word .first_ret_bl_sc -0E96: 3C 20 cmp al, ' ' -0E98: 74 03 jz .first_bl_sc -0E9A: E9 F9 F9 jmp get_firs_sym.not_space -0E9D: E9 EB F9 jmp get_firs_sym.first_sp -0EA0: E8 D0 F9 call get_firs_sym -0EA3: 85 C9 test cx, cx -0EA5: 0F 84 09 FC jz error.correct_exit_bl -0EA9: 3C 5B cmp al, '[' -0EAB: 75 F3 jnz .start_hbl -0EAD: 89 FE mov si, di -0EAF: 89 CB mov bx, cx -0EB1: BA 12 00 mov dx, size_show_section -0EB4: EB 09 jmp .analisist_al -0EB6: E8 BA F9 call get_firs_sym -0EB9: 85 C9 test cx, cx -0EBB: 0F 84 F3 FB jz error.correct_exit_bl -0EBF: 3C 5B cmp al, '[' -0EC1: 75 F3 jnz .start_bl -0EC3: 3B 7E F6 cmp di, point_loader -0EC6: 74 EE jz .start_bl -0EC8: 3B 7E F4 cmp di, point_default -0ECB: 74 05 jz .save_point_def -0ECD: 4A dec dx -0ECE: 75 E6 jnz .start_bl -0ED0: EB CE jmp .start_hbl -0ED2: 89 F7 mov di, si -0ED4: 89 D9 mov cx, bx -0ED6: 8D 76 F2 lea si, point_to_hframe -0ED9: BA 13 00 mov dx, size_show_section + 1 -0EDC: 26 8A 05 mov al, byte [ es : di ] -0EDF: 68 EF 0E push word .first_ret_mfb -0EE2: 3C 20 cmp al, ' ' -0EE4: 74 03 jz .first_bl_mbf -0EE6: E9 AD F9 jmp get_firs_sym.not_space -0EE9: E9 9F F9 jmp get_firs_sym.first_sp -0EEC: E8 84 F9 call get_firs_sym -0EEF: E3 13 jcxz .val_buff_comp -0EF1: 3C 5B cmp al, '[' -0EF3: 75 F7 jnz .start_mfb -0EF5: 3B 7E F6 cmp di, point_loader -0EF8: 74 F2 jz .start_mfb -0EFA: 89 3C mov [ si ], di -0EFC: 83 EE 02 sub si, 2 -0EFF: 4A dec dx -0F00: 75 EA jnz .start_mfb -0F02: EB 08 jmp @f -0F04: FF 76 FE push save_cx -0F07: 8F 04 pop word [ si ] -0F09: 83 EE 02 sub si, 2 -0F0C: 83 C6 04 add si, 4 -0F0F: 89 76 C8 mov point_to_eframe, si -0F12: E8 42 FB call show_bl_sc_sect -0F15: 8D 76 F2 lea si, point_to_hframe -0F18: BF 22 03 mov di, 962 - 160 -0F1B: 8B 46 F4 mov ax, point_default -0F1E: B9 12 00 mov cx, size_show_section -0F21: 8B 1C mov bx, [ si ] -0F23: 81 C7 A0 00 add di, 160 -0F27: 39 C3 cmp bx, ax -0F29: 74 05 jz .show_cursor_activ -0F2B: 83 EE 02 sub si, 2 -0F2E: E2 F1 loop .home_show_cur -0F30: 89 76 CA mov point_to_point_def, si -0F33: B8 10 04 mov ax, ( color_sym_red * 0x100 + 0x10 ) -0F36: AB stosw -0F37: 83 C7 44 add di, 68 -0F3A: 40 inc ax -0F3B: AB stosw -0F3C: 8B 7E F4 mov di, point_default -0F3F: 68 00 20 push ini_data_ -0F42: 8B 76 CA mov si, point_to_point_def -0F45: 07 pop es -0F46: 83 EE 02 sub si, 2 -0F49: 8B 0C mov cx, [ si ] -0F4B: 29 F9 sub cx, di -0F4D: E8 23 F9 call get_firs_sym -0F50: 85 C9 test cx, cx -0F52: 0F 84 91 00 jz .exit?0Pz -0F56: 3C 64 cmp al, 'd' -0F58: 75 F3 jnz .start_p_sh_d?0Py -0F5A: 89 CB mov bx, cx -0F5C: 89 F8 mov ax, di -0F5E: BE C5 07 mov si, parse_descript -0F61: B9 08 00 mov cx, parse_descript_e - parse_descript -0F64: F3 repe -0F65: A6 cmpsb -0F66: 75 78 jnz .rest_value_loop_sh_d?0Q0 -0F68: 83 EB 08 sub bx, parse_descript_e - parse_descript -0F6B: 01 CB add bx, cx -0F6D: 89 D9 mov cx, bx -0F6F: B8 20 3D mov ax, 0x3d20 -0F72: F3 repe -0F73: AE scasb -0F74: E3 6A jcxz .rest_value_loop_sh_d?0Q0 -0F76: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -0F7A: 75 64 jnz .rest_value_loop_sh_d?0Q0 -0F7C: F3 repe -0F7D: AE scasb -0F7E: 41 inc cx -0F7F: 4F dec di -0F80: 57 push di -0F81: 5E pop si -0F82: 06 push es -0F83: 1F pop ds -0F84: 68 00 B8 push 0xb800 -0F87: 07 pop es -0F88: BF 10 04 mov di, 1040 -0F8B: BB 12 00 mov bx, 18 -0F8E: 89 7E C6 mov find_sec_di, di -0F91: 89 5E FA mov save_cx_d, bx -0F94: 57 push di -0F95: 31 C0 xor ax, ax -0F97: B9 26 00 mov cx, 38 -0F9A: 57 push di -0F9B: F3 rep -0F9C: AB stosw -0F9D: 5F pop di -0F9E: 39 5E BE cmp save_descript_size, bx -0FA1: 74 07 jz @f -0FA3: 81 C7 A0 00 add di, 160 -0FA7: 4B dec bx -0FA8: 75 ED jnz @b -0FAA: 5F pop di -0FAB: AC lodsb -0FAC: B4 0A mov ah, color_sym_lettuce -0FAE: 3C 22 cmp al, '"' -0FB0: 74 04 jz .loop_message?0Q2 -0FB2: 3C 27 cmp al, ''' -0FB4: 75 20 jnz .end_sh_desc_sec?0Q1 -0FB6: B9 26 00 mov cx, 38 -0FB9: AC lodsb -0FBA: 3C 22 cmp al, '"' -0FBC: 74 18 jz .end_sh_desc_sec?0Q1 -0FBE: 3C 27 cmp al, ''' -0FC0: 74 14 jz .end_sh_desc_sec?0Q1 -0FC2: AB stosw -0FC3: E2 F4 loop @b -0FC5: 81 46 C6 A0 00 add find_sec_di, 160 -0FCA: 8B 7E C6 mov di, find_sec_di -0FCD: FF 4E FA dec save_cx_d -0FD0: 83 7E FA 00 cmp save_cx_d, 0 -0FD4: 75 E0 jnz .loop_message?0Q2 -0FD6: FF 76 FA push save_cx_d -0FD9: 8F 46 BE pop save_descript_size -0FDC: 0E push cs -0FDD: 1F pop ds -0FDE: EB 07 jmp .exit?0Pz -0FE0: 89 C7 mov di, ax -0FE2: 89 D9 mov cx, bx -0FE4: E9 66 FF jmp .start_p_sh_d?0Py -0FE7: 66 A1 D4 1A mov eax, dword [ old_timer ] -0FEB: 66 3B 06 DC 1A cmp eax, dword [ timer_ ] -0FF0: 74 5E jz .interrupt_16 -0FF2: 31 C0 xor ax, ax -0FF4: BF 20 0D mov di, 3360 -0FF7: B9 40 01 mov cx, 80 * 4 -0FFA: F3 rep -0FFB: AB stosw -0FFC: BF 22 0D mov di, 3362 -0FFF: B4 0C mov ah, color_sym_pink -1001: B0 DA mov al, 0xDA -1003: AB stosw -1004: B0 C4 mov al, 0xc4 -1006: B9 4C 00 mov cx, 76 -1009: F3 rep -100A: AB stosw -100B: B0 BF mov al, 0xBF -100D: AB stosw -100E: 83 C7 04 add di, 4 -1011: B0 B3 mov al, 0xb3 -1013: AB stosw -1014: 81 C7 98 00 add di, 152 -1018: AB stosw -1019: 83 C7 04 add di, 4 -101C: AB stosw -101D: 81 C7 98 00 add di, 152 -1021: AB stosw -1022: 83 C7 04 add di, 4 -1025: B0 C0 mov al, 0xc0 -1027: AB stosw -1028: B0 C4 mov al, 0xc4 -102A: B9 4C 00 mov cx, 76 -102D: F3 rep -102E: AB stosw -102F: B0 D9 mov al, 0xd9 -1031: AB stosw -1032: BE 2E 03 mov si, start_msg -1035: B9 4A 00 mov cx, start_msg_e - start_msg -1038: BF C6 0D mov di, 3526 -103B: AC lodsb -103C: AB stosw -103D: E2 FC loop @b -103F: 83 C7 2C add di, 44 -1042: BE 78 03 mov si, time_msg -1045: B9 2D 00 mov cx, time_msg_e - time_msg -1048: AC lodsb -1049: AB stosw -104A: E2 FC loop @b -104C: 89 26 E0 1A mov word [ start_stack ], sp -1050: 31 C0 xor ax, ax -1052: CD 16 int 0x16 -1054: 66 8B 1E D4 1A mov ebx, dword [ old_timer ] -1059: 66 3B 1E DC 1A cmp ebx, dword [ timer_ ] -105E: 74 2A jz @f -1060: FA cli -1061: 6A 00 push 0 -1063: 07 pop es -1064: 26 66 89 1E 20 00 mov [ es : 8 * 4 ], ebx -106A: 66 89 1E DC 1A mov dword [ timer_ ], ebx -106F: FB sti -1070: 50 push ax -1071: 68 00 B8 push 0xb800 -1074: 07 pop es -1075: 31 C0 xor ax, ax -1077: B8 20 07 mov ax, 0x0720 -107A: BF 20 0D mov di, 3360 -107D: B9 40 01 mov cx, 80 * 4 -1080: F3 rep -1081: AB stosw -1082: 68 00 20 push ini_data_ -1085: 07 pop es -1086: E8 CE F9 call show_bl_sc_sect -1089: 58 pop ax -108A: E8 23 F9 call clean_active_cursor -108D: 80 FC 48 cmp ah, 0x48 -1090: 74 21 jz .up -1092: 80 FC 50 cmp ah, 0x50 -1095: 74 3A jz .down -1097: 80 FC 49 cmp ah, 0x49 -109A: 74 53 jz .pgup -109C: 80 FC 51 cmp ah, 0x51 -109F: 74 5B jz .pgdown -10A1: 80 FC 47 cmp ah, 0x47 -10A4: 74 63 jz .home -10A6: 80 FC 4F cmp ah, 0x4f -10A9: 74 66 jz .end -10AB: 3C 0D cmp al, 0xD -10AD: 0F 85 64 FE jnz .show_active_cursor -10B1: EB 6F jmp .end_show_all -10B3: 8B 76 CA mov si, point_to_point_def -10B6: 83 C6 02 add si, 2 -10B9: 8D 46 F2 lea ax, point_to_hframe -10BC: 39 C6 cmp si, ax -10BE: 77 0B ja @f -10C0: 89 76 CA mov point_to_point_def, si -10C3: 8B 04 mov ax, [ si ] -10C5: 89 46 F4 mov point_default, ax -10C8: E9 4A FE jmp .show_active_cursor -10CB: E8 52 F8 call find_before_sect -10CE: E9 B1 FD jmp .show_all_scr -10D1: 8B 76 CA mov si, point_to_point_def -10D4: 8B 46 C8 mov ax, point_to_eframe -10D7: 83 EE 02 sub si, 2 -10DA: 39 C6 cmp si, ax -10DC: 72 0B jb @f -10DE: 89 76 CA mov point_to_point_def, si -10E1: 8B 04 mov ax, [ si ] -10E3: 89 46 F4 mov point_default, ax -10E6: E9 2C FE jmp .show_active_cursor -10E9: E8 8D F8 call find_next_sect -10EC: E9 93 FD jmp .show_all_scr -10EF: B9 12 00 mov cx, size_show_section -10F2: 51 push cx -10F3: E8 2A F8 call find_before_sect -10F6: 59 pop cx -10F7: E2 F9 loop @b -10F9: E9 86 FD jmp .show_all_scr -10FC: B9 12 00 mov cx, size_show_section -10FF: 51 push cx -1100: E8 76 F8 call find_next_sect -1103: 59 pop cx -1104: E2 F9 loop @b -1106: E9 79 FD jmp .show_all_scr -1109: 31 FF xor di, di -110B: E8 79 F8 call find_next_sect.h -110E: E9 71 FD jmp .show_all_scr -1111: 8B 7E FE mov di, save_cx -1114: E8 0C F8 call find_before_sect.e -1117: E9 68 FD jmp .show_all_scr -111A: 60 pusha -111B: BE D7 04 mov si, no_show_only_w -111E: E8 23 F7 call printplain -1121: 61 popa -1122: 8B 7E F4 mov di, point_default -1125: 68 00 20 push ini_data_ -1128: 07 pop es -1129: 8B 76 CA mov si, point_to_point_def -112C: 83 EE 02 sub si, 2 -112F: 8B 0C mov cx, [ si ] -1131: 31 C0 xor ax, ax -1133: 29 F9 sub cx, di -1135: 89 4E FA mov save_cx_d, cx -1138: 89 46 F8 mov status_flag, ax -113B: BE 2B 05 mov si, ramdiskFS_st -113E: E8 03 F7 call printplain -1141: 31 C0 xor ax, ax -1143: 89 46 C0 mov show_errors_sect, ax -1146: B4 88 mov ah, 0x88 -1148: CD 15 int 0x15 -114A: 73 02 jnc ._support_function_use_free_memory -114C: 31 C0 xor ax, ax -114E: 89 46 C2 mov free_ad_memory, ax -1151: 60 pusha -1152: 66 0F B7 C0 movzx eax, ax -1156: B9 0A 00 mov cx, 0x0a -1159: BF 46 05 mov di, free_memory_msg -115C: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' -1163: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' -1168: E8 BA F6 call decode -116B: BE 46 05 mov si, free_memory_msg -116E: E8 D3 F6 call printplain -1171: 61 popa -1172: 8B 7E F4 mov di, point_default -1175: 8B 4E FA mov cx, save_cx_d -1178: E8 F8 F6 call get_firs_sym -117B: 85 C9 test cx, cx -117D: 74 6E jz ._end_parse_RS?0k2 -117F: 3C 52 cmp al, 'R' -1181: 75 F5 jnz .start_p_RS?0ju -1183: 89 CB mov bx, cx -1185: 89 F8 mov ax, di -1187: BE D9 07 mov si, parse_RamdiskSize -118A: B9 0B 00 mov cx, parse_RamdiskSize_e - parse_RamdiskSize -118D: F3 repe -118E: A6 cmpsb -118F: 75 4C jnz .rest_value_loop_RS?0jz -1191: 83 EB 0B sub bx, parse_RamdiskSize_e - parse_RamdiskSize -1194: 01 CB add bx, cx -1196: 89 D9 mov cx, bx -1198: F7 46 F8 02 00 test status_flag, flag_found_RS -119D: 74 00 jz .correct_is_not_set_RS?0jv -119F: B8 20 3D mov ax, 0x3d20 -11A2: F3 repe -11A3: AE scasb -11A4: E3 3D jcxz .end_get_RS_ERROR_1?0k0 -11A6: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -11AA: 75 CC jnz .start_p_RS?0ju -11AC: F3 repe -11AD: AE scasb -11AE: 41 inc cx -11AF: 4F dec di -11B0: 31 DB xor bx, bx -11B2: B9 05 00 mov cx, 5 -11B5: 26 8A 05 mov al, byte [ es : di ] -11B8: 3C 30 cmp al, '0' -11BA: 72 04 jb .CS?0jw -11BC: 3C 39 cmp al, '9' -11BE: 76 06 jbe .correct_val_RS?0jx -11C0: 3C 4B cmp al, 'K' -11C2: 74 0C jz .correct_size_RS?0jy -11C4: EB 23 jmp .end_get_RS_ERROR_2?0k1 -11C6: 6B DB 0A imul bx, 10 -11C9: 34 30 xor al, 0x30 -11CB: 00 C3 add bl, al -11CD: 47 inc di -11CE: E2 E5 loop @b -11D0: 85 DB test bx, bx -11D2: 75 07 jnz @f -11D4: 83 4E C0 04 or show_errors_sect, show_error_3 -11D8: BB 40 00 mov bx, 64 -11DB: EB 10 jmp ._end_parse_RS?0k2 -11DD: 89 C7 mov di, ax -11DF: 89 D9 mov cx, bx -11E1: EB 95 jmp .start_p_RS?0ju -11E3: 83 4E C0 01 or show_errors_sect, show_error_1 -11E7: EB 04 jmp ._end_parse_RS?0k2 -11E9: 83 4E C0 02 or show_errors_sect, show_error_2 -11ED: 60 pusha -11EE: 66 0F B7 C3 movzx eax, bx -11F2: B9 0A 00 mov cx, 0x0a -11F5: BF 71 05 mov di, RamdiskSize_msg -11F8: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' -11FF: C7 45 04 20 20 mov word [ ds : di + 4 ], ' ' -1204: E8 1E F6 call decode -1207: BE 71 05 mov si, RamdiskSize_msg -120A: E8 37 F6 call printplain -120D: 61 popa -120E: 39 5E C2 cmp free_ad_memory, bx -1211: 0F 86 80 07 jbe ._not_memory_in_sys?0iL -1215: 66 0F B7 C3 movzx eax, bx -1219: 66 C1 E0 0A shl eax, 10 -121D: 66 89 46 BA mov save_ramdisksize, eax -1221: 8B 7E F4 mov di, point_default -1224: 8B 4E FA mov cx, save_cx_d -1227: E8 49 F6 call get_firs_sym -122A: 85 C9 test cx, cx -122C: 0F 84 5D 07 jz ._end_parse_FRS -1230: 3C 52 cmp al, 'R' -1232: 75 F3 jnz .start_g_tpe_RFS -1234: 89 CB mov bx, cx -1236: 89 F8 mov ax, di -1238: BE E4 07 mov si, parse_RamdiskFS -123B: B9 09 00 mov cx, parse_RamdiskFS_e - parse_RamdiskFS -123E: F3 repe -123F: A6 cmpsb -1240: 0F 85 38 07 jnz .start_g_tpe_RFS_rest_v -1244: 83 EB 09 sub bx, parse_RamdiskFS_e - parse_RamdiskFS -1247: 01 CB add bx, cx -1249: 89 D9 mov cx, bx -124B: F7 46 F8 04 00 test status_flag, flag_found_GTRFMS -1250: 74 00 jz .correct_is_not_set_FRS -1252: B8 20 3D mov ax, 0x3d20 -1255: F3 repe -1256: AE scasb -1257: 85 C9 test cx, cx -1259: 0F 84 26 07 jz .end_get_FRS_ERROR_1 -125D: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -1261: 75 C4 jnz .start_g_tpe_RFS -1263: F3 repe -1264: AE scasb -1265: 41 inc cx -1266: 4F dec di -1267: 89 CB mov bx, cx -1269: 89 F8 mov ax, di -126B: BE 08 08 mov si, parse_RFS_FAT -126E: B9 03 00 mov cx, parse_RFS_FAT_e - parse_RFS_FAT -1271: F3 repe -1272: A6 cmpsb -1273: 0F 85 F7 06 jnz .krfs_cmp -1277: 8B 7E F4 mov di, point_default -127A: 8B 4E FA mov cx, save_cx_d -127D: E8 F3 F5 call get_firs_sym -1280: 85 C9 test cx, cx -1282: 74 54 jz .end_RamdiskSector -1284: 3C 52 cmp al, 'R' -1286: 75 F5 jnz .start_RamdiskSector -1288: 89 CB mov bx, cx -128A: 89 F8 mov ax, di -128C: BE ED 07 mov si, parse_RamdiskSector -128F: B9 0D 00 mov cx, parse_RamdiskSector_e - parse_RamdiskSector -1292: F3 repe -1293: A6 cmpsb -1294: 75 3C jnz .RamdiskSector_rest_val -1296: 83 EB 0D sub bx, parse_RamdiskSector_e - parse_RamdiskSector -1299: 01 CB add bx, cx -129B: 89 D9 mov cx, bx -129D: F7 46 F8 08 00 test status_flag, flag_found_RamdiskSector -12A2: 74 00 jz .correct_is_not_set_RamdiskSector -12A4: B8 20 3D mov ax, 0x3d20 -12A7: F3 repe -12A8: AE scasb -12A9: E3 2D jcxz .end_get_RamS_ERROR_1 -12AB: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -12AF: 75 CC jnz .start_RamdiskSector -12B1: F3 repe -12B2: AE scasb -12B3: 41 inc cx -12B4: 4F dec di -12B5: 31 DB xor bx, bx -12B7: B9 04 00 mov cx, 4 -12BA: 26 0F B6 05 movzx ax, byte [ es : di ] -12BE: 3C 30 cmp al, '0' -12C0: 72 16 jb .end_RamdiskSector -12C2: 3C 39 cmp al, '9' -12C4: 77 12 ja .end_RamdiskSector -12C6: 6B DB 0A imul bx, 10 -12C9: 34 30 xor al, 0x30 -12CB: 01 C3 add bx, ax -12CD: 47 inc di -12CE: E2 EA loop @b -12D0: EB 06 jmp .end_RamdiskSector -12D2: 89 D9 mov cx, bx -12D4: 89 C7 mov di, ax -12D6: EB A5 jmp .start_RamdiskSector -12D8: 89 D8 mov ax, bx -12DA: 60 pusha -12DB: 66 0F B7 C3 movzx eax, bx -12DF: B9 0A 00 mov cx, 0x0a -12E2: BF 8E 05 mov di, RamdiskSector_msg -12E5: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' -12EC: 66 C7 45 04 20 20 20 20 mov dword [ ds : di + 4 ], ' ' -12F4: E8 2E F5 call decode -12F7: BE 8E 05 mov si, RamdiskSector_msg -12FA: E8 47 F5 call printplain -12FD: 61 popa -12FE: 3D 00 10 cmp ax, 4096 -1301: 77 04 ja .RS1?0sn -1303: 85 C0 test ax, ax -1305: 75 06 jnz @f -1307: C7 06 87 1A 00 02 mov word [ fat12_buffer.BPB_BytsPerSec ], 512 -130D: A3 87 1A mov word [ fat12_buffer.BPB_BytsPerSec ], ax -1310: 8B 7E F4 mov di, point_default -1313: 8B 4E FA mov cx, save_cx_d -1316: E8 5A F5 call get_firs_sym -1319: 85 C9 test cx, cx -131B: 74 47 jz .end_RamdiskCluster -131D: 3C 52 cmp al, 'R' -131F: 75 F5 jnz .start_RamdiskCluster -1321: 89 CB mov bx, cx -1323: 89 F8 mov ax, di -1325: BE FA 07 mov si, parse_RamdiskCluster -1328: B9 0E 00 mov cx, parse_RamdiskCluster_e - parse_RamdiskCluster -132B: F3 repe -132C: A6 cmpsb -132D: 75 2F jnz .RamdiskCluster_rest_val -132F: 83 EB 0E sub bx, parse_RamdiskCluster_e - parse_RamdiskCluster -1332: 01 CB add bx, cx -1334: 89 D9 mov cx, bx -1336: F7 46 F8 16 00 test status_flag, flag_found_RamdiskCluster -133B: 74 00 jz .correct_is_not_set_RamdiskCluster -133D: B8 20 3D mov ax, 0x3d20 -1340: F3 repe -1341: AE scasb -1342: E3 20 jcxz .end_get_RamSC_ERROR_1 -1344: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -1348: 75 CC jnz .start_RamdiskCluster -134A: F3 repe -134B: AE scasb -134C: 41 inc cx -134D: 4F dec di -134E: 26 0F B6 05 movzx ax, byte [ es : di ] -1352: 3C 30 cmp al, '0' -1354: 72 0E jb .end_RamdiskCluster -1356: 3C 39 cmp al, '9' -1358: 77 0A ja .end_RamdiskCluster -135A: 34 30 xor al, 0x30 -135C: EB 06 jmp .end_RamdiskCluster -135E: 89 D9 mov cx, bx -1360: 89 C7 mov di, ax -1362: EB B2 jmp .start_RamdiskCluster -1364: 60 pusha -1365: B9 0A 00 mov cx, 0x0a -1368: BF AA 05 mov di, RamdiskCluster_msg -136B: E8 B7 F4 call decode -136E: BE AA 05 mov si, RamdiskCluster_msg -1371: E8 D0 F4 call printplain -1374: 61 popa -1375: 3C 80 cmp al, 128 -1377: 77 6B ja @f -1379: A2 89 1A mov byte [ fat12_buffer.BPB_SecPerClus ], al -137C: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ] -1382: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] -1388: 66 0F AF D8 imul ebx, eax -138C: 66 8B 46 BA mov eax, save_ramdisksize -1390: 66 99 cdq -1392: 66 F7 FB idiv ebx -1395: 66 3D F5 0F 00 00 cmp eax, 4085 -139B: 0F 82 8E 00 jb .fat12?0so -139F: 66 3D F5 FF 00 00 cmp eax, 65525 -13A5: 72 18 jb .fat16?0sp -13A7: C7 46 B4 20 00 mov set_ramfs, 32 -13AC: C7 06 8A 1A 20 00 mov word [ fat12_buffer.BPB_RsvdSecCnt ], 32 -13B2: 66 31 C0 xor eax, eax -13B5: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax -13B8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax -13BB: 66 A3 9C 1A mov dword [ fat12_buffer.BPB_TotSec32 ], eax -13BF: EB FE jmp $ -13C1: C7 46 B4 10 00 mov set_ramfs, 16 -13C6: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] -13CC: 66 0F AF C3 imul eax, ebx -13D0: 66 3D 00 00 01 00 cmp eax, 0x10000 -13D6: 73 0C jae @f -13D8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax -13DB: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0 -13E4: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count -13EA: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax -13ED: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] -13F3: 66 6B C0 20 imul eax, 32 -13F7: 66 01 D8 add eax, ebx -13FA: 66 48 dec eax -13FC: 66 99 cdq -13FE: 66 F7 FB idiv ebx -1401: 66 0F B7 1E 8A 1A movzx ebx, word [ fat12_buffer.BPB_RsvdSecCnt ] -1407: 66 01 C3 add ebx, eax -140A: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ] -1410: 66 29 D8 sub eax, ebx -1413: 66 C1 E7 08 shl edi, 8 -1417: 66 0F B6 0E 8C 1A movzx ecx, byte [ fat12_buffer.BPB_NumFATs ] -141D: 66 01 CF add edi, ecx -1420: 66 01 F8 add eax, edi -1423: 66 48 dec eax -1425: 66 99 cdq -1427: 66 F7 FF idiv edi -142A: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax -142D: C7 46 B4 0C 00 mov set_ramfs, 12 -1432: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] -1438: 66 0F AF C3 imul eax, ebx -143C: 66 3D 00 00 01 00 cmp eax, 0x10000 -1442: 73 0C jae @f -1444: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax -1447: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0 -1450: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count -1456: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax -1459: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ] -145F: 66 6B C0 0C imul eax, 12 -1463: 66 C1 E8 03 shr eax, 3 -1467: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] -146D: 66 99 cdq -146F: 66 F7 FB idiv ebx -1472: 40 inc ax -1473: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax -1476: A1 92 1A mov ax, word [ fat12_buffer.BPB_FATSz16 ] -1479: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ] -147E: 0F AF C3 imul ax, bx -1481: 8B 1E 8D 1A mov bx, word [ fat12_buffer.BPB_RootEntCnt ] -1485: C1 EB 04 shr bx, 4 -1488: 01 D8 add ax, bx -148A: 89 5E B0 mov size_root_dir, bx -148D: 0F B6 1E 8A 1A movzx bx, byte [ fat12_buffer.BPB_RsvdSecCnt ] -1492: 01 D8 add ax, bx -1494: 89 46 AE mov firstDataSect, ax -1497: 8B 1E 8F 1A mov bx, word [ fat12_buffer.BPB_TotSec16 ] -149B: 29 C3 sub bx, ax -149D: 89 D8 mov ax, bx -149F: 0F B6 1E 89 1A movzx bx, byte [ fat12_buffer.BPB_SecPerClus ] -14A4: 99 cwd -14A5: F7 FB idiv bx -14A7: 89 46 AC mov DataClasters, ax -14AA: 60 pusha -14AB: 8B 46 AE mov ax, firstDataSect -14AE: B9 0A 00 mov cx, 0x0a -14B1: BF 44 06 mov di, firstDataSect_msg -14B4: E8 6E F3 call decode -14B7: BE 44 06 mov si, firstDataSect_msg -14BA: E8 87 F3 call printplain -14BD: 8B 46 B0 mov ax, size_root_dir -14C0: B9 0A 00 mov cx, 0x0a -14C3: BF 79 06 mov di, size_root_dir_msg -14C6: E8 5C F3 call decode -14C9: BE 79 06 mov si, size_root_dir_msg -14CC: E8 75 F3 call printplain -14CF: 8B 46 AC mov ax, DataClasters -14D2: B9 0A 00 mov cx, 0x0a -14D5: BF 9B 06 mov di, DataClasters_msg -14D8: E8 4A F3 call decode -14DB: BE 9B 06 mov si, DataClasters_msg -14DE: E8 63 F3 call printplain -14E1: 61 popa -14E2: A0 91 1A mov al, byte [ fat12_buffer.BPB_Media ] -14E5: 1E push ds -14E6: 8B 7E C4 mov di, info_real_mode_size -14E9: 81 C7 00 10 add di, 0x1000 -14ED: 57 push di -14EE: 31 FF xor di, di -14F0: 89 7E AA mov point_to_free_root, di -14F3: 1F pop ds -14F4: 88 05 mov byte [ di ], al -14F6: 83 C8 FF or ax, - 1 -14F9: 47 inc di -14FA: 89 05 mov word [ di ], ax -14FC: 1F pop ds -14FD: C7 46 B2 03 00 mov point_next_fat_str, 3 -1502: 60 pusha -1503: 8B 46 B2 mov ax, point_next_fat_str -1506: B9 0A 00 mov cx, 0x0a -1509: BF DA 05 mov di, fat_create_msg -150C: E8 16 F3 call decode -150F: BE DA 05 mov si, fat_create_msg -1512: E8 2F F3 call printplain -1515: 61 popa -1516: B8 7C 1A mov ax, fat12_buffer -1519: BE 3C 1A mov si, table_15_87 -151C: 01 44 12 add word [ si + 8 * 2 + 2 ], ax -151F: 06 push es -1520: 1E push ds -1521: 07 pop es -1522: B9 1F 00 mov cx, 31 -1525: B4 87 mov ah, 0x87 -1527: CD 15 int 0x15 -1529: 07 pop es -152A: 60 pusha -152B: 8B 44 12 mov ax, word [ si + 8 * 2 + 2 ] -152E: B9 0A 00 mov cx, 0x0a -1531: BF 0E 06 mov di, BPB_msg -1534: E8 EE F2 call decode -1537: BE 0E 06 mov si, BPB_msg -153A: E8 07 F3 call printplain -153D: 61 popa -153E: 8B 7E F4 mov di, point_default -1541: 8B 4E FA mov cx, save_cx_d -1544: C7 46 A6 00 00 mov data_offset, 0 -1549: E8 27 F3 call get_firs_sym -154C: 85 C9 test cx, cx -154E: 0F 84 B3 03 jz ._end?1D2 -1552: 3C 52 cmp al, 'R' -1554: 75 F3 jnz .start_loop?1D1 -1556: 89 CB mov bx, cx -1558: 89 F8 mov ax, di -155A: BE 1A 08 mov si, parse_RamdiskFile -155D: B9 0B 00 mov cx, parse_RamdiskFile_e - parse_RamdiskFile -1560: F3 repe -1561: A6 cmpsb -1562: 0F 85 98 03 jnz .rest_value_loop?1D3 -1566: 83 EB 0B sub bx, parse_RamdiskFile_e - parse_RamdiskFile -1569: 01 CB add bx, cx -156B: 89 D9 mov cx, bx -156D: B8 20 3D mov ax, 0x3d20 -1570: F3 repe -1571: AE scasb -1572: 66 85 C9 test ecx, ecx -1575: 0F 84 85 03 jz .rest_value_loop?1D3 -1579: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -157D: 0F 85 7D 03 jnz .rest_value_loop?1D3 -1581: F3 repe -1582: AE scasb -1583: 41 inc cx -1584: 4F dec di -1585: 89 7E A2 mov save_di_RAMDISK, di -1588: 89 4E A0 mov save_cx_RAMDISK, cx -158B: 26 8A 05 mov al, byte [ es : di ] -158E: 3C 2C cmp al, ',' -1590: 74 04 jz .found_end_str -1592: 47 inc di -1593: 49 dec cx -1594: 75 F5 jnz @b -1596: 89 7E A8 mov point_to_dest_file_name, di -1599: 47 inc di -159A: BE BA 1A mov si, shot_name_fat -159D: 83 4E A4 FF or first_input, - 1 -15A1: B9 0B 00 mov cx, 11 -15A4: 26 8A 05 mov al, byte [ es : di ] -15A7: 3C 0A cmp al, 0xa -15A9: 74 7D jz .st4_s?1GP -15AB: 3C 0D cmp al, 0xd -15AD: 74 79 jz .st4_s?1GP -15AF: 3C 20 cmp al, 0x20 -15B1: 74 75 jz .st4_s?1GP -15B3: 3C 20 cmp al, 0x20 -15B5: 72 7A jb .error?1GK -15B7: 3C 22 cmp al, 0x22 -15B9: 74 76 jz .error?1GK -15BB: 3C 2A cmp al, 0x2a -15BD: 74 72 jz .error?1GK -15BF: 3C 2B cmp al, 0x2b -15C1: 74 6E jz .error?1GK -15C3: 3C 2C cmp al, 0x2c -15C5: 74 6A jz .error?1GK -15C7: 3C 2F cmp al, 0x2F -15C9: 74 66 jz .error?1GK -15CB: 3C 3A cmp al, 0x3a -15CD: 74 62 jz .error?1GK -15CF: 3C 3B cmp al, 0x3b -15D1: 74 5E jz .error?1GK -15D3: 3C 3C cmp al, 0x3c -15D5: 74 5A jz .error?1GK -15D7: 3C 3D cmp al, 0x3d -15D9: 74 56 jz .error?1GK -15DB: 3C 3E cmp al, 0x3E -15DD: 74 52 jz .error?1GK -15DF: 3C 3F cmp al, 0x3F -15E1: 74 4E jz .error?1GK -15E3: 3C 5B cmp al, 0x5b -15E5: 74 4A jz .error?1GK -15E7: 3C 5C cmp al, 0x5c -15E9: 74 46 jz .error?1GK -15EB: 3C 5D cmp al, 0x5d -15ED: 74 42 jz .error?1GK -15EF: 3C 7C cmp al, 0x7c -15F1: 74 3E jz .error?1GK -15F3: 83 7E A4 FF cmp first_input, - 1 -15F7: 75 08 jnz .next_step?1GJ -15F9: 83 66 A4 00 and first_input, 0 -15FD: 3C 2E cmp al, '.' -15FF: 74 30 jz .error?1GK -1601: 3C 2E cmp al, 0x2e -1603: 75 13 jnz .st2?1GM -1605: B0 20 mov al, ' ' -1607: 80 F9 03 cmp cl, 3 -160A: 76 0C jbe .st2?1GM -160C: 88 04 mov byte [ si ], al -160E: 46 inc si -160F: 49 dec cx -1610: 83 F9 03 cmp cx, 3 -1613: 77 F7 ja .st3?1GO -1615: 47 inc di -1616: EB 8C jmp @b -1618: 3C 60 cmp al, 0x60 -161A: 76 02 jbe .st2_l?1GN -161C: 34 20 xor al, 0x20 -161E: 88 04 mov byte [ si ], al -1620: 47 inc di -1621: 46 inc si -1622: E2 80 loop @b -1624: 31 C0 xor ax, ax -1626: EB 0C jmp @f -1628: B0 20 mov al, ' ' -162A: 88 04 mov byte [ si ], al -162C: 46 inc si -162D: E2 FB loop .st4?1GQ -162F: EB F3 jmp .st5?1GR -1631: 83 C8 FF or ax, - 1 -1634: 60 pusha -1635: B9 0A 00 mov cx, 0x0a -1638: BF F5 06 mov di, convertion_file_name_msg -163B: E8 E7 F1 call decode -163E: BE F5 06 mov si, convertion_file_name_msg -1641: E8 00 F2 call printplain -1644: BE BA 1A mov si, shot_name_fat -1647: C6 44 0C 00 mov byte [ si + 12 ], 0 -164B: E8 F6 F1 call printplain -164E: 61 popa -164F: 85 C0 test ax, ax -1651: 75 39 jnz .exit?1GI -1653: BE BA 1A mov si, shot_name_fat -1656: 8B 7E AE mov di, firstDataSect -1659: 2B 7E B0 sub di, size_root_dir -165C: C1 E7 09 shl di, 9 -165F: BA E0 00 mov dx, root_dir_entry_count -1662: 8B 46 C4 mov ax, info_real_mode_size -1665: 05 00 10 add ax, 0x1000 -1668: 8E E8 mov gs, ax -166A: B9 0B 00 mov cx, 11 -166D: 8A 00 mov al, byte [ ds : si + bx ] -166F: 65 8A 21 mov ah, byte [ gs : di + bx ] -1672: 43 inc bx -1673: 38 C4 cmp ah, al -1675: 75 07 jnz .no_equal?1GH -1677: E2 F4 loop @b -1679: 83 C8 FF or ax, - 1 -167C: EB 0E jmp .exit?1GI -167E: B9 0B 00 mov cx, 11 -1681: 31 DB xor bx, bx -1683: 83 C7 20 add di, 32 -1686: 4A dec dx -1687: 75 E4 jnz @b -1689: 83 E0 00 and ax, 0 -168C: 60 pusha -168D: B9 0A 00 mov cx, 0x0a -1690: BF B9 06 mov di, check_name_fat_msg -1693: 66 C7 05 20 20 20 20 mov dword [ di ], ' ' -169A: C7 45 04 20 20 mov word [ di + 4 ], ' ' -169F: E8 83 F1 call decode -16A2: BE B9 06 mov si, check_name_fat_msg -16A5: E8 9C F1 call printplain -16A8: 61 popa -16A9: 8B 7E A2 mov di, save_di_RAMDISK -16AC: 8B 4E A0 mov cx, save_cx_RAMDISK -16AF: 84 C0 test al, al -16B1: 0F 85 94 FE jnz .start_loop?1D1 -16B5: 26 66 FF 75 FA push dword [ es : di - 6 ] -16BA: 8D 75 FA lea si, [ di - 6 ] -16BD: 26 FF 75 FE push word [ es : di - 2 ] -16C1: 57 push di -16C2: 31 C0 xor ax, ax -16C4: 26 89 45 FA mov word [ es : di - 6 ], ax -16C8: 8B 46 C4 mov ax, info_real_mode_size -16CB: 26 89 45 FC mov word [ es : di - 4 ], ax -16CF: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16 -16D5: 8B 7E A8 mov di, point_to_dest_file_name -16D8: 26 FF 35 push word [ es : di ] -16DB: 51 push cx -16DC: 31 C0 xor ax, ax -16DE: 26 89 05 mov word [ es : di ], ax -16E1: 57 push di -16E2: 89 F7 mov di, si -16E4: 40 inc ax -16E5: 56 push si -16E6: 06 push es -16E7: 55 push bp -16E8: 06 push es -16E9: 1F pop ds -16EA: 0E push cs -16EB: 07 pop es -16EC: 26 FF 1E DC 0A call far dword [ es : loader_callback ] -16F1: 0E push cs -16F2: 1F pop ds -16F3: 5D pop bp -16F4: 07 pop es -16F5: 5E pop si -16F6: 83 FB 02 cmp bx, 2 -16F9: 0F 87 01 02 ja .error?1D4 -16FD: 89 5E 9E mov status_flag_loader_f, bx -1700: 66 C1 E2 10 shl edx, 16 -1704: 89 C2 mov dx, ax -1706: 66 89 56 B6 mov save_file_size, edx -170A: 66 89 D0 mov eax, edx -170D: 5F pop di -170E: 59 pop cx -170F: 26 8F 05 pop word [ es : di ] -1712: 5F pop di -1713: 26 8F 45 FE pop word [ es : di - 2 ] -1717: 26 66 8F 45 FA pop dword [ es : di - 6 ] -171C: 60 pusha -171D: B9 0A 00 mov cx, 0x0a -1720: BF C1 05 mov di, RamdiskFile_msg -1723: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' ' -172A: E8 F8 F0 call decode -172D: BE C1 05 mov si, RamdiskFile_msg -1730: E8 11 F1 call printplain -1733: 61 popa -1734: 06 push es -1735: 8B 46 C4 mov ax, info_real_mode_size -1738: 05 00 10 add ax, 0x1000 -173B: 8E C0 mov es, ax -173D: 8B 7E AE mov di, firstDataSect -1740: 2B 7E B0 sub di, size_root_dir -1743: C1 E7 09 shl di, 9 -1746: 03 7E AA add di, point_to_free_root -1749: BE BA 1A mov si, shot_name_fat -174C: B9 0B 00 mov cx, 11 -174F: AC lodsb -1750: AA stosb -1751: E2 FC loop @b -1753: 31 C0 xor ax, ax -1755: B4 08 mov ah, ATTR_VOLUME_ID -1757: 26 89 05 mov word [ es : di ], ax -175A: 83 C7 02 add di, 2 -175D: 26 C6 05 64 mov byte [ es : di ], 100 -1761: 47 inc di -1762: 26 C7 05 2B 03 mov word [ es : di ], 0x032b -1767: 83 C7 02 add di, 2 -176A: 26 C7 05 00 00 mov word [ es : di ], 0x0 -176F: 83 C7 02 add di, 2 -1772: 26 C7 05 2B 03 mov word [ es : di ], 0x032b -1777: 83 C7 02 add di, 2 -177A: 26 C7 05 00 00 mov word [ es : di ], 0x0 -177F: 83 C7 02 add di, 2 -1782: 26 C7 05 00 00 mov word [ es : di ], 0x0 -1787: 83 C7 02 add di, 2 -178A: 26 C7 05 2B 03 mov word [ es : di ], 0x032b -178F: 83 C7 02 add di, 2 -1792: 8B 46 B2 mov ax, point_next_fat_str -1795: 26 89 05 mov word [ es : di ], ax -1798: 83 C7 02 add di, 2 -179B: 57 push di -179C: 89 C3 mov bx, ax -179E: D1 EB shr bx, 1 -17A0: 01 D8 add ax, bx -17A2: 8B 1E 87 1A mov bx, word [ fat12_buffer.BPB_BytsPerSec ] -17A6: 99 cwd -17A7: F7 FB idiv bx -17A9: 89 C6 mov si, ax -17AB: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ] -17B1: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ] -17B7: 66 0F AF C3 imul eax, ebx -17BB: 66 8B 5E B6 mov ebx, save_file_size -17BF: 66 29 C3 sub ebx, eax -17C2: 66 39 C3 cmp ebx, eax -17C5: 76 29 jbe .eof_file?1US -17C7: FF 46 B2 inc point_next_fat_str -17CA: 8B 4E B2 mov cx, point_next_fat_str -17CD: 89 C2 mov dx, ax -17CF: D1 EA shr dx, 1 -17D1: 01 D1 add cx, dx -17D3: F7 C6 01 00 test si, 0x1 -17D7: 74 0B jz .step2?1UP -17D9: C1 E1 04 shl cx, 4 -17DC: 26 89 0C mov word [ es : si ], cx -17DF: 46 inc si -17E0: 01 C1 add cx, ax -17E2: EB DB jmp @b -17E4: 81 E1 FF 0F and cx, 0x0FFF -17E8: 26 89 0C mov word [ es : si ], cx -17EB: 46 inc si -17EC: 01 C1 add cx, ax -17EE: EB CF jmp @b -17F0: B9 FF 0F mov cx, 0x0fff -17F3: F7 C6 01 00 test si, 0x1 -17F7: 74 08 jz .step3?1UQ -17F9: C1 E1 04 shl cx, 4 -17FC: 26 89 0C mov word [ es : si ], cx -17FF: EB 07 jmp .end?1UR -1801: 81 E1 FF 0F and cx, 0x0FFF -1805: 26 89 0C mov word [ es : si ], cx -1808: FF 46 B2 inc point_next_fat_str -180B: 5F pop di -180C: 66 8B 46 B6 mov eax, save_file_size -1810: 26 66 89 05 mov dword [ es : di ], eax -1814: 66 60 pushad -1816: 8B 7E AE mov di, firstDataSect -1819: 2B 7E B0 sub di, size_root_dir -181C: C1 E7 09 shl di, 9 -181F: 03 7E AA add di, point_to_free_root -1822: BE C6 1A mov si, dest_name_fat -1825: B9 0B 00 mov cx, 11 -1828: 26 8A 05 mov al, byte [ es : di ] -182B: 47 inc di -182C: 88 04 mov byte [ ds : si ], al -182E: 46 inc si -182F: E2 F7 loop @b -1831: 31 C0 xor ax, ax -1833: 88 04 mov byte [ si ], al -1835: BE C6 1A mov si, dest_name_fat -1838: E8 09 F0 call printplain -183B: 66 61 popad -183D: 83 46 AA 20 add point_to_free_root, 32 -1841: 07 pop es -1842: 8B 46 C4 mov ax, info_real_mode_size -1845: BE 3C 1A mov si, table_15_87 -1848: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax -184B: 66 0F B7 46 AE movzx eax, firstDataSect -1850: 66 0F B7 56 A6 movzx edx, data_offset -1855: 66 01 D0 add eax, edx -1858: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ] -185E: 66 0F B6 16 89 1A movzx edx, byte [ fat12_buffer.BPB_SecPerClus ] -1864: 0F AF DA imul bx, dx -1867: 66 53 push ebx -1869: 66 0F AF C3 imul eax, ebx -186D: 60 pusha -186E: B9 0A 00 mov cx, 0x0a -1871: BF 07 04 mov di, show_db1 -1874: E8 AE EF call decode -1877: BE 07 04 mov si, show_db1 -187A: E8 C7 EF call printplain -187D: 61 popa -187E: B2 10 mov dl, 0x10 -1880: 66 3D 00 00 01 00 cmp eax, 0x00010000 -1886: 72 0A jb @f -1888: 66 2D 00 00 01 00 sub eax, 0x00010000 -188E: FE C2 inc dl -1890: EB EE jmp @b -1892: 88 54 1B mov byte [ si + 8 * 3 + 3 ], dl -1895: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax -1898: 66 8B 4E B6 mov ecx, save_file_size -189C: 66 81 F9 FF FF 00 00 cmp ecx, 0x0000ffff -18A3: 76 0A jbe .correct_on_byte?1cJ -18A5: 66 B9 00 00 01 00 mov ecx, 0x00010000 -18AB: 66 29 4E B6 sub save_file_size, ecx -18AF: 66 58 pop eax -18B1: 66 51 push ecx -18B3: FF 46 A6 inc data_offset -18B6: 66 39 C8 cmp eax, ecx -18B9: 73 05 jae @f -18BB: 66 29 C1 sub ecx, eax -18BE: EB F3 jmp @b -18C0: 66 59 pop ecx -18C2: 66 F7 C1 01 00 00 00 test ecx, 0x1 -18C9: 74 02 jz .st1?1cI -18CB: 66 41 inc ecx -18CD: 66 D1 E9 shr ecx, 1 -18D0: 06 push es -18D1: 1E push ds -18D2: 07 pop es -18D3: B4 87 mov ah, 0x87 -18D5: CD 15 int 0x15 -18D7: 07 pop es -18D8: 60 pusha -18D9: B9 0A 00 mov cx, 0x0a -18DC: BF 46 07 mov di, return_code_af_move -18DF: E8 43 EF call decode -18E2: BE 46 07 mov si, return_code_af_move -18E5: E8 5C EF call printplain -18E8: 61 popa -18E9: 83 7E 9E 01 cmp status_flag_loader_f, 0x1 -18ED: 75 00 jnz @f -18EF: 8B 7E A2 mov di, save_di_RAMDISK -18F2: 8B 4E A0 mov cx, save_cx_RAMDISK -18F5: 60 pusha -18F6: 31 C0 xor ax, ax -18F8: CD 16 int 0x16 -18FA: 61 popa -18FB: E9 4B FC jmp .start_loop?1D1 -18FE: 89 C7 mov di, ax -1900: 89 D9 mov cx, bx -1902: E9 44 FC jmp .start_loop?1D1 -1905: 8B 46 C4 mov ax, info_real_mode_size -1908: 05 00 10 add ax, 0x1000 -190B: BE 3C 1A mov si, table_15_87 -190E: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax -1911: B8 00 02 mov ax, 512 -1914: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax -1917: 66 0F B7 0E 92 1A movzx ecx, word [ fat12_buffer.BPB_FATSz16 ] -191D: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ] -1922: 0F AF CB imul cx, bx -1925: 03 4E B0 add cx, size_root_dir -1928: 66 C1 E1 09 shl ecx, 9 -192C: 66 F7 C1 01 00 00 00 test ecx, 0x1 -1933: 74 02 jz .st1?1ho -1935: 66 41 inc ecx -1937: 66 D1 E9 shr ecx, 1 -193A: 06 push es -193B: 1E push ds -193C: 07 pop es -193D: B4 87 mov ah, 0x87 -193F: CD 15 int 0x15 -1941: 07 pop es -1942: 60 pusha -1943: B9 0A 00 mov cx, 0x0a -1946: BF 77 07 mov di, return_code_af_fat_m -1949: E8 D9 EE call decode -194C: BE 77 07 mov si, return_code_af_fat_m -194F: E8 F2 EE call printplain -1952: 61 popa -1953: 60 pusha -1954: B9 0A 00 mov cx, 0x0a -1957: BF 07 04 mov di, show_db1 -195A: E8 C8 EE call decode -195D: BE 07 04 mov si, show_db1 -1960: E8 E1 EE call printplain -1963: 61 popa -1964: 60 pusha -1965: BE 21 07 mov si, make_fat12_RFS_msg -1968: E8 D9 EE call printplain -196B: 61 popa -196C: EB 1F jmp ._end_parse_FRS -196E: 89 D9 mov cx, bx -1970: 89 C7 mov di, ax -1972: BE 0B 08 mov si, parse_RFS_KRFS -1975: B9 04 00 mov cx, parse_RFS_KRFS_e - parse_RFS_KRFS -1978: F3 repe -1979: A6 cmpsb -197A: EB 11 jmp ._end_parse_FRS -197C: 89 D9 mov cx, bx -197E: 89 C7 mov di, ax -1980: E9 A4 F8 jmp .start_g_tpe_RFS -1983: 83 4E C0 01 or show_errors_sect, show_error_1 -1987: EB 04 jmp ._end_parse_FRS -1989: 83 4E C0 02 or show_errors_sect, show_error_2 -198D: 60 pusha -198E: BE 34 07 mov si, get_type_FS_msg -1991: E8 B0 EE call printplain -1994: 61 popa -1995: 31 C0 xor ax, ax -1997: CD 16 int 0x16 -1999: 8B 7E F4 mov di, point_default -199C: 8B 4E FA mov cx, save_cx_d -199F: E8 D1 EE call get_firs_sym -19A2: 85 C9 test cx, cx -19A4: 0F 84 8E 00 jz ._afterLoaderModule -19A8: 3C 4C cmp al, 'L' -19AA: 75 F3 jnz .start_p_LM -19AC: 89 CB mov bx, cx -19AE: 89 F8 mov ax, di -19B0: BE CD 07 mov si, parse_LoaderModule -19B3: B9 0C 00 mov cx, parse_LoaderModule_e - parse_LoaderModule -19B6: F3 repe -19B7: A6 cmpsb -19B8: 75 75 jnz .rest_value_loop_LM -19BA: 83 EB 0C sub bx, parse_LoaderModule_e - parse_LoaderModule -19BD: 01 CB add bx, cx -19BF: 89 D9 mov cx, bx -19C1: F7 46 F8 01 00 test status_flag, flag_found_LM -19C6: 74 00 jz .correct_is_not_set_LM -19C8: B8 20 3D mov ax, 0x3d20 -19CB: F3 repe -19CC: AE scasb -19CD: E3 60 jcxz .rest_value_loop_LM -19CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ] -19D3: 75 5A jnz .rest_value_loop_LM -19D5: F3 repe -19D6: AE scasb -19D7: 41 inc cx -19D8: 4F dec di -19D9: 26 66 FF 75 FA push dword [ es : di - 6 ] -19DE: 8D 75 FA lea si, [ di - 6 ] -19E1: 26 FF 75 FE push word [ es : di - 2 ] -19E5: 31 C0 xor ax, ax -19E7: 26 89 45 FA mov word [ es : di - 6 ], ax -19EB: 8B 46 C4 mov ax, info_real_mode_size -19EE: 26 89 45 FC mov word [ es : di - 4 ], ax -19F2: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16 -19F8: 26 8A 05 mov al, byte [ es : di ] -19FB: 3C 20 cmp al, ' ' -19FD: 74 0C jz .found_end_str?1mb -19FF: 3C 0A cmp al, 0xa -1A01: 74 08 jz .found_end_str?1mb -1A03: 3C 0D cmp al, 0xd -1A05: 74 04 jz .found_end_str?1mb -1A07: 47 inc di -1A08: 49 dec cx -1A09: 75 ED jnz @b -1A0B: 26 FF 35 push word [ es : di ] -1A0E: 31 C0 xor ax, ax -1A10: 26 89 05 mov word [ es : di ], ax -1A13: 89 F7 mov di, si -1A15: 40 inc ax -1A16: 56 push si -1A17: 06 push es -1A18: 06 push es -1A19: 1F pop ds -1A1A: 0E push cs -1A1B: 07 pop es -1A1C: 26 FF 1E DC 0A call far dword [ es : loader_callback ] -1A21: 0E push cs -1A22: 1F pop ds -1A23: 07 pop es -1A24: 5E pop si -1A25: 85 DB test bx, bx -1A27: 75 03 jnz .error_LM -1A29: 26 FF 2C jmp far dword [ es : si ] -1A2C: E8 91 F0 call error.LoaderModule -1A2F: 89 C7 mov di, ax -1A31: 89 D9 mov cx, bx -1A33: E9 69 FF jmp .start_p_LM -1A36: EB FE jmp $ -1A38: E9 6A F1 jmp ini_loaded -1A3C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 -1A44: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 -1A4C: FF FF db 0xff, 0xff -1A4E: 00 10 db 0x0, 0x10 -1A50: 00 93 00 00 db 0x00, 0x93, 0x0, 0x0 -1A54: FF FF 00 00 10 93 00 00 db 0xff, 0xff, 0x0, 0x00, 0x10, 0x93, 0x0, 0x0 -1A5C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 -1A64: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 -1A6C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 -1A74: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0 -1A7C: 90 90 90 .BS_jmpBoot db 0x90, 0x90, 0x90 -1A7F: 4B 20 53 79 53 20 36 34 .BS_OEMName db 'K SyS 64' -1A87: 00 02 .BPB_BytsPerSec dw 512 -1A89: 01 .BPB_SecPerClus db 0x1 -1A8A: 01 00 .BPB_RsvdSecCnt dw 0x1 -1A8C: 01 .BPB_NumFATs db 0x1 -1A8D: 00 02 .BPB_RootEntCnt dw 512 -1A8F: 00 00 .BPB_TotSec16 dw 0x0 -1A91: F0 .BPB_Media db 0xF0 -1A92: 00 00 .BPB_FATSz16 dw 0x0 -1A94: 00 00 .BPB_SecPerTrk dw 0x0 -1A96: 00 00 .BPB_NumHeads dw 0x0 -1A98: 00 00 00 00 .BPB_HiddSec dd 0x0 -1A9C: 00 00 00 00 .BPB_TotSec32 dd 0x0 -1AA0: 52 .BS_DrvNum db 'R' -1AA1: 00 .BS_Reserved1 db 0x0 -1AA2: 29 .BS_BootSig db 0x29 -1AA3: 52 46 4B 53 .BS_VolID db 'RFKS' -1AA7: 52 41 4D 20 44 49 53 4B 20 46 53 .BS_VolLab db 'RAM DISK FS' -1AB2: 46 41 54 31 32 20 20 20 .BS_FilSysType db 'FAT12 ' -1ABA: shot_name_fat rb 11 -1AC5: rb 1 -1AC6: dest_name_fat rb 12 -1AD2: value_timeout rw 1 -1AD4: old_timer rd 1 -1AD8: start_timer rd 1 -1ADC: timer_ rd 1 -1AE0: start_stack rw 1 -1AE2: save_bp_from_timer rw 1 -3 passes, 0.8 seconds, 6842 bytes. diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse.inc deleted file mode 100644 index 72c1e7e9ea..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse.inc +++ /dev/null @@ -1,118 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; Модуль парсинга - это стандартный компонент, встраиваемый во вторичный загрузчик. -; Данный модуль позволяет стандартно произвести разбор ini файла -; (и с использованием полученных данных ОС будет загружаться дальше). -; В начале найдем открывающий "[" - это будет указывать на начало -; секции. Поддерживается 1 секция это [loader], остальные секции могут иметь -; любые имена, но они должны быть заключены в в скобки [] -macro use_parse -{ -;input cx=size of ini file -parse_start: -;es:di as 2000:0000 new segment -;установим указатель на загруженный блок - enter 256, 0 ;set 16 byte for current task in stack -;we are is not use bp because bp is pointer on array 16 byte - mov word [save_bp_from_timer], bp ;save point to own data array - mov save_cx, cx ;it's placed size of ini file - les di, dword [file_data] -;обнулим все переменные выделенные из стека -;init flag - xor ax, ax - mov status_flag, ax -;set data size - mov info_real_mode_size, ini_data_ +0x1000 ;изменим значение занятости памяти - -;поиск начала блока. -;///////////check [loader] - cld - - mov ret_on_ch, .start ;set return - mov al, byte [es:di] - push word .first_ret - cmp al, ' ' - jz .first_sp_1 - jmp get_firs_sym.not_space -.first_sp_1: - jmp get_firs_sym.first_sp - -.start: - call get_firs_sym ;get first symbol on new line -.first_ret: ;первый возврат -; jcxz .end_file ;.end_loader ;found or not found parametrs in section exit in section - test cx, cx - jz error.not_loader - cmp al, '[' - jz .parse_loader - jmp .start -;////// проверка на наличее секции loader -use_parse_loader -;pause -if DEBUG - xor ax, ax - int 16h -end if -;////// вывод графического экрана, выбор, секции под дефолту -use_any_sec -;парсинг выбраной или дефолтной секции т.е. разбор параметров выполнение сценария -use_parse_def_sect - -;////////////////// -;/end parse block -;////////////////// -;.end_bl: -; mov cx,bx -; -; jmp .start - -.exit: - -; mov si,parse_ini_end -; call printplain -; -;if DEBUG -; pusha -; mov ax,cx -; mov cx,0x0a -; mov di,show_db1_dec -; mov dword[ds:di],' ' -; call decode -;Show size -; mov si,show_db1 -; call printplain -; -; popa -;end if - jmp $ - -;///////////////////procedure ////////// -;input es:di - is pointer to date -;cx - counter -;return: cx - status if =0 - end of date else es:di point to first symbol on new line - -} diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_any.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_any.inc deleted file mode 100644 index f85fef13dd..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_any.inc +++ /dev/null @@ -1,686 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -;тут распологается модуль с помощью которого будут парситься все остальные секции -color_sym_black equ 0 -color_sym_blue equ 1 -color_sym_green equ 2 -color_sym_turquoise equ 3 -color_sym_red equ 4 - -color_sym_lightgray equ 7 - -color_sym_lightblue equ 9 -color_sym_lettuce equ 10 -color_sym_pink equ 12 -color_sym_yellow equ 14 - -macro use_any_sec -{ -;узнаем работу предыдущего шага т.е. чему = timeout, если он 0, то визуальная часть не будет отображена на дисплее с выбором загрузочных секций. -;иначе мы ее должны отобразить и ждать заявленое время для выбора и конигурирования пукнктов секции от пользователя. - -if DEBUG - pusha - mov ax, word [value_timeout];идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти -; mov ax,cx - mov cx, 0x0a - mov di, show_db1 - mov dword[ds:di], ' ' - mov word [ds:di+4], ' ' - call decode -;Show size - mov si, show_db1 - call printplain -; - popa -end if - - test ax, ax - jz .parse_run_only - -;отобразим полный список всех найденых секций. -if DEBUG - pusha - mov si, show_all_sect - call printplain - popa -end if -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование - out 0x60, al - xor cx, cx -.wait_loop: ; variant 2 -; reading state of port of 8042 controller - in al, 64h - and al, 00000010b ; ready flag -; wait until 8042 controller is ready - loopnz .wait_loop - - -; set keyboard typematic rate & delay - mov al, 0xf3 - out 0x60, al - xor cx, cx -@@: - in al, 64h - test al, 2 - loopnz @b - mov al, 0 - out 0x60, al - xor cx, cx -@@: - in al, 64h - test al, 2 - loopnz @b -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; get start time - call gettime - mov dword [start_timer], eax - mov word [timer_], newtimer - mov word [timer_+2], cs -;установить свое прерывание на таймер т.е. код будет перрываться ~18 раз в сек и переходить на обработчик - cli - push 0 - pop es - push dword [es:8*4] - pop dword [old_timer] - push dword [timer_] - pop dword [es:8*4] - sti - -;процедура формирования буфера для скролинга секций -;if DEBUG -; pusha -; mov ax,point_default -; mov ax,cx -; mov cx,0x0a -; mov di,show_db1 -; mov dword[ds:di],' ' -; mov word [ds:di+4],' ' -; call decode -;Show size -; mov si,show_db1 -; call printplain -; -; xor ax,ax -; int 0x16 -; popa -;end if -;;;;;;;;;;;;;размер предыдущей сеции установим =0 - mov save_descript_size, 18 -;отобразить black screen -show_bl_sc ;es=0xb800 -.show_all_scr: -get_frame_buffer ;es=0x2000 -;отображение секций - call show_bl_sc_sect ;es=0xb800 -;отобразить активный курсор -.show_active_cursor: -show_act_cursor -show_descript ;макрос по отображению описания секции - -;отобразить Press any key .... - mov eax, dword [old_timer] - cmp eax, dword [timer_] - jz .interrupt_16 - -show_timer_message - mov word [start_stack], sp -.interrupt_16: - xor ax, ax ;получим информацию о том что нажато - int 0x16 -;check on change - mov ebx, dword [old_timer] - cmp ebx, dword [timer_] - jz @f -;restore timer interrupt - cli - push 0 - pop es -; mov eax,dword [old_timer] ; восстановим прежднее прерывание - mov [es:8*4], ebx - mov dword [timer_], ebx - sti - - push ax -clear_timer_msg - pop ax -@@: - call clean_active_cursor ;clean old cursor ;es=0xb800 - - cmp ah, 0x48 ;реакция системы на события - jz .up - cmp ah, 0x50 - jz .down - cmp ah, 0x49 - jz .pgup - cmp ah, 0x51 - jz .pgdown - cmp ah, 0x47 - jz .home - cmp ah, 0x4f - jz .end - - cmp al, 0xD - jnz .show_active_cursor - - jmp .end_show_all ;парсинг секции которая указана в point_default -.up: - mov si, point_to_point_def ;значение указателя - add si, 2 - lea ax, point_to_hframe - - cmp si, ax - ja @f - - mov point_to_point_def, si - mov ax, [si] - mov point_default, ax - jmp .show_active_cursor -@@: - call find_before_sect - jmp .show_all_scr - - - -.down: - mov si, point_to_point_def ;значение указателя - mov ax, point_to_eframe ;указатель на последний элемент - sub si, 2 - cmp si, ax - jb @f - - mov point_to_point_def, si - mov ax, [si] - mov point_default, ax - jmp .show_active_cursor - -@@: - call find_next_sect - jmp .show_all_scr - -.pgup: - mov cx, size_show_section -@@: - push cx - call find_before_sect - pop cx - loop @b - jmp .show_all_scr - - -.pgdown: - mov cx, size_show_section -@@: - push cx - call find_next_sect - pop cx - loop @b - jmp .show_all_scr - -.home: - xor di, di - call find_next_sect.h - jmp .show_all_scr - -.end: - mov di, save_cx - call find_before_sect.e - jmp .show_all_scr - - - - -; тут мы будем парсить только дефолтную секцию и выполнять ее ничего не предлагая пользователю из диалогов. -.parse_run_only: -if DEBUG - pusha - mov si, no_show_only_w - call printplain - popa -end if - - -.end_show_all: -} - - - - - - - - - - - - - - - -;show black screen SL -macro show_bl_sc -{ -;;;;;;;;;;;;;;; -;очистим экран и выведем меню -; draw frames - xor ax, ax -if DEBUG - mov ax, 0x0720 -end if - push 0xb800 - pop es - xor di, di -; draw top - mov cx, 25 * 80 - rep stosw -;;;;;;;;;;;;;;;;;;;;;;; show 'Secondary Loader v0.xxx' - mov di, 164 - mov si, version - mov cx, version_end-version - mov ah, color_sym_yellow -@@: - lodsb - stosw - loop @b -;;;;;;;;;;;;;;;;;;;;;;; show firm )) - mov di, (2*160-(2*(soft_mes_end-soft_mes+4))) ;286 - mov ah, color_sym_pink;color_sym_red - mov al, 'K' - stosw - mov al, ' ' - stosw - mov ah, color_sym_lightgray;color_sym_lightblue;color_sym_pink - mov si, soft_mes - mov cx, soft_mes_end- soft_mes -@@: - lodsb - stosw - loop @b -;;;;;;;;;;;;;;;;;;;;;;; show '__________________________' - mov di, 480 - mov ah, color_sym_yellow - mov al, 0xC4 ; '─' - mov cx, 61 - rep stosw -;;;;;;;;;;;;;;;;;;;;;;; show 'Select section' - mov di, 804 - mov si, select_section - mov cx, select_section_end - select_section - mov ah, color_sym_lightgray -@@: - lodsb - stosw - loop @b -;;;;;;;;;;;;;;;;;;;;;;; show 'Section description' - mov di, 880 - mov si, section_description - mov cx, section_description_end - section_description -; mov ah,color_sym_lightgray -@@: - lodsb - stosw - loop @b - -} - -macro show_timer_message -{ -;;;;;;;;;;;;;;;;;;;;; show Press any key -;;;;;;;;;;;;;;;;;;;;; show ramk - - xor ax, ax - mov di, 3360 - mov cx, 80*4 - rep stosw - - mov di, 3362 - mov ah, color_sym_pink - mov al, 0xDA - stosw - mov al, 0xc4 - mov cx, 76 - rep stosw - mov al, 0xBF - stosw - add di, 4 - mov al, 0xb3 - stosw - add di, 152 - stosw - add di, 4 - stosw - add di, 152 - stosw - add di, 4 - mov al, 0xc0 - stosw - mov al, 0xc4 - mov cx, 76 - rep stosw - mov al, 0xd9 - stosw -;;;;;;;;;;;;;;;;;;;;;;;;ramk is complete show -;show first message - mov si, start_msg - mov cx, start_msg_e-start_msg - mov di, 3526 -@@: - lodsb - stosw - loop @b -;;;;;;;;;;;;;;;;;;;; show press Enter to.... - add di, 44 - mov si, time_msg - mov cx, time_msg_e-time_msg -@@: - lodsb - stosw - loop @b -} - - - - - - - - -macro get_frame_buffer -{ - mov cx, save_cx ;it's placed size of ini file - les di, dword [file_data] - - mov si, di ;point frame - mov bx, cx - mov dx, size_show_section -; mov point_to_hframe,di ; внесем значение, так подстраховка не более - - mov al, byte [es:di] - push word .first_ret_bl_sc - cmp al, ' ' - jz .first_bl_sc - jmp get_firs_sym.not_space -.first_bl_sc: - jmp get_firs_sym.first_sp - -.start_hbl: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before - cmp al, '[' - jnz .start_hbl - - mov si, di ;point frame - mov bx, cx - mov dx, size_show_section - jmp .analisist_al - - -.start_bl: - call get_firs_sym ;get first symbol on new line -.first_ret_bl_sc: ;первый возврат - test cx, cx - jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before -.analisist_al: - cmp al, '[' - jnz .start_bl -;просматриваем ini файл с начала в поисках секции указаной как default -;поиск фрейма в котором содержиться значение default -.found_sect_bl: - cmp di, point_loader - jz .start_bl - cmp di, point_default - jz .save_point_def - - dec dx - jnz .start_bl - - jmp .start_hbl - - -.save_point_def: -;итак далее мы должны заполнить frame буфер адресов секций, что бы потом по нему быстро перемещаться не вычисляя снова адреса - mov di, si ;указатель на начало - mov cx, bx - lea si, point_to_hframe - mov dx, size_show_section+1 ;т.к. у нас структура содержит размер между первым и вторым указателем, то нам нужно на 1 адрес больше обсчитать секций. -;переходим на обработку значения указателя - mov al, byte [es:di] - push word .first_ret_mfb - cmp al, ' ' - jz .first_bl_mbf - jmp get_firs_sym.not_space -.first_bl_mbf: - jmp get_firs_sym.first_sp - -.start_mfb: - call get_firs_sym ;get first symbol on new line -.first_ret_mfb: ;первый возврат - jcxz .val_buff_comp ;.end_loader ;found or not found parametrs in section exit in section - cmp al, '[' - jnz .start_mfb - -.found_sect_mfb: - cmp di, point_loader ;if we have section loader - jz .start_mfb - - mov [si], di - - sub si, 2 - dec dx - jnz .start_mfb -;bufer is full - jmp @f -.val_buff_comp: - push save_cx - pop word [si] - sub si, 2 -@@: - - add si, 4 - mov point_to_eframe, si - -} - -macro show_act_cursor -{ -;отображение курсора по умолчанию - lea si, point_to_hframe - mov di, 962-160 - mov ax, point_default - mov cx, size_show_section -.home_show_cur: - mov bx, [si] - add di, 160 - cmp bx, ax - jz .show_cursor_activ - sub si, 2 - loop .home_show_cur - -.show_cursor_activ: -; push 0xb800 -; pop es - mov point_to_point_def, si - mov ax, (color_sym_red*0x100+0x10) - stosw - add di, 68 - inc ax - stosw -} - -macro clear_timer_msg -{ - push 0xb800 - pop es - xor ax, ax -if DEBUG - mov ax, 0x0720 -end if -;;;;;;;;;;;;;;;;;;;;; show Press any key - mov di, 3360 - mov cx, 80*4 - rep stosw - -;show sect - push ini_data_ - pop es - call show_bl_sc_sect ;es=0xb800 - -} - -macro show_descript -;Этот макрос показывает краткое описание, если оно есть у секции в пункте -;Section description -{ -local .start_p_sh_d -local .exit -local .rest_value_loop_sh_d -local .end_sh_desc_sec -local .loop_message -local .show_mess_prev_eq - mov di, point_default - push ini_data_ - mov si, point_to_point_def - pop es - sub si, 2 - mov cx, [si] ;загрузим указатель наследующию секцию - sub cx, di ;вот теперь имеем истиный размер -;di - указатель на дефолтную секцию т.е. выбранную cx - размер области. для просмотра - -.start_p_sh_d: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz .exit ;нету? ну ладно - следующее значение тогда ) - cmp al, 'd' - jnz .start_p_sh_d -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - mov bx, cx - mov ax, di - - mov si, parse_descript - mov cx, parse_descript_e - parse_descript - repe cmpsb - jnz .rest_value_loop_sh_d ;is not compare - - sub bx, parse_descript_e - parse_descript;correct cx - add bx, cx - mov cx, bx -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; разбор аля ' = ' - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .rest_value_loop_sh_d ;not found param timeout - - cmp ah, byte [es:di-1] ;find '=' - jnz .rest_value_loop_sh_d - - repe scasb ;cut ' ' - inc cx - dec di -;;;;;;;;;;;;;;;;;;;;di указывает на строчку, которую нам нужно выводить. -;строчка будет выводиться блоками по 37 символов. -;настроим куда будем выводить т.е. начало -;es:di - указывают на строчку из которой мы берем символ, ds:si куда будем выводить - push di - pop si - - push es - pop ds - - push 0xb800 - pop es - - mov di, 1040 - mov bx, 18 - mov find_sec_di, di - mov save_cx_d, bx -;;;;;;;;;;;;;;;;;;;;;;;;;; -;clean string - - push di - xor ax, ax - -@@: - mov cx, 38 - push di - rep stosw - pop di - - cmp save_descript_size, bx - jz @f - - - add di, 160 - dec bx - jnz @b - -@@: - pop di -;enter in mess -.show_mess_prev_eq: - lodsb - mov ah, color_sym_lettuce;color_sym_turquoise -; sub di,2 - cmp al, '"' - jz .loop_message - cmp al, "'" - jnz .end_sh_desc_sec - -.loop_message: - mov cx, 38 -@@: - lodsb - cmp al, '"' - jz .end_sh_desc_sec - cmp al, "'" - jz .end_sh_desc_sec - stosw - loop @b - - add find_sec_di, 160 - mov di, find_sec_di - dec save_cx_d - cmp save_cx_d, 0 - jnz .loop_message - -.end_sh_desc_sec: - push save_cx_d - pop save_descript_size - - push cs - pop ds - jmp .exit - - -.rest_value_loop_sh_d: - mov di, ax - mov cx, bx - jmp .start_p_sh_d - -.exit: -} diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_dat.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_dat.inc deleted file mode 100644 index 0525f5221b..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_dat.inc +++ /dev/null @@ -1,56 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -;Тут представленны теги, для сравнения -parse_loader db '[loader]' -parse_loader_e: -parse_l_timeout db 'timeout' -parse_l_timeout_e: -parse_l_default db 'default' -parse_l_default_e: -parse_name db 'ame' -parse_name_e: -parse_descript db 'descript' -parse_descript_e: - -parse_LoaderModule db 'LoaderModule' -parse_LoaderModule_e: -parse_RamdiskSize db 'RamdiskSize' -parse_RamdiskSize_e: -parse_RamdiskFS db 'RamdiskFS' -parse_RamdiskFS_e: -parse_RamdiskSector db 'RamdiskSector' -parse_RamdiskSector_e: -parse_RamdiskCluster db 'RamdiskCluster' -parse_RamdiskCluster_e: -parse_RFS_FAT db 'FAT' -parse_RFS_FAT_e: -parse_RFS_KRFS db 'KRFS' -parse_RFS_KRFS_e: -parse_Loader_Image db 'LoaderImage' -parse_Loader_Image_e: -parse_RamdiskFile db 'RamdiskFile' -parse_RamdiskFile_e: diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_def_sect.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_def_sect.inc deleted file mode 100644 index 9e1fa83641..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_def_sect.inc +++ /dev/null @@ -1,2121 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; в этой секции идет разбор параметров указатель на секцию храниться в point_default -;типы ошибок при обработке макроса -;Макрос RamdiskFS -;/определение флагов в записи корневой директории -ATTR_READ_ONLY equ 0x01 -ATTR_HIDDEN equ 0x02 -ATTR_SYSTEM equ 0x04 -ATTR_VOLUME_ID equ 0x08 -ATTR_DIRECTORY equ 0x10 -ATTR_ARCHIVE equ 0x20 - - - -show_error_1 equ 0x1 ;кончились данные - не запланированный конец секции -show_error_2 equ 0x2 ;нет завершающего символа в размере рам диска. -show_error_3 equ 0x4 ; рам диск будет иметь размер =64 кб. -show_error_4 equ 0x8 ; - -macro use_parse_def_sect -{ - mov di, point_default - push ini_data_ - pop es - mov si, point_to_point_def - sub si, 2 - mov cx, [si] ;загрузим указатель наследующию секцию - - xor ax, ax ;обнулим аx для очистки флагов - - sub cx, di ;вот теперь имеем истиный размер - mov save_cx_d, cx ;сохраним значение cx своей переменной -;обнулим переменную флагов, это необходимо, для того, что бы избежать обработку повторяющихся значений - - mov status_flag, ax -;;;; -;ВХод в обработку парсинга значений секций. es:di - указатель на начало секции cx размер секции доступной для парсинга -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;соглашение не разрушаем bp, es, cs, sp -;use_Loader_Image ;загрузить образ выше 1 мб -use_RamdiskFS -;проверяется самый последний. -use_LoaderModule ;особенность - передает управление на загруженный модуль. -} - -macro use_LoaderModule -;как вариант сейчас используется модель, при загрузке модуля на него передается управление, решение временое -;управление будет передаваться только после обработки всей секции -{ -local .found_end_str - - mov di, point_default ;restore value - mov cx, save_cx_d -;обработка конструкции типа LoaderModule=kord/kolibri.ldm -.start_p_LM: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz ._afterLoaderModule ;нету? ну ладно - следующее значение тогда ) - cmp al, 'L' - jnz .start_p_LM -;проверка на значение LoaderModule -; parse_LoaderModule - mov bx, cx - mov ax, di - - mov si, parse_LoaderModule - mov cx, parse_LoaderModule_e - parse_LoaderModule - repe cmpsb - jnz .rest_value_loop_LM ;is not compare - - sub bx, parse_LoaderModule_e - parse_LoaderModule;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_LM ;оценка флагов - jz .correct_is_not_set_LM - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -.correct_is_not_set_LM: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .rest_value_loop_LM ;not found param timeout - - cmp ah, byte [es:di-1] ;find '=' - jnz .rest_value_loop_LM - - repe scasb ;cut ' ' - inc cx - dec di -;di указывает на начало блока информации, в cx длинна до конца секции. -;после загрузки заноситься значение занятой памяти. -;для того что бы загрузить модуль, воспользуемся callback сервисом -;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 -;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader -;мы ее модифицируем до такого состояния dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем -;сохранили певые 2 word - push dword [es:di-6] - lea si, [di-6] - - push word [es:di-2] - xor ax, ax - mov word [es:di-6], ax ;вносим нужные значения -;info_real_mode_size размер и указатель на область в которую можно загрузиться - mov ax, info_real_mode_size ;0x3000 ;следующий сегмент за данными - - - mov word [es:di-4], ax - mov word [es:di-2], 16 ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем -;;;;;; поиск конца строчки -@@: - mov al, byte [es:di] - cmp al, ' ' - jz .found_end_str - cmp al, 0xa - jz .found_end_str - cmp al, 0xd - jz .found_end_str - inc di - dec cx - jnz @b -;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки -.found_end_str: - - push word [es:di] - xor ax, ax - mov word [es:di], ax -; xor ax,ax ; function 1 - read file - mov di, si ;file_data - inc ax - push si - push es - - push es - pop ds - push cs - pop es - - call far dword [es:loader_callback] - - push cs - pop ds - - pop es - pop si - - test bx, bx - jnz .error_LM - - - jmp far dword [es:si] - - -.error_LM: - call error.LoaderModule -.rest_value_loop_LM: - mov di, ax - mov cx, bx - jmp .start_p_LM - -._afterLoaderModule: -} - -macro use_RamdiskFS -; формирование рам диска, + обработка всего связанного. -{ -if DEBUG -local ._not_memory_in_sys -;//////// clear window - mov ax, 3 - int 0x10 -;\\\\\\\\\ clear window is end - mov si, ramdiskFS_st - call printplain -end if -; обнулим регистр состояния ошибок - xor ax, ax - mov show_errors_sect, ax -use_free_memory ; узнаем какого объема у нас доступна память. значение возаращается в ax -;узнаем сколько у нас есть памяти и сможем ли мы сформировать нужного размера рам диск. -use_RamdiskSize ;значение возвращается в bx - cmp free_ad_memory, bx ; размерность в кб. - jbe ._not_memory_in_sys - movzx eax, bx - shl eax, 10 ;*1024 = get size in byte - mov save_ramdisksize, eax ; сорханим размер в byte - -get_type_FS ;получим тип файловой системы + создадим ее - - -._not_memory_in_sys: - -if DEBUG -;pause - xor ax, ax - int 0x16 -end if -} -macro use_RamdiskSize -{ -local .start_p_RS -local .correct_is_not_set_RS -local .CS -local .correct_val_RS -local .correct_size_RS -local .rest_value_loop_RS -local .end_get_RS_ERROR_1 -local .end_get_RS_ERROR_2 -local ._end_parse_RS -;обрабатывается размер формируемого рам диска -;загрузим начало секции, т.к. будем просматривать с начала и всю секцию - mov di, point_default ;restore value - mov cx, save_cx_d -.start_p_RS: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz ._end_parse_RS ;нету? ну ладно - следующее значение тогда ) - cmp al, 'R' - jnz .start_p_RS -;проверка на значения RamdiskSize -; parse_RamdiskSize - mov bx, cx - mov ax, di - - mov si, parse_RamdiskSize - mov cx, parse_RamdiskSize_e - parse_RamdiskSize - repe cmpsb - jnz .rest_value_loop_RS ;is not compare - - sub bx, parse_RamdiskSize_e - parse_RamdiskSize;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_RS ;оценка флагов - jz .correct_is_not_set_RS - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -.correct_is_not_set_RS: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .end_get_RS_ERROR_1 ;not found param - - cmp ah, byte [es:di-1] ;find '=' - jnz .start_p_RS ; перейдем на начало и попробуем найти еще секцию - - repe scasb ;cut ' ' - inc cx - dec di -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;Тут нужно преобразовывать строчку в цифровое значение. -;;;;;;;;;;;;;;;;;;;;;;;;;; - xor bx, bx - mov cx, 5 -@@: - mov al, byte [es:di] - cmp al, '0' - jb .CS - cmp al, '9' - jbe .correct_val_RS -.CS: - cmp al, 'K' - jz .correct_size_RS - jmp .end_get_RS_ERROR_2 -.correct_val_RS: - imul bx, 10 - xor al, 0x30 - add bl, al - inc di - loop @b - -.correct_size_RS: -;возможен 1 вариант, когда размер задан в K киллобайтах -;внутренный формат данных это кол-во запрощеной памяти в кб. - test bx, bx - jnz @f ;если значение отлично от 0 -;;;;;сообщение об ошибке, размер "найденого" блока =0 минимально мы должны -;установить 64 кб размер рам диска. - or show_errors_sect, show_error_3 - mov bx, 64 -@@: - jmp ._end_parse_RS - - -.rest_value_loop_RS: - mov di, ax - mov cx, bx - jmp .start_p_RS - - - -.end_get_RS_ERROR_1: -;сообщение об ошибке - данный участок кода не был корректно обработан :( - or show_errors_sect, show_error_1 - jmp ._end_parse_RS -.end_get_RS_ERROR_2: - or show_errors_sect, show_error_2 - -._end_parse_RS: -if DEBUG - pusha - movzx eax, bx - mov cx, 0x0a - mov di, RamdiskSize_msg - mov dword[ds:di], ' ' - mov word [ds:di+4], ' ' - call decode -;Show size - mov si, RamdiskSize_msg - call printplain - - popa -end if - -} - -macro use_free_memory -{ -local _support_function_use_free_memory -;макрос для получения общего числа доступной памяти в кб, для формирования рам диска за пределами 1 мб. -;используется 0х88 функция 0х15 прерывания -; если поддерживается функция, то в ax значение в кб, если нет, то в ax=0 - mov ah, 0x88 ;ah,0x88 - int 0x15 - jnc ._support_function_use_free_memory - xor ax, ax -;возвращает в ax число в кб -._support_function_use_free_memory: - mov free_ad_memory, ax ; если не поддерживается биосом, то в ax=0 -if DEBUG - pushad - movzx eax, ax - mov cx, 0x0a - mov di, free_memory_msg - mov dword[ds:di], ' ' - mov word [ds:di+4], ' ' - call decode -;Show size - mov si, free_memory_msg - call printplain - - popad -end if - - - - -} -macro show_ERRORS -{ - -} - -macro get_type_FS ;получить и создать образ для заданной RFS. -{ - mov di, point_default ;restore value - mov cx, save_cx_d -.start_g_tpe_RFS: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz ._end_parse_FRS ;._end_get_type_RFS ;нету? ну ладно - следующее значение тогда ) - cmp al, 'R' - jnz .start_g_tpe_RFS -;проверка на значения RamdiskSize -; parse_RamdiskSize - mov bx, cx - mov ax, di - - mov si, parse_RamdiskFS - mov cx, parse_RamdiskFS_e - parse_RamdiskFS - repe cmpsb - jnz .start_g_tpe_RFS_rest_v ;is not compare - - sub bx, parse_RamdiskFS_e - parse_RamdiskFS;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_GTRFMS ;оценка флагов - jz .correct_is_not_set_FRS - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -.correct_is_not_set_FRS: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - test cx, cx - jz .end_get_FRS_ERROR_1 ;not found param - - cmp ah, byte [es:di-1] ;find '=' - jnz .start_g_tpe_RFS ; перейдем на начало и попробуем найти еще секцию - - repe scasb ;cut ' ' - inc cx - dec di -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;Тут нужно преобразовывать строчку в цифровое значение. -;;;;;;;;;;;;;;;;;;;;;;;;;; - mov bx, cx - mov ax, di - - mov si, parse_RFS_FAT - mov cx, parse_RFS_FAT_e - parse_RFS_FAT - repe cmpsb - jnz .krfs_cmp ;is not compare - -make_FAT_RamFS ;сделать - -if DEBUG - pusha - mov si, make_fat12_RFS_msg - call printplain - popa -end if - jmp ._end_parse_FRS - -.krfs_cmp: - mov cx, bx - mov di, ax - - mov si, parse_RFS_KRFS - mov cx, parse_RFS_KRFS_e - parse_RFS_KRFS - repe cmpsb -; jnz @f ;is not compare - - jmp ._end_parse_FRS - - -.start_g_tpe_RFS_rest_v: - mov cx, bx - mov di, ax - jmp .start_g_tpe_RFS - - - -.end_get_FRS_ERROR_1: -;сообщение об ошибке - данный участок кода не был корректно обработан :( - or show_errors_sect, show_error_1 - jmp ._end_parse_FRS -.end_get_FRS_ERROR_2: - or show_errors_sect, show_error_2 - -._end_parse_FRS: -if DEBUG - pusha - mov si, get_type_FS_msg - call printplain - popa -end if - - - -} -macro make_FAT_RamFS -{ -local .RS1 -local .fat12 -local .fat16 -; мы должны сформировать в начальный образ Ram FS, а потом записать его за область выше 1 мб.. -;для случая с FAT12 -; mov di,fat12_buffer ;ds должен быть = cs -;es:di - указывают на начало блока для формирования рам фс. -use_RamdiskSector ;возращаемое значение в ax размер сектора в байтах - cmp ax, 4096;по спецификации значение должно быть в пределах от 1 до 4096 - ja .RS1 - test ax, ax - jnz @f ;ошибка если сюда прыгнули все таки ... - -.RS1: - mov word [fat12_buffer.BPB_BytsPerSec], 512 -;;;;;;;;;;скажем что по дефолту будем юзать значение... -@@: - mov word [fat12_buffer.BPB_BytsPerSec], ax;тут все ок - -;BPB_SecPerClus кол-во секторов в кластере -use_RamdiskCluster ;возращаемое значение в al - cmp al, 128 - ja @f -; test al,0x1 ;проверка на кратность ) -; jnz @f - - mov byte [fat12_buffer.BPB_SecPerClus], al - - ;incorrect value will be set dafault - -;ниже некорректное значение в т.к. размер кратен 2 и в диапазоне от 1 до 128 включительно -; мы должны ругнуться на это -;@@: ;mov byte [fat12_buffer.BPB_SecPerClus],1 - -;;;;; определеим какая у нас будет использоваться FAT -;по условию, fat12<4085<=fat16<65525<=fat32 -; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = кол-во секторов - movzx eax, word [fat12_buffer.BPB_BytsPerSec] - movzx ebx, byte [fat12_buffer.BPB_SecPerClus] - - imul ebx, eax;тут размерность сектора - mov eax, save_ramdisksize ;размер запрошенного рам диска в байтах - cdq - idiv ebx -;;;;;;;; сейчас частное в eax, а остаток в edx -;получим кол-во секторов, и можем уже определить тип FAT которую нужно делать. - cmp eax, 4085 - jb .fat12 - cmp eax, 65525 - jb .fat16 -;;;;;;;;;;;;;;;;;;;;;;;; тут fat32 - mov set_ramfs, 32 ;установим тип файловой системы - mov word [fat12_buffer.BPB_RsvdSecCnt], 32 - xor eax, eax - mov word [fat12_buffer.BPB_RootEntCnt], ax - mov word [fat12_buffer.BPB_TotSec16], ax - mov dword [fat12_buffer.BPB_TotSec32], eax - - -.fat16: ;fat16 -;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000). - jmp $ - mov set_ramfs, 16 ;установим тип файловой системы - movzx ebx, byte [fat12_buffer.BPB_SecPerClus] - imul eax, ebx - - cmp eax, 0x10000 - jae @f - mov word [fat12_buffer.BPB_TotSec16], ax - mov dword [fat12_buffer.BPB_TotSec32], 0 -@@: -;количество секторов занимаемое одной копией фат -; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Для FAT12/FAT16 это количество секторов одной FAT. ?? -;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число -;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно -;быть 0. Пока константа, нужно будет позже доделать. - mov eax, root_dir_entry_count - mov word [fat12_buffer.BPB_RootEntCnt], ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) -;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб -;;;;;;; -;Для FAT16 это количество секторов одной FAT. Для FAT32 это значение -;равно 0, а количество секторов одной FAT содержится в BPB_FATSz32. -;RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec; - -;TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors); -;TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs; -;If(FATType == FAT32) -; TmpVal2 = TmpVal2 / 2; -;FATSz = (TMPVal1 + (TmpVal2 - 1)) / TmpVal2; -;If(FATType == FAT32) { -; BPB_FATSz16 = 0; -; BPB_FATSz32 = FATSz; -;} else { -; BPB_FATSz16 = LOWORD(FATSz); -; /* there is no BPB_FATSz32 in a FAT16 BPB */ -;} -;===================================== -;RootDirSectors - movzx ebx, word [fat12_buffer.BPB_BytsPerSec] - imul eax, 32 - add eax, ebx - dec eax - - cdq - idiv ebx -;;;;;;;; сейчас частное в eax, а остаток в edx для дискеты 1.44 у нас должно быть значение =14 -;BPB_ResvdSecCnt + RootDirSectors - movzx ebx, word [fat12_buffer.BPB_RsvdSecCnt] - add ebx, eax - -;DskSize у нас это значение уже получено и доступно - movzx eax, word [fat12_buffer.BPB_TotSec16] ;должен быть в секторах - sub eax, ebx - - -;TmpVal1=eax - shl edi, 8 ;=edi*256 - movzx ecx, byte [fat12_buffer.BPB_NumFATs] - add edi, ecx -;TmpVal2=edi - add eax, edi - dec eax - cdq - idiv edi -;FATSz = сейчас частное в eax, а остаток в edx - mov word [fat12_buffer.BPB_FATSz16], ax - - - - - - - - -.fat12: ;fat12 -if DEBUG -; выведем в отладке, что собираемся делать образ диска c FS=fat12 - pushad - mov si, start_making_FAT12_msg - call printplain - popad -end if - - - -;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000). - mov set_ramfs, 12 ;установим тип файловой системы - movzx ebx, byte [fat12_buffer.BPB_SecPerClus] - imul eax, ebx - - cmp eax, 0x10000 - jae @f - mov word [fat12_buffer.BPB_TotSec16], ax - mov dword [fat12_buffer.BPB_TotSec32], 0 -@@: -;количество секторов занимаемое одной копией фат -; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Для FAT12/FAT16 это количество секторов одной FAT. ?? -;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число -;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно -;быть 0. Пока константа, нужно будет позже доделать. - mov eax, root_dir_entry_count - mov word [fat12_buffer.BPB_RootEntCnt], ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) -;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб -;;;;;;; -;DskSize(в секторах)*12 (размерность файловой системы, т.е предположим сколько битов потребуется для адресации этого объема) /8 (что получить размер в байтах) -;полученное число округляем в большую сторону кратное сектору т.е. 512 байт Такой подход не универсален, но пока пойдет -;вообще у мелкософт это все считается ручками, но мы будем юзать только под коос рам диск с фат12 - movzx eax, word [fat12_buffer.BPB_TotSec16] - imul eax, 12 - shr eax, 3 ;делим на 8 но т.е. нам нужно делить еще и на 512 или более в зависимости от размеров кластера - movzx ebx, word [fat12_buffer.BPB_BytsPerSec] ;размер сектора - cdq - idiv ebx ;разделим на размер кластера -;сейчас у нас в eax значение его нужно округлить в большую сторону кратному 512 байтам -;применим следующее очистим and и добавим 512 байт. таким образом выравним на 512 байт -;но т.к. все равно делить нижний код нам не нужен -; and eax,0xfff200 -; add eax,0x200 ;добавим 512 байт для 1.44 дискеты идеально подходит )) - - inc ax -;по идее должно на каждую фат таблицу -;резервироваться 9 секторов т.е. получается 2*9=18+1 =19 секторов т.е. рут дир находиться на с 20 сетора т.е. с адреса 0х2600 -;сейчас нужно вычислить сколько будет секторов занимать фат ) нужно разделить на 512 -;FATSz = сейчас частное в eax - mov word [fat12_buffer.BPB_FATSz16], ax -;;;;;;;;;;;;;;;;;;;;;;;;;;;; -get_firstDataSector ;получить смещение до данных -;создадим певую запись в фат по определенному адресу. -first_create_fat_table -;закиним BPB файловой системы за 1 мб. -use_BPB_RAM -; -;копирование файла. -use_RamdiskFile - -;;;; вычисляем указатель на корневую дир FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16); -; movzx ebx, [fat12_buffer.BPB_NumFATs] -; movzx eax,ax -; imul eax,ebx -;eax=(BPB_NumFATs * BPB_FATSz16) -; inc eax -; BPB_ResvdSecCnt значение только 1 для fat12/16 -;в eax указатель на root dir. для дискеты fat12 должно получиться при кол-во копий fat 1 = 1+ (1*1) =2 или 3 - -if DEBUG - pusha -; mov ax,point_default -; mov ax,cx - mov cx, 0x0a - mov di, show_db1 -; mov dword[ds:di],' ' -; mov word [ds:di+4],' ' - call decode -;Show size - mov si, show_db1 - call printplain -; -; xor ax,ax -; int 0x16 - popa -end if - - - - - - - -} - -macro use_RamdiskSector -{ -;для некоторых FS будет игнорироваться - mov di, point_default ;restore value - mov cx, save_cx_d - -.start_RamdiskSector: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz .end_RamdiskSector ;нету? ну ладно - следующее значение тогда ) - - cmp al, 'R' - jnz .start_RamdiskSector -;проверка на значения RamdiskSize -; parse_RamdiskSize - - mov bx, cx - mov ax, di - - mov si, parse_RamdiskSector - mov cx, parse_RamdiskSector_e - parse_RamdiskSector - repe cmpsb - jnz .RamdiskSector_rest_val ;is not compare - - sub bx, parse_RamdiskSector_e - parse_RamdiskSector;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_RamdiskSector ;оценка флагов - jz .correct_is_not_set_RamdiskSector - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -.correct_is_not_set_RamdiskSector: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .end_get_RamS_ERROR_1 ;not found param - - cmp ah, byte [es:di-1] ;find '=' - jnz .start_RamdiskSector ; перейдем на начало и попробуем найти еще секцию - - repe scasb ;cut ' ' - inc cx - dec di -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - xor bx, bx - mov cx, 4 -@@: - movzx ax, byte [es:di] - cmp al, '0' - jb .end_RamdiskSector - cmp al, '9' - ja .end_RamdiskSector -;;;;;;;;;;;;;;;;;;; - - imul bx, 10 - xor al, 0x30 - add bx, ax - - inc di - - loop @b - jmp .end_RamdiskSector - - -.RamdiskSector_rest_val: - mov cx, bx - mov di, ax - jmp .start_RamdiskSector -.end_get_RamS_ERROR_1: - -.end_RamdiskSector: - mov ax, bx - -if DEBUG - pusha - movzx eax, bx;save_cx_d;point_default - mov cx, 0x0a - mov di, RamdiskSector_msg - mov dword[ds:di], ' ' - mov dword [ds:di+4], ' ' - call decode -;Show size - mov si, RamdiskSector_msg - call printplain - - popa -end if - -; pop di -; pop es -} - -macro use_RamdiskCluster -{ -;для некоторых FS будет игнорироваться -; push es -; push di - mov di, point_default ;restore value - mov cx, save_cx_d -; push ini_data_ -; pop es -.start_RamdiskCluster: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz .end_RamdiskCluster ;нету? ну ладно - следующее значение тогда ) - cmp al, 'R' - jnz .start_RamdiskCluster -;проверка на значения RamdiskSize -; parse_RamdiskSize - - mov bx, cx - mov ax, di - - mov si, parse_RamdiskCluster - mov cx, parse_RamdiskCluster_e - parse_RamdiskCluster - repe cmpsb - jnz .RamdiskCluster_rest_val ;is not compare - - sub bx, parse_RamdiskCluster_e - parse_RamdiskCluster;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_RamdiskCluster ;оценка флагов - jz .correct_is_not_set_RamdiskCluster - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -.correct_is_not_set_RamdiskCluster: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .end_get_RamSC_ERROR_1 ;not found param - - cmp ah, byte [es:di-1] ;find '=' - jnz .start_RamdiskCluster ; перейдем на начало и попробуем найти еще секцию - - repe scasb ;cut ' ' - inc cx - dec di -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@@: - movzx ax, byte [es:di] - cmp al, '0' - jb .end_RamdiskCluster - cmp al, '9' - ja .end_RamdiskCluster -;;;;;;;;;;;;;;;;;;; - xor al, 0x30 - - jmp .end_RamdiskCluster - - -.RamdiskCluster_rest_val: - mov cx, bx - mov di, ax - jmp .start_RamdiskCluster -.end_get_RamSC_ERROR_1: - -.end_RamdiskCluster: -if DEBUG - pusha - mov cx, 0x0a - mov di, RamdiskCluster_msg -; mov word[ds:di],' ' - call decode -;Show size - mov si, RamdiskCluster_msg - call printplain - - popa -end if - -} - -macro use_Loader_Image -;предназначен для загрузки образов выше 1 Мб. -;первоначальная версия загружает образ дискеты 1.44 мб -{ -local .start_p_LI -local .exit -local .error_LI -local .rest_value_loop -local .found_end_str - mov di, point_default ;restore value - mov cx, save_cx_d -;обработка конструкции типа LoaderModule=kord/kolibri.ldm -.start_p_LI: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz .exit ;нету? ну ладно - следующее значение тогда ) - cmp al, 'L' - jnz .start_p_LI -;проверка на значение LoaderModule -; parse_LoaderModule - mov bx, cx - mov ax, di - - mov si, parse_LoaderImage - mov cx, parse_LoaderImage_e - parse_LoaderImage - repe cmpsb - jnz .rest_value_loop ;is not compare - - sub bx, parse_LoaderImage_e - parse_LoaderImage;correct cx - add bx, cx - mov cx, bx - -; test status_flag,flag_found_LM ;оценка флагов -; jz .correct_is_not_set_LI - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -;.correct_is_not_set_LI: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .rest_value_loop_LI ;not found param timeout - - cmp ah, byte [es:di-1] ;find '=' - jnz .rest_value_loop_LI - - repe scasb ;cut ' ' - inc cx - dec di -;di указывает на начало блока информации, в cx длинна до конца секции. -;после загрузки заноситься значение занятой памяти. -;для того что бы загрузить модуль, воспользуемся callback сервисом -;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 -;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader -;мы ее модифицируем до такого состояния dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем -;сохранили певые 2 word - push dword [es:di-6] - lea si, [di-6] - - push word [es:di-2] - xor ax, ax - mov word [es:di-6], ax ;вносим нужные значения -;info_real_mode_size размер и указатель на область в которую можно загрузиться - mov ax, info_real_mode_size ;0x3000 ;следующий сегмент за данными - - - mov word [es:di-4], ax - mov word [es:di-2], 16 ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем -;;;;;; поиск конца строчки -@@: - mov al, byte [es:di] - cmp al, ' ' - jz .found_end_str - cmp al, 0xa - jz .found_end_str - cmp al, 0xd - jz .found_end_str - inc di - dec cx - jnz @b -;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки -.found_end_str: -; чтение блока по 64 кб в сегмент и забрасывание его выше 1 мб. - push word [es:di] - xor ax, ax - mov word [es:di], ax -; xor ax,ax ; function 1 - read file - mov di, si ;file_data - inc ax - push si - push es - call far dword [loader_callback] - push cs - pop ds - - pop es - pop si - - test bx, bx - jnz .error_LM - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; забрасывание блока в 64 кб выше 1 мб. - mov si, table_15_87 - push es - push ds - pop es - mov cx, 256*18 - mov ah, 0x87 - int 0x15 - pop es - pop dx cx - test ah, ah - - - - jmp far dword [es:si] - - - - -.rest_value_loop: - mov di, ax - mov cx, bx - jmp .start_p_LI - -.exit: - - - -} - - - -macro name_in_root_fat -;макрос, который записывает информацию о загруженном файле в корневую фат таблицу -{ - -} - - - -macro use_RamdiskFile -{ -;загрузка файлов с использование callback сервиса первичного загрузчика -;используется только для загрузки необходимых и небольших файлов, т.к. достаточно медленно работает -;для загрузки использует 0х87 функцию int 0x15 прерывания - загрузка блоков данных до 64 кб выше 1 мб -local .start_loop -local ._end -local .rest_value_loop -local .error - mov di, point_default ;restore value - mov cx, save_cx_d - mov data_offset, 0 ;clean offset -;обработка конструкции типа LoaderModule=kord/kolibri.ldm -.start_loop: - call get_firs_sym ;get first symbol on new line - test cx, cx - jz ._end ;нету? ну ладно - следующее значение тогда ) - cmp al, 'R' - jnz .start_loop -;проверка на значение RamdiskFile - mov bx, cx - mov ax, di - - mov si, parse_RamdiskFile - mov cx, parse_RamdiskFile_e - parse_RamdiskFile - repe cmpsb - jnz .rest_value_loop ;is not compare - - sub bx, parse_RamdiskFile_e - parse_RamdiskFile;correct cx - add bx, cx - mov cx, bx -; test status_flag,flag_found_LM ;оценка флагов -; jz .correct_is_not_set_LM - -; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем -; call printplain -; jmp .get_next_str - -;.correct_is_not_set_LM: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - test ecx, ecx - jz .rest_value_loop ;not found param timeout - - cmp ah, byte [es:di-1] ;find '=' - jnz .rest_value_loop - - repe scasb ;cut ' ' - inc cx - dec di - - mov save_di_RAMDISK, di - mov save_cx_RAMDISK, cx -;di указывает на начало блока информации, в cx длинна до конца секции. -;после загрузки заноситься значение занятой памяти. -;для того что бы загрузить модуль, воспользуемся callback сервисом -;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 -;это выглядит так: в ini файле существует строчка RamdiskFile = @menu,@menu -;мы ее модифицируем до такого состояния dw,dw,db'@menu',0 конечно сохранив те значения которые мы заменяем -;сохранили певые 2 word - -; -@@: - mov al, byte [es:di] - cmp al, ',' ; т.е. ищем разделитель - jz .found_end_str - inc di - dec cx - jnz @b -;;;not found допустим,что это конец файла и он не имеет привычного завершения строки -.found_end_str: -; mov al,byte [es:di] -; cmp al,' ' ; убираем пробелы, если они есть -; jnz @f -; inc di -; dec cx -; jnz .found_end_str - -;@@: - mov point_to_dest_file_name, di - inc di -;проверка индивидуальности имени файла -check_name_file -;/restore di - point and cx -size section - mov di, save_di_RAMDISK - mov cx, save_cx_RAMDISK - - test al, al - jnz .start_loop ;если в al значение не =0, то такое имя уже существует в системе. - - - - push dword [es:di-6] - lea si, [di-6] - - push word [es:di-2] - push di - xor ax, ax - mov word [es:di-6], ax ;вносим нужные значения -;info_real_mode_size размер и указатель на область в которую можно загрузиться - mov ax, info_real_mode_size ;0x3000 ;следующий сегмент за данными - - - mov word [es:di-4], ax - mov word [es:di-2], 16 ;кол-во блоков по 4 кб =64 кб т.е. больше не читаем - - mov di, point_to_dest_file_name - -if DEBUG - pushad -; mov ax,di - mov cx, 0x0a - mov di, name_of_seg_get_64 - mov dword[ds:di], ' ' - mov word[ds:di+4], ' ' - call decode -;Show size - mov si, name_of_seg_get_64 - call printplain - - popad -end if - - push word [es:di] - push cx - xor ax, ax - mov word [es:di], ax -; xor ax,ax ; function 1 - read file - push di - mov di, si ;file_data - inc ax - push si - push es - push bp - - push es - pop ds - push cs - pop es - - call far dword [es:loader_callback] - - - push cs - pop ds - - pop bp - pop es - pop si - - cmp bx, 2 - ja .error -; сейчас у нас в dx:ax размер файла, который мы загрузили. -; возможна ситуация, когда в bx=1 т.е. есть еще данные на диске - mov status_flag_loader_f, bx - - shl edx, 16 - mov dx, ax -; shr edx,10 ;размер файла в кб. -;;в edx размер в байтах. - mov save_file_size, edx - mov eax, edx -;восстановим полностью файл сценария - pop di - pop cx ;длинна остатка с 2-ой частью имени т.е. с именем назначением. - pop word [es:di] - pop di - pop word [es:di-2] - pop dword [es:di-6] - - -if DEBUG - pushad - mov cx, 0x0a - mov di, RamdiskFile_msg - mov dword[ds:di], ' ' - call decode -;Show size - mov si, RamdiskFile_msg - call printplain - - popad -end if - - - - - - - - - - -; загрузим чему у нас равен кластер -; mov ax,word [fat12_buffer.BPB_BytsPerSec] ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта -; movzx bx,byte [fat12_buffer.BPB_SecPerClus] ;кол-во секторов в кластере -; imul ax,bx -;сейчас в eax размер кластера (512) байт -;в edx длина файла в байтах до 64 кб -;закиним файл за 1 мб -;1 нам нужно составить фат таблицу т.е. произвести разметку рамдиска, затем перенесем по адресу файл - -;записать инфорамацию о файле в корневую директорию -register_file_in_fat -;перенести за 1 мб содержимое файла -move_file_up - -;проверим, загружен ли до конца файл? т.е. если размер файла больше чем 64 кб, то будет подгружать оставшиеся блоки - cmp status_flag_loader_f, 0x1 - jnz @f -;нужно дозагузить данные файла и перенести их за 1-ый мб согласно фат структуре - - - - - - - - - -@@: -;тут организован цикл по загрузке файлов в корневую директорию - mov di, save_di_RAMDISK - mov cx, save_cx_RAMDISK -if DEBUG - pusha - xor ax, ax - int 0x16 - popa -end if - - - jmp .start_loop - - -.error: - ;call error.LoaderModule -;fixme! -.rest_value_loop: - mov di, ax - mov cx, bx - jmp .start_loop - -._end: -;перенесем за 1-ый мб фат и рут дир -move_up_fat_and_root_d - - - - - - -;загрузка блока -; mov ah,0x87 -; mov cx, ;size in byte - - -;es:si point to descripts - - -} - -macro use_BPB_RAM ;закинуть самые первые 512 байт за 1-й мб -;данный макрос закидывает BPB структуру т.е. первые 512 байт, пока только фат12 за 1 мб -{ - mov ax, fat12_buffer - mov si, table_15_87 - add word [si+8*2+2], ax - push es - push ds - pop es - mov cx, 256 ;бут сектор укладывается в 512 байт 512/2=256 - mov ah, 0x87 - int 0x15 - pop es -;add 512 byte for destination adress -; add dword [si+8*3+2], 512 -; test ah, ah -; jz -if DEBUG - pusha - mov ax, word [si+8*2+2] - mov cx, 0x0a - mov di, BPB_msg - call decode -;Show size - mov si, BPB_msg - call printplain - popa -end if -} -macro first_create_fat_table -;данный макрос создает оформляет 3 первых байта fat таблицы, и устанавливает указатель на следующий блок, и вносит 0 значение -;для смещения в корневой таблице. -{ - mov al, byte [fat12_buffer.BPB_Media] - - - push ds - - - mov di, info_real_mode_size - add di, 0x1000 - -if DEBUG - pushad - - mov ax, info_real_mode_size - add ax, 0x1000 -; mov ax,ds - mov cx, 0xa - - mov di, first_entry_in_fat - mov dword [di], ' ' - mov word [di+4], ' ' - call decode -;Show size - mov si, first_entry_in_fat - call printplain - - xor ax, ax - int 0x16 - - popad -end if - - - push di ; push word info_real_mode_size+0x1000 ;cледующий сегмент за загруженным участком - - xor di, di - mov point_to_free_root, di ;значение смещения =0 в корневой фат таблице описания - - pop ds ; загружен следующий сегмент т.е. пустой сегмент - - mov byte [di], al - or ax, -1 - inc di - mov word [di], ax - - pop ds - mov point_next_fat_str, 3 - -if DEBUG - pushad - mov ax, point_next_fat_str - mov cx, 0x0a - mov di, fat_create_msg - call decode -;Show size - mov si, fat_create_msg - call printplain - popad -end if - -} -macro register_file_in_fat -;макрос регистрации файла в файловой структуре Fat -;пока поддерживается только фат12, пока )) -;вычисление смежных кластеров и занесение инфы в fat/ -{ -local .step2 -local .step3 -local .end -local .eof_file - -;di point on root dir на фри секцию. - push es - - mov ax, info_real_mode_size - add ax, 0x1000 - mov es, ax ; push word info_real_mode_size+0x1000 ;сегмент следующий за загруженным блоком в 64 кб - -; определяем тип фат пока не определяем, пока только фат 12 -; 12 бит, для вычесления соседних каластеров. - mov di, firstDataSect ;в секторах - sub di, size_root_dir -;теперь в ax размер в секторах начала рут дир - shl di, 9;imul 512 - add di, point_to_free_root ;смещение в уже записанных 32-х структурах. -;необходимо внести значение в рут дир т.е. 32 байта -if DEBUG - pushad -; mov ax,point_default -; mov ax, - mov cx, 0x0a - mov di, show_db2 - mov dword[ds:di], ' ' - mov word [ds:di+4], ' ' - call decode -;Show size - mov si, show_db2 - call printplain -; -; xor ax,ax -; int 0x16 - popad -end if - - - -;gs:di - указатель для внесения инфорации в рут область фат таблицы инормации о файле. - mov si, shot_name_fat - mov cx, 11 -;запишем в структуру имя -@@: - lodsb - stosb - loop @b - -;запишем атрибуты файла и DIR_NTRes - зарезеврированный байт =0 - xor ax, ax - mov ah, ATTR_VOLUME_ID - mov word [es:di], ax - add di, 2 -;DIR_CrtTimeTenth - mov byte [es:di], 100 - inc di -;DIR_CrtTime - mov word [es:di], 0x032b ;дата - add di, 2 -;DIR_CrtDate - mov word [es:di], 0x0 ;время >< - add di, 2 -;DIR_LstAccDate - mov word [es:di], 0x032b ;дата моего - add di, 2 -;DIR_FstClusHI - mov word [es:di], 0x0 ;время для фат12 /16 всегда 0 - add di, 2 -;DIR_WrtTime - mov word [es:di], 0x0 ;время >< - add di, 2 -;DIR_WrtDate - mov word [es:di], 0x032b - add di, 2 - - mov ax, point_next_fat_str - mov word [es:di], ax - add di, 2 - - push di -;DIR_FstClusLO Младшее слово номера первого кластера. - ; mov ax,point_next_fat_str ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи -;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат - mov bx, ax - shr bx, 1 - add ax, bx -;в ах сейчас FATOffset -;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec); - mov bx, word [fat12_buffer.BPB_BytsPerSec] - cwd - idiv bx -;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) четный или нечетный указатель. - mov si, ax -;нам нужно в цикле записать все кластеры которые будут использованы для размещения файла. -;узнаем размер кластера. - movzx eax, word [fat12_buffer.BPB_BytsPerSec] - movzx ebx, byte [fat12_buffer.BPB_SecPerClus] - imul eax, ebx -;ax - размер кластера. -;сейчас будем записывать во временный буфер фат таблицу для выбранного файла. Поскольку мы его загрузили возможно не полностью -;мы обработаем запись для фат полностью, в не зависимости от предела буфера где возможна часть файла. - mov ebx, save_file_size ;размер файла в байтах - -@@: - sub ebx, eax - cmp ebx, eax - jbe .eof_file - - inc point_next_fat_str - mov cx, point_next_fat_str ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи -;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат - mov dx, ax - shr dx, 1 - add cx, dx - - - - test si, 0x1 - jz .step2 - shl cx, 4 - mov word[es:si], cx - inc si - add cx, ax - jmp @b - -.step2: - and cx, 0x0FFF - mov word[es:si], cx - inc si - add cx, ax - jmp @b - -.eof_file: - mov cx, 0x0fff - test si, 0x1 - jz .step3 - shl cx, 4 - mov word[es:si], cx - jmp .end - -.step3: - and cx, 0x0FFF - mov word[es:si], cx - -.end: - inc point_next_fat_str - - pop di -;DIR_FileSize 32-битный DWORD содержит размер файла в байтах. - mov eax, save_file_size - mov dword [es:di], eax - -if DEBUG - pushad - - mov di, firstDataSect ;в секторах - sub di, size_root_dir -;теперь в ax размер в секторах начала рут дир - shl di, 9;imul 512 - add di, point_to_free_root ;смещение в уже записанных 32-х структурах. - - push di - - mov si, dest_name_fat - mov cx, 11 - -;запишем в структуру имя -@@: - mov al, byte [es:di] - inc di - mov byte [ds:si], al - inc si - loop @b - - mov di, si - inc di - pop ax - mov cx, 0xa - call decode - - mov si, dest_name_fat - call printplain - popad - -END IF - - - - - - add point_to_free_root, 32 ;увелицим смещение до следующего значения. - pop es - -} - - - - - -macro get_firstDataSector -;макрос для вычисления певого сектора данных т.е. данных файлов в фате -;вычислим FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors; -{ - mov ax, word [fat12_buffer.BPB_FATSz16] - movzx bx, byte [fat12_buffer.BPB_NumFATs] - imul ax, bx ;9x1=9 -;ax=BPB_NumFATs * FATSz - mov bx, word [fat12_buffer.BPB_RootEntCnt] ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) - shr bx, 4 ;imul bx,32 and then div 512 -> in bx size in sectors - add ax, bx ;9+14=23 - mov size_root_dir, bx - movzx bx, byte [fat12_buffer.BPB_RsvdSecCnt] ;add 1 for fat 16/12 - add ax, bx -;ax=firstDataSector - где начинается первый секторо от 0 сектора в секторах. - фактически = 24 сектор - mov firstDataSect, ax ;сохраним для вычисления -; получимзначение кластеров, это объем в который мы можем записать данные - mov bx, word [fat12_buffer.BPB_TotSec16] - sub bx, ax - mov ax, bx - movzx bx, byte [fat12_buffer.BPB_SecPerClus] - cwd - idiv bx - mov DataClasters, ax - -if DEBUG - pushad - mov ax, firstDataSect ;первый сектор данных - mov cx, 0x0a - mov di, firstDataSect_msg - call decode -;Show size - mov si, firstDataSect_msg - call printplain -;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, size_root_dir ;размер рут дир в сетокторах - mov cx, 0x0a - mov di, size_root_dir_msg - call decode -;Show size - mov si, size_root_dir_msg - call printplain -;;;;;;;;;;;;;;;;;;;;;;;;;; - mov ax, DataClasters;кластеры - mov cx, 0x0a - mov di, DataClasters_msg - call decode -;Show size - mov si, DataClasters_msg - call printplain - popad - -end if - -} - -macro use_RamdiskPATHS -;парсинг пути источника файлов. -{ - -} - -macro use_RamdiskPATHD -;парсинг пути назначения файлов. -{ - -} -macro check_name_file -;макрос проверки имени на повтор, имя должно быть уникальным. -;входные данные: es- сегмент где лежит файл для парсинга т.е. startos.ini -;di - указатель на имя файла т.е. es:di указывает на имя файла назначения -;выходные данные eax =-1 имя совпало, eax=0 имя не совпало. -{ -local .no_equal -local .exit -local .loop_size_root_dir -;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными. -;преобразуем в аналог фат записи сточку с именем назначения - convertion_file_name ; преобразовали имя по нужным правилам - test ax, ax - jnz .exit - - lea si, [shot_name_fat] ; desination name of file - -;вычислим указатель на корневую директорию - mov di, firstDataSect - sub di, size_root_dir -;теперь в ax размер в секторах начала рут дир - shl di, 9;imul 512 -;di= Это смещение от начала буфера до рут директории. в пределах 64 кб. -;загрузим значение - т.е. кол-во элементов, которые мы можем просматривать. - mov dx, root_dir_entry_count - - mov ax, info_real_mode_size - add ax, 0x1000 - - - mov gs, ax -.loop_size_root_dir: -DEBUG1 equ 0 -if DEBUG1 - pushad - push di - mov eax, dword[gs:di] - lea si, [check_root_fat_+14] - mov dword [ds:si], '----' - mov dword [ds:si+4], '----' - mov dword [ds:si+8], '----' - mov dword[ds:si], eax - mov eax, dword[gs:di+4] - mov dword[ds:si+4], eax - mov eax, dword[gs:di+8] - mov dword[ds:si+8], eax - -; - xor eax, eax - mov ax, gs;point_next_fat_str - mov cx, 0x0a - mov di, check_root_fat_ - mov dword [di], ' ' - mov word [di+4], ' ' - call decode - xor eax, eax - pop ax - mov di, (check_root_fat_+7) - mov dword [di], ' ' - mov word [di+4], ' ' - call decode - -;Show size - lea si, [check_root_fat_] - call printplain - - lea si, [shot_name_fat] - call printplain - - xor ax, ax - int 0x16 - popad -end if - - xor bx, bx - mov cx, 11 ;size of name in struct FAT - -@@: - mov al, byte [ds:si+bx] ;ds:si - point to name of convertion variable. - mov ah, byte [gs:di+bx] ;gs:di - point to name in fat struct - inc bx - -if DEBUG -; pushad -; lea si,[check_root_fat_+14] -; mov dword [ds:si],'----' -; mov word [ds:si],ax -; call printplain - -; xor ax,ax -; int 0x16 - -; popad -end if - - - - cmp ah, al - jnz .no_equal - -; dec cx -; jnz @b - loop @b - -;.succesfuly: -;печально, такое имя уже имеется :( - or ax, -1 - jmp .exit - - -.no_equal: - add di, 32 ;fat struct =32 byte - dec dx - jnz .loop_size_root_dir - -;.exit_check_name: - and ax, 0 - -.exit: - -if DEBUG - pushad -;Show size - lea si, [check_name_fat_msg_n] - test ax, ax - jz @f - lea si, [check_name_fat_msg_y] - call printplain - lea si, [alarm_msg] -@@: - call printplain - popad -end if - -} - - -macro convertion_file_name -;макрос конвертации имени, это нужно поскольку формат представленный не соответсвует фат и напрямую редко можно когда использовать -;преобразование имени типа hello.asm в 'HELLO ASM', в соответствии с правилами fat. -;входные параметры es:di указатель на имя файла которое нужно преобразовать, конечный буфер shot_name_fat -{ -local .next_step -local .error -local .st1 -local .st2 -local .st2_l -local .st3 -local .st4_s -local .st4 -local .st5 - -;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными. -; mov di,point_to_dest_file_name входной параметр - mov si, shot_name_fat - or first_input, -1 ;при первом входе устанавливаем флаг - mov cx, 11 ;длинна имени в стуктуре фат таблицы - -@@: - mov al, byte [es:di] - cmp al, 0xa - jz .st4_s - cmp al, 0xd - jz .st4_s - cmp al, 0x20 - jz .st4_s - - cmp al, 0x20 - jb .error - cmp al, 0x22 - jz .error - cmp al, 0x2a - jz .error - cmp al, 0x2b - jz .error - cmp al, 0x2c - jz .error - cmp al, 0x2F - jz .error - - cmp al, 0x3a - jz .error - cmp al, 0x3b - jz .error - cmp al, 0x3c - jz .error - cmp al, 0x3d - jz .error - cmp al, 0x3E - jz .error - cmp al, 0x3F - jz .error - - cmp al, 0x5b - jz .error - cmp al, 0x5c - jz .error - cmp al, 0x5d - jz .error - - cmp al, 0x7c - jz .error - - - cmp first_input, -1 - jnz .next_step - and first_input, 0 ;сборосим флаг. - cmp al, '.' - jz .error ;обработка точки, файл не может начинаться с точки - -.next_step: - cmp al, 0x2e - jnz .st2 ;обработка точки, в середине файла -;тут у нас установлен разделитель -;все остальнео место займут пробелы - mov al, ' ' - -;!fixme обработаны не все исключения :( - cmp cl, 3 ;формат файла такой GIDGIDIIASM т.е. gidgidii.asm - jbe .st2 - - -.st3: - mov byte [si], al - inc si - dec cx - cmp cx, 3 - ja .st3 -; inc cx - inc di - jmp @b - -.st2: - cmp al, 0x60 - jbe .st2_l - - xor al, 0x20;сделаем заглавные буквы -.st2_l: - mov byte [si], al - inc di - inc si -; dec cx -; jnz @b - loop @b -.st5: - xor ax, ax - jmp @f - -;;;;;;;;файл закончился, и нужно внести в конец пробелы -.st4_s: - mov al, ' ' -.st4: - mov byte [si], al - inc si - loop .st4 - jmp .st5 - -.error: - or ax, -1 -@@: - -if DEBUG - pushad - - mov si, convertion_file_name_msg_y - test ax, ax - jz @f - mov si, convertion_file_name_msg_n -@@: - call printplain - - mov si, shot_name_fat - mov byte [si+12], 0 - call printplain - popad - -end if -} - -macro move_file_up -;макрос который перемещает за 1 мб с правилами фат данные файла. -{ -local .st1 -local .correct_on_byte -;сейчас имеет быть ситуация, когда BPB уже перемещен за 1 мб, фат, и рут дир будут позже перемещены, -;а нам нужно вычислить место, и перенести туда содержимое файла -;полученое значение указывает в байтах на начало данных - - mov ax, info_real_mode_size ; сегмент где расположены данные - mov si, table_15_87 - mov word [si+8*2+2], ax -;смещение до данных уже за 1-м мб - movzx eax, firstDataSect - movzx edx, data_offset - add eax, edx - - movzx ebx, word [fat12_buffer.BPB_BytsPerSec] - movzx edx, byte [fat12_buffer.BPB_SecPerClus] - imul bx, dx ;получим размер кластера - - - - push ebx ;save bx - - imul eax, ebx -; shl eax,9 ;умножим на 512 - -if DEBUG - pushad - xor eax, eax - mov ax, info_real_mode_size - mov cx, 0x0a - mov di, seg_where_get_data - mov dword [di], ' ' - mov word [di+4], ' ' - call decode -;Show size - mov si, seg_where_get_data - call printplain - popad - -end if - -; mov bx,word [fat12_buffer.BPB_BytsPerSec] -; movzx dx,byte [fat12_buffer.BPB_SecPerClus] -; imul bx,dx -; cwd -; idiv bx - - mov dl, 0x10 - -@@: - cmp eax, 0x00010000 - jb @f - - sub eax, 0x00010000 - inc dl - jmp @b - - -@@: - mov byte [si+8*3+3], dl ;куда писать - mov word [si+8*3+2], ax - - mov ecx, save_file_size ;размер файла в байтах. - cmp ecx, 0x0000ffff ;размер блока т.е. 64 кб - jbe .correct_on_byte ;корректировка на байт значения - - - - mov ecx, 0x00010000 ;65536 - sub save_file_size, ecx ;отнимим -; jmp .st1 ;получим 0х8000 - - - - -;корректировка значения должна быть выполенена на размер кластера -.correct_on_byte: -;/узнаем размер кластера - pop eax ;restore size of claster - push ecx -@@: - inc data_offset - - cmp eax, ecx - jae @f - sub ecx, eax - jmp @b -@@: - pop ecx - - - - - test ecx, 0x1 - jz .st1 - inc ecx -.st1: - shr ecx, 1 ; преобразовать значение для 0x87 function - -;перенесем блок за 1 мб - push es - push ds - pop es - - mov ah, 0x87 - int 0x15 - pop es - -if DEBUG - pusha -; mov ax,point_next_fat_str - mov cx, 0x0a - mov di, return_code_af_move - call decode -;Show size - mov si, return_code_af_move - call printplain - popa - -end if - -} - - -macro move_up_fat_and_root_d -;макрос, который позволяет перенести выше 1 мб в структуру образа фат таблицу и рут директорию -{ -local .st1 - - mov ax, info_real_mode_size - add ax, 0x1000 - - mov si, table_15_87 - mov word [si+8*2+2], ax -;смещение до данных - mov ax, 512 - mov word [si+8*3+2], ax -;fixme! тут необходимо сделать подержку т.е. формировать смещение файла в уже записанных данных. - - movzx ecx, word [fat12_buffer.BPB_FATSz16] - movzx bx, byte [fat12_buffer.BPB_NumFATs] - imul cx, bx ;9x1=9 - - add cx, size_root_dir ;размер корневой дирректории - shl ecx, 9 ;imul 512 - - -;корректировка значения - test ecx, 0x1 - jz .st1 - inc ecx -.st1: - shr ecx, 1 - - push es - push ds - pop es - - mov ah, 0x87 - int 0x15 - pop es - -if DEBUG - pusha -; mov ax,point_next_fat_str - mov cx, 0x0a - mov di, return_code_af_fat_m - call decode -;Show size - mov si, return_code_af_fat_m - call printplain - popa - -end if - -} diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_err.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_err.inc deleted file mode 100644 index 794600b000..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_err.inc +++ /dev/null @@ -1,66 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -error: -.rest_value: - mov di, ax;restore value after repe cmpsb - mov cx, bx - jmp ret_on_ch ;return - -;///// ошибка при находжении длинны секции в параметре default -.error_get_size_d_sect: - leave ;clear array in stack - mov si, not_found_def_sect - jmp err_show_ini - -;/////ERROR -.not_loader: - leave ;clear array in stack - mov si, not_found_sec_loader - jmp err_show_ini - -.default_eq_loader: ;критическая ошибка default секция = loader - leave - mov si, default_eq_loader - jmp err_show_ini -.correct_exit_bl: - leave - mov si, point_to_default_sec_not_found - jmp err_show_ini -.incorect_section_def: - leave - mov si, incorect_section_define - jmp err_show_ini -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;show message error -.LoaderModule: - push word 0xb800 - pop es - - - - - ret diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_loader.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_loader.inc deleted file mode 100644 index 60dff0bbd8..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_loader.inc +++ /dev/null @@ -1,335 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -;блок макросов по обработке секции [loader] -;входные данные: -;es:di - указатель на секцию начинающиюся с '[' встечающиюся после 0хa -;cx - счетчик кол-во байт для проверке в кадре -; -macro use_parse_loader -{ -.parse_loader: -;////////////////// -;/ parse [loader] -;////////////////// - mov bx, cx ;cохраним в регистры значения счетчика и указателя - mov ax, di - -; mov word [bp-4],.start ;is alredy set, see up - mov si, parse_loader - mov cx, parse_loader_e - parse_loader - repe cmpsb - jnz error.rest_value ;цепочка не совпала :( перейдем далее т.е. будем снова искать)) - - ;сохраним указательна loader, что бы потом больше его не искать - mov point_loader, ax - sub bx, parse_loader_e - parse_loader;correct cx - add bx, cx - mov cx, bx - -if DEBUG - pusha - mov si, lm_l_found - call printplain - popa -end if -;/////////////////end check [loader]. [loader] is found -;parsing section [loader] -;first found end section,let's found '[' -it's start next section -;in previosly steep bx =cx we are not need save cx, save only di - point - mov dx, di -@@: - call get_firs_sym - jcxz .loader_f_end ;.end_loader ; end даже если мы не нашли секцию предположим что секция [loader] стоит в конце - cmp al, '[' - jnz @b - -.loader_f_end: - sub bx, cx ;bx = n byte presend in section [loader] - mov di, dx ;restore di -;////////////////parse parametrs in section [loader] -;//timeout=5 -;//default=main -; mov di,dx ;set pointer on section [loader] i think it's not need - mov cx, bx ;set counter for parsing section [loader] cx= кол-ву символов в секции [loader] - mov ret_on_ch, .get_next_str; return point -;;;;;;; parse timeout & default -.get_next_str: - call get_firs_sym ;get first symbol on new line - - test cx, cx - jz .end_loader -; jcxz .end_loader ;завершение парсинга значений timeout & default - cmp al, 't' - jz .loader_timeout - cmp al, 'd' - jnz .get_next_str -;//////[loader].default -;input di point to data cx=size [loader] - mov bx, cx - mov ax, di - - mov si, parse_l_default - mov cx, parse_l_default_e - parse_l_default - repe cmpsb - - jnz error.rest_value ;is not compare цепочка не совпала - - sub bx, parse_l_default_e - parse_l_default;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_default - jz .correct_is_not_set - - mov si, found_equal_default ;мы нашли что флаг уже установлен, информируем - call printplain - jmp .get_next_str - -.correct_is_not_set: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - test cx, cx - jz .end_loader - - cmp ah, byte [es:di-1] ;find '=' - jnz .get_next_str - - repe scasb ;cut ' ' - inc cx - dec di -;сейчас es:di указывают на название секции, имя секции по дефолту не должно быть loader т.е. иначе возможно зацикливание -;установим указатель si на это значение и сначала проверим - -;получение длинны секции -; cx=bx содержит длинну остатка секции -; di=ax указатель на текущию секцию - mov bx, cx - mov dx, di - -@@: - mov al, byte [es:di] - inc di - dec cx - test cx, cx - jz error.error_get_size_d_sect ;переход на обработку ошибки по нахождению длины дефолтной секции - cmp al, ' ' - jz @b - cmp al, 0xd - jz .found_size_d_sect - cmp al, 0xa - jnz @b -.found_size_d_sect: -; - inc cx ;correct cx - mov ax, bx - sub bx, cx ; в bx длина секции которая определена по дефолту - mov save_cx_d, bx - mov di, dx - - mov cx, bx ;set size default section -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;проверка на =loader -;save in reg point and счетчик -;check on loader - mov bx, ax - mov ax, dx - - mov si, parse_loader - inc si ;set only loader and 6 char in counter - repe cmpsb - jnz .check_section ;цепочка не совпала :( перейдем далее )) значит не исключение - - jmp error.default_eq_loader ;error критическая ошибка т.е. в дефолте присутствует имя [loader] - -.check_section: ;поиск соответствующей секции нам нужно будет узнать адрес этой секции - mov cx, bx - mov di, ax - -;///////////////////////////// -; mov ret_on_ch,.start_d ;set return - mov si, di ;установим указатель на нашу секцию, которая по дефолту - - push di ;save point di - - push cx ;save cx -;установим указатель es:di на начало ini файла - mov cx, save_cx ;it's placed size of ini file - les di, dword [file_data] - - - mov al, byte [es:di] - push word .first_ret_d - cmp al, ' ' - jz .first_sp_1_d - jmp get_firs_sym.not_space -.first_sp_1_d: - jmp get_firs_sym.first_sp - -.start_d: - call get_firs_sym ;get first symbol on new line -.first_ret_d: ;первый возврат - jcxz .correct_exit ;.end_loader ;found or not found parametrs in section exit in section - cmp al, '[' - jz .found_sect_d - jmp .start_d -;просматриваем ini файл с начала в поисках секции указаной как default -;идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти -.found_sect_d: - -;check on name section - mov bx, cx - mov ax, di - push si ;save point - -; mov si,parse_loader - mov cx, save_cx_d;load size section - push es - pop ds - - inc di - repe cmpsb - push cs - pop ds - pop si - - jnz .not_compare_d_s ;цепочка не совпала :( перейдем далее )) значит не исключение - cmp byte[es:di], ']' - jnz .not_compare_d_s ;нет в конце нашей секции завершающего символа :( - - - -;set flag -we have found default -not enter again in this prosedure - or status_flag, flag_found_default - pop cx - pop di - mov point_default, ax ;point to [ - -if DEBUG - pusha - mov si, lm_lf_default_f - call printplain - popa -end if - - jmp .get_next_str - -.not_compare_d_s: - - mov cx, bx - mov di, ax - jmp .start_d - -.correct_exit: - pop cx ;восстановим значение счетчика - pop di - - -if DEBUG - pusha - mov si, lm_lf_default - call printplain - popa -end if - jmp .get_next_str - -;//////////[loader].timeout -.loader_timeout: - mov bx, cx - mov ax, di - - mov si, parse_l_timeout - mov cx, parse_l_timeout_e - parse_l_timeout - repe cmpsb - jnz error.rest_value ;is not compare - - sub bx, parse_l_timeout_e - parse_l_timeout;correct cx - add bx, cx - mov cx, bx - - test status_flag, flag_found_timeout - jz .correct_is_not_set_t - - mov si, found_equal_timeout ;мы нашли что флаг уже установлен, информируем - call printplain - jmp .get_next_str - -.correct_is_not_set_t: - mov ax, 0x3d20 ;cut al=' ' ah='=' - repe scasb - jcxz .timeout_sec_end_d ;not found param timeout - - cmp ah, byte [es:di-1] ;find '=' - jnz .get_next_str - - repe scasb ;cut ' ' - inc cx - dec di -;get timeout value -;2 знакa может быть обработано т.е. значение от 0 до 99 секунд - push cx - xor bx, bx - mov cx, 2 -@@: - mov al, byte [es:di] - cmp al, '0' - jb .end_get_val_t - cmp al, '9' - ja .end_get_val_t - imul bx, 10 - xor al, 0x30 - add bl, al -.end_get_val_t: - inc di - loop @b - mov word [value_timeout], bx -; pop cx - -if DEBUG - pusha - mov si, lm_lf_timeout - call printplain - popa -end if - - jmp @f -.timeout_sec_end_d: - mov word [value_timeout], default_timeout_value - mov si, set_default_timeout_val - call printplain -@@: - pop cx - jmp .get_next_str - -;///////here end block loader -.end_loader: -if DEBUG - pusha - mov si, lm_l_end - call printplain - popa -end if - -} diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_equ.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_equ.inc deleted file mode 100644 index 15ef90ccda..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_equ.inc +++ /dev/null @@ -1,98 +0,0 @@ -; Copyright (c) 2008-2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** -; Предопределения -DEBUG equ 1 ;компиляция с отладочной информацией =1 без отладочной инфорации =0 -loop_read_startos_file equ 3 ;кол-во попыток считать через callback сервис файл конфигурации блок2 -root_dir_entry_count equ 224 ;кол-во элементов в корневой дирректории -;point_to_fat_struc equ 0xA000 ;временный буфер, куда будет размещена Fat таблица, и затем перенесена за 1 мб -ini_data_ equ 0x2000 ;файл где размещен файл сценария загрузки, там происходит синтаксический разбор -size_show_section equ 18 -default_timeout_value equ 5 ;default value to timeout is will was some errors -flag_found_default equ 0x1 ;default value is found -flag_found_timeout equ 0x2 ;timeout value is found -flag_found_LM equ 0x1 ;found LM value -flag_found_RS equ 0x2 ;found RS value -flag_found_GTRFMS equ 0x4 ;found type RamFS -flag_found_RamdiskSector equ 0x8 ;found RamdiskSector -flag_found_RamdiskCluster equ 0x16 ;found RamdiskCluster -;statick data эти данные не предопределяются в течении выполнения всей программы. -save_cx equ word [bp-2] ;save cx size ini file -ret_on_ch equ word [bp-4] ;point to return разрушаемое значение -save_cx_d equ word [bp-6] ;save cx - size default section and working section -status_flag equ word [bp-8] ;status flag -point_loader equ word [bp-10] -point_default equ word [bp-12] ;point to default - -;данные которые зависимы от ветки выполнения и которые могут быть переопределены в процессе выполнения программы. -point_to_hframe equ word [bp-14] ;point on start frame (for change section) -point_to_1 equ word [bp-16] -point_to_2 equ word [bp-18] -point_to_3 equ word [bp-20] -point_to_4 equ word [bp-22] -point_to_5 equ word [bp-24] -point_to_6 equ word [bp-26] -point_to_7 equ word [bp-28] -point_to_8 equ word [bp-30] -point_to_9 equ word [bp-32] -point_to_10 equ word [bp-34] -point_to_11 equ word [bp-36] -point_to_12 equ word [bp-38] -point_to_13 equ word [bp-40] -point_to_14 equ word [bp-42] -point_to_15 equ word [bp-44] -point_to_16 equ word [bp-46] -point_to_16 equ word [bp-48] -point_to_17 equ word [bp-50] -point_to_18 equ word [bp-52] -;here array for fast scroling 16 word - poin to start section -point_to_point_def equ word [bp-54] -point_to_eframe equ word [bp-56] ;point on point frame - - - -; тут расположено временное хранилище для cx и di при переходе на следующий буфер при поиске секций -find_sec_di equ word [bp-58] ;тут будет храниться di -info_real_mode_size equ word [bp-60];тут храниться информация о занятой области т.е. размер, можно узнать сколько осталось места вычислив -free_ad_memory equ word [bp-62] ;сколько у нас расширенной памяти для формирования рам диска и загрузки модулей -show_errors_sect equ word [bp-64] ;переменая которая хранит биты ошибок для каждой логической секции. -save_descript_size equ word [bp-66] ;save descript size previos section сохраним размер предыдущей секции которую выводили -save_ramdisksize equ dword [bp-70] ;save size of ramdisk in byte -save_file_size equ dword [bp-74] ;save size of reading file -set_ramfs equ word [bp-76] ;определенный тип файловой системы,нужно для формирования рам диска -point_next_fat_str equ word [bp-78] ;указатель на следующий элемент fat таблицы -size_root_dir equ word [bp-80] ;кол-во элементов в секторах по 512 байт корневой директории -firstDataSect equ word [bp-82] ;первый сектор данных в сеторах от 0 -DataClasters equ word [bp-84] ;размер массива доступной для записи данных в кластерах. -point_to_free_root equ word [bp-86] ;указатель на следующий пустую запись в рут дир -point_to_dest_file_name equ word [bp-88] ;указывает на начало имени файла назначения. в формате es:point_to_dest_file_name, где es =0x2000 -data_offset equ word [bp-90] ;смещение в кластерах для записанных данных т.е перекинутых за 1-й мб -first_input equ word [bp-92] ;поле для флагов в преобразовании имени. -save_di_RAMDISK equ word [bp-94] ;сохраним di -указателя при обработке секции -save_cx_RAMDISK equ word [bp-96] ;сохраним размер остатка секции -status_flag_loader_f equ word [bp-98] ;сохраним результат выполенения загрузки файла -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;данные которые используются при обработке секции, т.е. после нажатия Enter, уже не возможно вернуться в первоначальный экран -;для возврата, необходимо перезапустить полностью код т.е. стартовать с 0х1000:0000 diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_proc.inc b/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_proc.inc deleted file mode 100644 index 8032f4dd39..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_proc.inc +++ /dev/null @@ -1,528 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; тут описываются процедуры которые используются в secondary loader -color_sym_black equ 0 -color_sym_blue equ 1 -color_sym_green equ 2 -color_sym_turquoise equ 3 -color_sym_red equ 4 - -color_sym_lightgray equ 7 - -color_sym_lightblue equ 9 -color_sym_lettuce equ 10 -color_sym_pink equ 12 -color_sym_yellow equ 14 -color_sym_white equ 15 -if DEBUG -decode: -;input eax - число, es:di куда писать, cx=10 - cmp eax, ecx - jb @f - xor edx, edx - div ecx - push edx - call decode - pop eax - @@: - or al, 0x30 - mov [ds:di], al - inc di - ret - -end if - - -putchar: -; in: al=character - mov ah, 0Eh - mov bh, 0 - int 10h - ret - -printplain: -; in: si->string - pushad - lodsb -@@: - call putchar - lodsb - test al, al - jnz @b - mov al, 13 - call putchar - - mov al, 10 - call putchar - popad - ret -getkey: -; get number in range [bl,bh] (bl,bh in ['0'..'9']) -; in: bx=range -; out: ax=digit (1..9, 10 for 0) - mov ah, 0 - int 16h - cmp al, bl - jb getkey - cmp al, bh - ja getkey - push ax - call putchar - pop ax - and ax, 0Fh - jnz @f - mov al, 10 -@@: - ret - -;setcursor: -; in: dl=column, dh=row -; mov ah, 2 -; mov bh, 0 -; int 10h -; ret - -;macro _setcursor row,column -;{ -; mov dx, row*256 + column -; call setcursor -;} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -get_firs_sym: -.start: - mov al, byte [es:di] - inc di - dec cx - jcxz .exit - - cmp al, 0xa ;cmp al,0xa - jz ._entry - - cmp al, ';' - jnz .start - -.first_com: - - mov al, 0xa - repnz scasb - jcxz .exit -._entry: - mov al, byte [es:di] -.first_sp: - cmp al, ' ' - jnz .not_space - -; mov al,' ' ;cut ' ' - repe scasb - dec di - inc cx - mov al, byte [es:di] -.not_space: - cmp al, ';' - jz .first_com -.exit: - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -show_name_section: - push si - push ini_data_ - pop es - - - mov al, ']' - repnz scasb - test cx, cx - jz error.incorect_section_def -.find_val_name_fb1: - mov al, 'n' -.find_val_name_fb: - repnz scasb - jcxz .not_name_sec_fb - - mov si, parse_name - - push cx - push di - - mov cx, parse_name_e -parse_name - repe cmpsb - pop di - pop cx - jz .yaaa_find_value - - - jmp .find_val_name_fb - -.yaaa_find_value: - sub cx, parse_name_e -parse_name - add di, parse_name_e -parse_name - - mov ax, 0x3d20 ; ah='=' - repe scasb - test cx, cx - jz .not_name_sec_fb - - cmp ah, byte [es:di-1] ;find '=' - jnz .find_val_name_fb1 - - repe scasb ;cut ' ' - inc cx - dec di - - -;все вырезали и все готово для вывода имени секции )) - push es - pop ds - -.def_sect_name: - push 0xb800 - pop es -;clear array for message - xor ax, ax -if DEBUG - mov ax, 0x0720 -end if - - mov cx, 39 - mov si, di - mov di, dx - sub di, 2 - rep stosw -;////////////////////// - - - mov di, dx - mov ah, color_sym_white;color_sym_lightblue - mov cx, 36 - lodsb - sub di, 2 - cmp al, '"' - jz @f - cmp al, "'" - jnz .end_sh_name_sec -@@: - lodsb -@@: - stosw - lodsb - cmp al, '"' - jz .end_sh_name_sec - cmp al, "'" - jz .end_sh_name_sec - loop @b - - mov al, '}' - mov ah, color_sym_yellow - stosw -.end_sh_name_sec: - push cs - pop ds - - pop si - ret - -.not_name_sec_fb: ;нет имени в названии секции - значит так и скажем об этом - push cs - pop ds - mov di, default_section_name - jmp .def_sect_name - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;процедура поиска вверх следующей секции -;в point_default содержиться указатель на дефаулт секцию, и в пределах врейма мы бегаем по заранее пропарсеными значениям указателей -;для того что бы отобразить и пропарсить следующий фрейм, нам нужно получить за пердыдущий или следующий указатель -find_before_sect: - mov di, point_default -.e: - push ini_data_ - pop es - mov cx, di ;предположим будем просматривать к началу, текущая позиция di = сколько символов от начала документа имеется - mov bx, cx ;копия - -;настроили указатель на дефаулт секцию -;будем искать вверх -.find_start_section: - std ;установка флага направления - будем просматирвать к началу нашего ини файла -;будем искать начало секции т.е. '[' этот символ - mov al, 0xa - repnz scasb ;просканируем на наличее символа начала секции - jcxz .go_ ;мы просмотрели до начала файла, но так и ничего не нашли ;(( по тихому выйдем ) - - mov find_sec_di, di ;сохраним данные - mov cx, di ; - - sub bx, cx - mov cx, bx ;в сx значение - кол-во символов - cld - call get_firs_sym -.ret_go: - jcxz ._not_section ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее - - cmp di, point_loader; секцию loader мы не заносим иначе крах - jz ._not_section -;все удачно мы нашли вхождение секции предыдущей - cmp al, '[' - jnz ._not_section - mov point_default, di -.exit_scan_sect: - ret -;;;;;;;; восстановим значения и продолжим поиски начала секции которая нас устроит )) -._not_section: - mov di, find_sec_di - mov cx, di - mov bx, cx - jmp .find_start_section -.go_: - cld - mov cx, bx ;в сx значение - кол-во символов - - mov al, byte [es:di] - push word .f_go - cmp al, ' ' - jz @f - jmp get_firs_sym.not_space -@@: - jmp get_firs_sym.first_sp - -.f_go: - jcxz .exit_scan_sect ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее - - cmp di, point_loader; секцию loader мы не заносим иначе крах - jz .exit_scan_sect -;все удачно мы нашли вхождение секции предыдущей - cmp al, '[' - jnz .exit_scan_sect - mov point_default, di - ret - - - - - - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -find_next_sect: - mov di, point_default - push ini_data_ - pop es - mov cx, save_cx;di ;предположим будем просматривать к концу, текущая позиция di = сколько символов от начала документа имеется - sub cx, di ;сейчас в cx остаток т.е. сколько можно крутить до конца и не вылазить на начало - jmp .let_s_go -.h: - push ini_data_ - pop es - mov cx, save_cx;di ;предположим будем просматривать к концу, текущая позиция di = сколько символов от начала документа имеется -; sub cx,di ;сейчас в cx остаток т.е. сколько можно крутить до конца и не вылазить на начало - - mov al, byte [es:di] - push word .let_s_go_ret - cmp al, ' ' - jz @f - jmp get_firs_sym.not_space -@@: - jmp get_firs_sym.first_sp - - - - -;настроили указатель на дефаулт секцию -;будем искать вниз -.let_s_go: - call get_firs_sym -.let_s_go_ret: - jcxz .exit_scan_sect ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее - cmp al, '[' - jnz .let_s_go - cmp di, point_loader - jz .let_s_go -;все удачно мы нашли вхождение секции предыдущей - mov point_default, di -.exit_scan_sect: - ret - -;;;;;;;;;;;;;;;;;;;;;;;;;; -;clean old cursor -clean_active_cursor: -;не изменяет значение ax -;отображение курсора по умолчанию - lea si, point_to_hframe - mov di, 962-160 - mov dx, point_default - mov cx, 18 -.clean_show_cur: - mov bx, [si] - add di, 160 - cmp bx, dx - jz .clean_cursor_ - sub si, 2 - loop .clean_show_cur - -; jmp $ - -.clean_cursor_: - push 0xb800 - pop es - push ax - mov point_to_point_def, si - xor ax, ax -if DEBUG - mov ax, 0x0720 -end if - stosw - add di, 68 - stosw - pop ax - ret -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;установка таймера и отображение счетчика времени -gettime: - mov ah, 0 - int 1Ah - xchg ax, cx - shl eax, 10h - xchg ax, dx - ret -newtimer: - push ds - - push cs - pop ds - - pushf - call far dword [old_timer] - - pushad - call gettime - - sub eax, dword[start_timer] - mov bx, word [value_timeout] - imul bx, 18 - sub bx, ax - jbe .timergo - - push es - - push 0xb800 - pop es - mov ax, bx - - mov bx, 18 - xor dx, dx - div bx - - mov bx, 10 - mov di, 3734 - call .decode - - xor ax, ax - stosw - -; wait 5/4/3/2 seconds, 1 second - pop es - popad - pop ds - - iret -.timergo: - push 0 - pop es - mov eax, dword [old_timer] - mov [es:8*4], eax - mov dword [timer_], eax - mov sp, word [start_stack] - mov bp, word [save_bp_from_timer] -;;не восстановленый стек :( - sti - jmp parse_start.parse_run_only - - -.decode: -;input ax - число, es:di куда писать, bx=10 - cmp ax, bx - jb @f - xor dx, dx - div bx - push dx - call .decode - pop ax - @@: - or al, 0x30 - push ax - mov ah, 9 - stosw - pop ax - ret - -show_bl_sc_sect: -;1) отображение списка секций. Если секция не имет имя - ошибка - вывод Section unname -;проверка на наличее имени. -;входные данные es:di -указатель на секцию - cx размер секции -; push bp - mov bx, point_to_eframe - lea si, point_to_hframe - mov dx, 966 - -.home_show_fb: - cmp si, bx - jb ._show_space_fb - mov di, [si] - sub si, 2 - mov cx, [si] - sub cx, di ;home first section it's end before section - call show_name_section - add dx, 160 - jmp .home_show_fb -._show_space_fb: - sub dx, 4 - push 0xb800 - pop es -@@: - cmp dx, 0xE64 - ja .exit_show_fb - mov di, dx -;clear array for message - xor ax, ax -if DEBUG - mov ax, 0x0720 -end if - mov cx, 39 - rep stosw -;////////////////////// - - add dx, 160 - jmp @b -.exit_show_fb: -; pop bp - ret - diff --git a/kernel/branches/Kolibri-acpi/sec_loader/trunk/startos.ini b/kernel/branches/Kolibri-acpi/sec_loader/trunk/startos.ini deleted file mode 100644 index 66e6a6bdde..0000000000 --- a/kernel/branches/Kolibri-acpi/sec_loader/trunk/startos.ini +++ /dev/null @@ -1,98 +0,0 @@ -; Copyright (c) 2009, -; All rights reserved. -; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: -; * Redistributions of source code must retain the above copyright -; notice, this list of conditions and the following disclaimer. -; * Redistributions in binary form must reproduce the above copyright -; notice, this list of conditions and the following disclaimer in the -; documentation and/or other materials provided with the distribution. -; * Neither the name of the nor the -; names of its contributors may be used to endorse or promote products -; derived from this software without specific prior written permission. -; -; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka ''AS IS'' AND ANY -; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -;***************************************************************************** - -; это комментарий - [loader] -; секция [loader] содержит параметры загрузчика -; в течение timeout секунд загрузчик будет ждать реакции пользователя, -; если её не последует, будет загружена конфигурация, указанная в default -timeout=5 - default=kolibri_EE -; прочие секции - по одной на каждую конфигурацию -; и по одной на каждый вторичный модуль -[main] -name="Kord OS v 0.00001" -descript="This is x64 OS microkernel" -kernel=kord/kord001.ker -module=kord/fat.mod -module=kord/ntfs.mod -RamdiskFS=fat -RamdiskSector=512 -RamdiskCluster=1 -RamdiskSize=1440K -RamdiskFile=kord/launcher,launcher -RamdiskFile=kord/filema~1/kfar,"File Managers/kfar" -[beta] -name="Kord OS v 0.00002 beta" -descript="This is x64 OS microkernel version 2" -kernel=kord/kord002.ker -module=kord/fat.mod -module=kord/ntfs.mod -RamdiskFS=fat -RamdiskSector=512 -RamdiskCluster=1 -RamdiskSize=1440K -RamdiskFile=kord/launcher,launcher -RamdiskFile=kord/filema~1/kfar,"File Managers/kfar" -[kolibri_EE] -name="KOLIBRY EXCLUSIVE EDITION" -descript="KOLIBRY EXCLUSIVE EDITION BEST OF THE BEST opetation system" -LoaderModule=kolibri/kolibri.ldm -RamdiskFS=FAT -RamdiskSector=512 -RamdiskCluster=1 -RamdiskSize=1440K -LoaderRamImage=kolibri.img -RamdiskPATH=/kolibri/ -RamdiskFile=@menu,@menu -RamdiskFile=@TASKBAR,@TASKBAR -RamdiskFile=@RB,@TASKBAR - -[legacy_kolibri] -name="KolibriOS" -descript="Standart KolibriOS" -LoaderModule=kord/kolibri.ldm -RamdiskFS=fat -RamdiskSector=512 -RamdiskCluster=1 -RamdiskSize=1440K -RamdiskPATH=/kolibri/ -RamdiskFile=@menu,@menu -RamdiskFile=@TASKBAR,@TASKBAR -RamdiskFile=@RB,@RB -RamdiskFile=@rcher,@rcher -RamdiskFile=@ss,@ss -RamdiskFile=ac97snd,ac97snd -RamdiskFile=animage,animage -RamdiskFile=AUTOEXEC.CMD,AUTOEXEC.CMD -RamdiskFile=AUTORUN.DAT,AUTORUN.DAT -RamdiskFile=calc,calc -RamdiskFile=calendar,calendar -RamdiskFile=progs/cdp,cdp -RamdiskFile=cmd,cmd -RamdiskFile=config.inc,config.inc -RamdiskFile=copy2,copy2 -