Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1941 → Rev 1942

/kernel/branches/kolibri-cfg/bootloader/after_win/kordldr.win.asm
0,0 → 1,921
; 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 <organization> 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 <Lrz> ''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 <copyright holder> 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
/kernel/branches/kolibri-cfg/bootloader/after_win/build.bat
0,0 → 1,2
@fasm -m 65535 kordldr.win.asm kordldr.win
@pause
/kernel/branches/kolibri-cfg/bootloader/after_win/fat.inc
0,0 → 1,509
; 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 <organization> 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 <Lrz> ''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 <copyright holder> 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
/kernel/branches/kolibri-cfg/bootloader/after_win/kordldr.win.txt
0,0 → 1,391
; 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 <organization> 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 <Lrz> ''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 <copyright holder> 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. Äîáàâëÿåò ñåêòîð â êîíåö ñïèñêà (ñàìûé íîâûé âõîä).
/kernel/branches/kolibri-cfg/bootloader/after_win/ntfs.inc
0,0 → 1,587
; 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 <organization> 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 <Lrz> ''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 <copyright holder> 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 <eax> 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
/kernel/branches/kolibri-cfg/bootloader/after_win/.
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property