Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2782 → Rev 2783

/programs/hd_load/mtldr/fat32.inc
0,0 → 1,112
fat32_parse_dir:
; in: eax=directory cluster
; out: eax=entry cluster
mov bx, 900h
mov di, bx
push eax
call read_cluster
mov cx, word [cluster_size]
shr cx, 5 ; div 20h
.scan_cluster:
pop eax
cmp byte [di], 0
jz file_not_found
mov si, [esp+2]
push eax
call fat_compare_name
jz .file_found
and di, not 1Fh
add di, 20h
loop .scan_cluster
pop eax
call next_cluster
jnc file_not_found
jc fat32_parse_dir
.file_found:
pop eax
mov si, [esp+2]
mov [cur_obj], si
and di, not 1Fh
mov si, directory_string
mov ax, [di+14h]
shl eax, 10h
mov ax, [di+1Ah]
test eax, eax
mov si, nodata_string
jz find_error_si
ret 2
 
fat_compare_name:
push cx
mov cx, 9
.scan:
lodsb
cmp al, '.'
jz .ext
cmp al, 0
jz .nameend
cmp al, 'a'
jb .notletter
cmp al, 'z'
ja .notletter
or byte [di], 20h
.notletter:
scasb
loopz .scan
.notfound:
inc cx ; to clear ZF flag
pop cx
ret
.ext:
mov al, ' '
dec cx
repz scasb
jnz .notfound
test di, 1
jnz .notfound
mov cx, 4
jmp .scan
.nameend:
mov al, ' '
dec cx
repz scasb
jnz .notfound
test di, 1
jnz .file_found
mov cx, 3
repz scasb
jnz .notfound
.file_found:
xor cx, cx ; to set ZF flag
pop cx
ret
 
read_cluster:
; in: eax=cluster,bx->buffer
and eax, 0FFFFFFFh
movzx ecx, byte [50Dh] ; sects_per_clust
mul ecx
add eax, [data_start]
; call read
; ret
jmp relative_read
next_cluster:
mov bx, 700h
; sector is 200h bytes long, one entry in FAT occupies 4 bytes => 80h entries in sector
push eax
shr eax, 7 ; div 80h
cmp eax, [fat_cur_sector]
jz @f
mov [fat_cur_sector], eax
add eax, [fat_start]
mov cx, 1
call relative_read
@@:
pop eax
and eax, 7Fh
mov eax, [700h+eax*4]
and eax, 0FFFFFFFh
cmp eax, 0FFFFFF7h
mov si, bad_cluster_string
jz find_error_si
ret
/programs/hd_load/mtldr/install.txt
0,0 → 1,101
“áâ ­®¢ª  ®áãé¥á⢫ï¥âáï á«¥¤ãî騬 ¯à®áâë¬ á¯®á®¡®¬:
˜ £ 1. ‘ª®¯¨àã©â¥ ä ©«ë mtldr ¨ kolibri.img ¢ C:\
(¥ ­à ¢¨âáï C:\? à®ç¨â ©â¥ § ¬¥ç ­¨ï ­¨¦¥.)
 
˜ £ 2 ) „«ï ¯®«ì§®¢ â¥«¥© NT-ᥬ¥©á⢠ ¤® Vista (NT/2k/XP/2003 Server (?)):
¤®¡ ¢ì⥠¢ boot.ini ¢ à §¤¥« [operating systems] áâபã
c:\mtldr="KolibriOS"
(«¨¡® ®âªàë¢ «î¡ë¬ ⥪áâ®¢ë¬ à¥¤ ªâ®à®¬ c:\boot.ini,
«¨¡® ç¥à¥§ Control Panel -> System -> Advanced -> Startup and Recovery
-> Edit).  §¢ ­¨¥ ¢ ª ¢ëçª å ¬®¦¥â¥ § ¬¥­¨âì ­  ¢áñ, çâ® ¢ ¬ ­à ¢¨âáï,
¯®¤ í⨬ ­ §¢ ­¨¥¬ á¨á⥬  ¡ã¤¥â ¯®ï¢«ïâìáï ¢ ᯨ᪥ § £à㧪¨.
’¥¯¥àì ¯à¨ § £à㧪¥ ¡ã¤¥â ¢ë¤ ¢ âìáï íªà ­ ¢ë¡®à  ®¯¥à æ¨®­­®© á¨á⥬ë.
 
˜ £ 2¡) „«ï ¯®«ì§®¢ â¥«¥© 9x-ᥬ¥©á⢠ (95/98)
(  ¬®¦¥â ¡ëâì, íâ® ¡ã¤¥â à ¡®â âì ¨ ¤«ï ­¥ª®â®àëå DOS):
¤®¡ ¢ì⥠¢ config.sys áâபã
install=c:\mtldr
¯¥à¢®© áâப®©, ¥á«¨ ã ¢ á ¯à®á⮩ «¨­¥©­ë© config.sys,
¯¥à¢®© áâப®© ¢ ᮮ⢥âáâ¢ãî饩 ᥪ樨, ¥á«¨ config.sys
à §¡¨â ­  ᥪ樨 (¨ ­ ç¨­ ¥âáï á [menu])
’¥¯¥àì ¯à¨ § £à㧪¥ mtldr ¡ã¤¥â á¯à è¨¢ âì: "Load KolibriOS? [y/n]: " ¨ ®¦¨¤ âì
­ ¦ â¨ï ®¤­®£® ¨§ 'y','Y','n','N'.
 
„«ï Windows Millenium íâ® ­¥ à ¡®â ¥â, â.ª. Me'è­ë© § £àã§ç¨ª ­¥
§ £à㦠¥â ¢­¥è­¥£® ª®¤  ¨§ config.sys. (‘¯ á¨¡® camper'ã §  㪠§ ­¨¥
­  íâ®â ¯à¨áª®à¡­ë© ä ªâ.) ˆá¯®«ì§ã©â¥ 9x2klbr.
 
˜ £ 2¢) „«ï ¯®«ì§®¢ â¥«¥© Vista:
®âªà®©â¥ ª®¬ ­¤­ãî áâபã á  ¤¬¨­¨áâà â®à᪨¬¨ ¯à¨¢¨«¥£¨ï¬¨
(¯ã­ªâ "Run as administrator" ¢ ª®­â¥ªáâ­®¬ ¬¥­î);
¥á«¨ ¢ë ­¥ ¯« ­¨àã¥â¥ ãáâ ­®¢ª¨ ­¥áª®«ìª¨å ¢ à¨ ­â®¢ Š®«¨¡à¨
ª ª ®¯¨á ­® ¢ § ¬¥ç ­¨ïå, ¯à®áâ® § ¯ãáâ¨â¥ ¯à¨« £ ¥¬ë© vista_install.bat;
¨­ ç¥ ¢ë¯®«­¨â¥ á«¥¤ãî騥 ª®¬ ­¤ë:
bcdedit /create /d "KolibriOS" /application BOOTSECTOR
( §¢ ­¨¥ ¢ ª ¢ëçª å ¬®¦¥â¥ § ¬¥­¨âì ­  ¢áñ, çâ® ¢ ¬ ­à ¢¨âáï,
¯®¤ í⨬ ­ §¢ ­¨¥¬ á¨á⥬  ¡ã¤¥â ¯®ï¢«ïâìáï ¢ ᯨ᪥ § £à㧪¨.)
„®«¦­® ¯®ï¢¨âìáï á®®¡é¥­¨¥ ⨯ 
"‡ ¯¨áì {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} ãᯥ譮 ᮧ¤ ­ ."
„ «¥¥ ¢ ª®¬ ­¤ å ¯®¤áâ ¢«ï©â¥ ¯®«ã祭­®¥ §­ ç¥­¨¥ (®­®, ¢®®¡é¥ £®¢®àï,
à §­®¥ ­  à §­ëå ª®¬¯ìîâ¥à å).
bcdedit /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} DEVICE PARTITION=C:
bcdedit /set {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} PATH \mtldr
bcdedit /displayorder {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} /addlast
 
“¤ «¥­¨¥ ¢ á«ãç ïå 2 ) ¨ 2¡) ®áãé¥á⢫ï¥âáï 㤠«¥­¨¥¬ ¢¢¥¤ñ­­ëå ¤ ­­ëå ¢
boot.ini ¨ config.sys ᮮ⢥âá⢥­­®. “¤ «¥­¨¥ ¢ á«ãç ¥ 2¢) ¤¥« ¥âáï â ª:
 
vista_remove.bat, ¥á«¨ ãáâ ­®¢ª  ¡ë«  ç¥à¥§ vista_install.bat;
bcdedit /delete {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} ¢ ®¡é¥¬ á«ãç ¥
 
…᫨ ¢ë ­¥ ¯®¬­¨â¥ ­ §­ ç¥­­ë© ¯à¨ ãáâ ­®¢ª¥ GUID (íâ® ­®à¬ «ì­®¥ ¥­¨¥),
⮠㧭 âì ¥£® ¬®¦­®, ¢ë¯®«­¨¢ ª®¬ ­¤ã bcdedit ¡¥§  à£ã¬¥­â®¢ ¨ ­ ©¤ï
¢ ¢ë¢¥¤¥­­®¬ ᯨ᪥ ᮮ⢥âáâ¢ãî騩 í«¥¬¥­â.
 
‚® ¢á¥å á«ãç ïå ¢ íªà ­¥ ¢ë¡®à  ¯ à ¬¥â஢ KolibriOS ¬®¦­® ­  ¢®¯à®á,
®âªã¤  £à㧨âì ®¡à § (¯ã­ªâ d, "®¡à § ¤¨áª¥âë"),
®â¢¥ç âì "3" (¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §).
 
‡ ¬¥ç ­¨ï:
 
1. ®ª  çâ® ¢áñ íâ® à ¡®â ¥â ¤«ï ä ©«®¢ëå á¨á⥬ NTFS ¨ FAT32, ¯®¤¤¥à¦ª  FAT16
­¥ ॠ«¨§®¢ ­  ¢ á¢ï§¨ á ¬®¨¬ £«ã¡®ª¨¬ ã¡¥¦¤¥­¨¥¬, ç⮠ᥩç á FAT16 - ®¡ê¥ªâ
ç¨áâ® ¨áâ®à¨ç¥áª¨©. …᫨ ¢ë ¨á¯®«ì§ã¥â¥ FAT16, ã ¢ á á⮨â Windows ¨ ¢ë ¯®
ª ª¨¬-â® ¯à¨ç¨­ ¬ ­¥ å®â¨â¥ ¯¥à¥å®¤¨âì ­  FAT32 - ­ ¯¨è¨â¥ ¬­¥
- ¬®¦¥â ¡ëâì, ¢ ¬ 㤠áâáï ¬¥­ï ¯¥à¥ã¡¥¤¨âì.
 
2. ‘ ¬ § £àã§ç¨ª mtldr ­¥®¡ï§ â¥«ì­® ¯®¬¥é âì ¢ C:\. ®¤ 9x ¨ Vista ®­ ¬®¦¥â
à §¬¥é âìáï £¤¥ 㣮¤­®, ¢ NT/2k/XP - ­  ¤¨áª¥ C:, ­® ­¥®¡ï§ â¥«ì­®
¢ ª®à­¥¢®© ¯ ¯ª¥. ( §ã¬¥¥âáï, ¯à¨ ãáâ ­®¢ª¥ ­ã¦­® 㪠§ë¢ âì ¢¬¥áâ®
c:\mtldr ॠ«ì­ë© ¯ãâì ¨ ॠ«ì­®¥ ¨¬ï ä ©« .)
 
3. Ž¡à § kolibri.img ⮦¥ ­¥®¡ï§ â¥«ì­® ¯®¬¥é âì ¢ C:\. Œ®¦­® ¡¥§ ¢á直å
¨§¬¥­¥­¨© ¢ ãáâ ­®¢ª¥ ¨á¯®«ì§®¢ âì ª®à­¥¢ãî ¯ ¯ªã «î¡®£® «®£¨ç¥áª®£® ¤¨áª ,
à §¬¥é î饣®áï ­  ¯¥à¢®¬ 䨧¨ç¥áª®¬.
 
4. …᫨ å®ç¥âáï ¨á¯®«ì§®¢ âì «®£¨ç¥áª¨© ¤¨áª ­  ¤à㣮¬ 䨧¨ç¥áª®¬ ¤¨áª¥?
‘£®¤¨âáï «î¡®© ¨§ á«¥¤ãîé¨å ¢ à¨ ­â®¢:
a) (…᫨ ¢ë 㬥¥â¥ à ¡®â âì á FASM'®¬) ‚ ¨á室­¨ª å (ª®â®àë¥ ¬®¦­® ᪠ç âì
­  http://diamondz.land.ru, â ¬ ¦¥, £¤¥ ¨ á ¬ § £àã§ç¨ª) ¯®¬¥­ï©â¥
ª®­áâ ­âã boot_drive (¢ ª®­æ¥ mtldr.asm) á 80h ­  ¨¤¥­â¨ä¨ª â®à ¤¨áª ,
80h ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã, 81h - ¢â®à®¬ã ¨ â.¤. ¥à¥ª®¬¯¨«¨àã©â¥.
¡) (…᫨ ¢ë 㬥¥â¥ à ¡®â âì á hex-। ªâ®à®¬) ®¬¥­ï©â¥ ¡ ©â ¯® ᬥ饭¨î 0xD98
á 80h ­  ¨¤¥­â¨ä¨ª â®à ¤¨áª  (ª ª ¢ ¯ã­ªâ¥  ).
¢) ˆá¯®«ì§ã©â¥ ãáâ ­®¢é¨ª mtldr_install (᪠ç âì ¥£® ¬®¦­® â ¬ ¦¥).
Ž­ ­ áâந⠧ £àã§ç¨ª ¨ á ¬ ¦¥ ¥£® ¨ ãáâ ­®¢¨â.
 
5. …᫨ 祬-â® ­¥ ­à ¢¨âáï ª®à­¥¢ ï ¯ ¯ª ? ’ãâ ¯®ï¢«ïîâáï ¤¢  ¢ à¨ ­â :
 ) ‚ ¨á室­¨ª å ¯®¬¥­ï©â¥ áâபã kolibri_img_name (¢ ª®­æ¥ mtldr.asm)
­  ¯ãâì ª ä ©«ã.  ¯à¨¬¥à, ¤«ï C:\Program Files\kolibri\kolibri.img § ¯¨è¨â¥
'progra~1\kolibri\kolibri.img' (¯à¨ í⮬ ­ã¦­ë ¨¬¥­  8.3). ¥à¥ª®¬¯¨«¨àã©â¥.
¡) ˆá¯®«ì§ã©â¥ ãáâ ­®¢é¨ª mtldr_install.
 
6. …᫨ ¢®á¯®«ì§®¢ âìáï ४®¬¥­¤ æ¨ï¬¨ ¯ã­ªâ®¢ 2 ¨ 5 ¨ ¯®¢â®à¨âì ãáâ ­®¢ªã
­¥áª®«ìª® à § ¤«ï à §­ëå à á¯®«®¦¥­¨© á¢ï§ª¨ mtldr+kolibri.img,
¬®¦­® ¯®«ãç¨âì ¢ § £à㧮筮¬ ¬¥­î ­¥áª®«ìª® ¢å®¤®¢ ¤«ï à §­ëå ¢¥àᨩ
Š®«¨¡à¨ (¨«¨ ¤«ï ¢¥àᨩ á à §­ë¬¨ ­ áâனª ¬¨).
 
7. ®¦¥« ­¨ï, § ¬¥ç ­¨ï, ¯à¥¤«®¦¥­¨ï ¢ëáë« ©â¥ ­  ¬ë«®, 㪠§ ­­®¥ ­¨¦¥.
 
diamond
mailto: diamondz@land.ru
/programs/hd_load/mtldr/mtldr.asm
0,0 → 1,852
; KolibriOS bootloader
; this code has been written by diamond in 2005,2006,2008 specially for KolibriOS
 
; this code is loaded by ntldr to 0D00:0000
; and by io.sys from config.sys to xxxx:0100
; and by bootmgr in vista to 0000:7C00
format binary
use16
 
org 0xD000
; entry point for 9x and Vista booting
call @f
; db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
db 'NTFS'
@@:
pop si
sub si, 3
cmp si, 7C00h
jz boot_vista
mov si, load_question + 100h - 0D000h
call out_string
; mov si, answer + 100h - 0D000h ; 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:
lodsb
test al, al
jz .xxx
mov ah, 0Eh
mov bx, 7
int 10h
jmp out_string
.xxx: ret
xxz:
; boot KolibriOS
call out_string
push 0
pop ds
mov word [4], new01handler + 100h - 0D000h
mov [6], cs
pushf
pop ax
or ah, 1
push ax
popf
; int 19h
; pushf ; there will be no iret
call far [19h*4]
xxt:
; TF has been cleared when entered new01handler
; pushf
; pop ax
; and ah, not 1
; push ax
; popf
xor di, di
mov ds, di
cmp word [8*4+2], 0F000h
jz @f
les bx, [8*4]
mov eax, [es:bx+1]
mov [8*4], eax
@@:
mov si, 100h
boot_vista:
push cs
pop ds
push 0D00h
pop es
mov cx, 2000h/2
rep movsw
jmp 0D00h:0256h
load_question db 'Load KolibriOS? [y/n]: ',0
answer db ?
db 13,10,0
 
new01handler:
; [sp]=ip, [sp+2]=cs, [sp+4]=flags
push bp
mov bp, sp
push bx
push ds
lds bx, [bp+2]
cmp word [bx], 19cdh
jz xxt
pop ds
pop bx
pop bp
iret
 
relative_read:
add eax, [partition_start]
 
; read from hard disk
; drive_size must be already initialized
; in: eax = absolute sector
; cx = number of sectors
; es:bx -> buffer
read:
pushad
cmp eax, [drive_size]
jb .old_style
; new style - LBA, function 42
cmp [has_lba], 0
jz disk_error
; allocate disk address packet on the stack
; qword +8: absolute block number
push dword 0 ; dword +C is high dword
push eax ; dword +8 is low dword
; dword +4: buffer address
push es ; word +6 is segment
push bx ; word +4 is offset
; word +2: number of blocks = 1
; word +0: size of packet = 10h
push dword 10010h
; now pair ss:sp contain address of disk address packet
.patch1:
mov ax, 4200h
mov dl, [boot_drive]
mov si, sp
push ds
push ss
pop ds
int 13h
pop ds
add sp, 10h
.end:
popad
jc disk_error
add bx, 200h
inc eax
dec cx
jnz read
ret
.old_style:
; old style - CHS, function 2
; convert absolute sector in eax to cylinder-head-sector coordinates
; calculate sector
xor edx, edx
movzx ecx, [sectors]
div ecx
; sectors are counted from 1
inc dx
mov cl, dl ; low 6 bits of cl = sector number
; calculate head number
shld edx, eax, 10h ; convert eax to dx:ax
div [heads]
mov dh, dl ; dh = head
mov ch, al ; ch = low 8 bits of cylinder
shl ah, 6
or cl, ah ; high 2 bits of cl = high 2 bits of cylinder
.patch2:
mov ax, 201h ; function 2, al=1 - number of sectors
mov dl, [boot_drive]
int 13h
jmp .end
 
disk_error:
mov si, disk_error_msg
call out_string
jmp $
 
has_lba db 0
 
disk_error_msg db 'Disk read error!',0
start_msg db 2,' KolibriOS 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
fat16_msg db 'FAT12/FAT16 - unsupported',13,10,0
fat32_msg db 'FAT32'
newline db 13,10,0
ntfs_msg db 'NTFS',13,10,0
error_msg db 'Error'
colon db ': ',0
mft_string db 'MFT',0
root_string db '\',0
noindex_string db '$INDEX_ROOT not found',0
invalid_read_request_string db 'cannot read attribute',0
nodata_string db '$DATA '
notfound_string db 'not found',0
directory_string db 'is a directory',0
notdir_string db 'not a directory',0
fragmented_string db 'too fragmented file',0
exmem_string db 'extended memory error',0
bad_cluster_string db 'bad cluster',0
data_error_msg db 'data error',0
 
; init procedure - ntldr jmps here
repeat 0D256h - $
db 1
end repeat
start:
; cs=es=0D00, ds=07C0, ss=0
; esi=edi=ebp=0, esp=7C00
xor ax, ax
mov ds, ax
mov es, ax
; our stack is 4Kb-512b-2b!!! (0xDFE)
mov ss, ax
mov esp, 0FFFEh
 
; we are booting from hard disk identified by [boot_drive]
mov dl, [boot_drive]
cld
sti
; calculate drive size
mov ah, 8 ; 8 = get drive parameters
int 13h
; now: CF is set on error;
; ch = low 8 bits of maximum cylinder number
; cl : low 6 bits makes maximum sector number, high 2 bits are high 2 bits of maximum cylinder number
; dh = maximum head number
jnc @f
mov cx, -1
mov dh, cl
@@:
movzx ax, dh
inc ax
; ax = number of heads
mov [heads], ax
mov dl, cl
and dx, 3Fh
; dx = number of sectors
; (note that sectors are counted from 1, and maximum sector number = number of sectors)
mov [sectors], dx
mul dx
xchg cl, ch
shr ch, 6
inc cx
; cx = number of cylinders
mov [cyls], cx
mul cx
mov word [drive_size], ax
mov word [drive_size+2], dx
; this drive supports LBA?
mov dl, [boot_drive]
mov ah, 41h
mov bx, 55AAh
int 13h
jc .no_lba
cmp bx, 0AA55h
jnz .no_lba
test cl, 1
jz .no_lba
inc [has_lba]
.no_lba:
; say hi to user
mov si, start_msg
call out_string
; now read first sector to determine file system type
; first sector of disk is MBR sector
xor eax, eax
new_partition_ex:
mov cx, 1
mov bx, 0F000h
call read
new_partition:
mov bx, [cur_partition_ofs]
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, [extended_part_start]
mov [extended_part_cur], eax
next_partition:
add [cur_partition_ofs], 10h
cmp [cur_partition_ofs], 0xF1FE
jb new_partition
mov eax, [extended_part_cur]
test eax, eax
jz partitions_done
cmp [extended_part_start], 0
jnz @f
mov [extended_part_start], eax
@@:
mov [extended_parent], eax
and [extended_part_cur], 0
mov [cur_partition_ofs], 0xF1BE
jmp new_partition_ex
partitions_done:
mov si, total_kaput
call out_string
jmp $
not_extended:
mov eax, [bx+8]
add eax, [extended_parent]
mov [partition_start], eax
push ax
mov si, part_msg
inc [si+part_char-part_msg]
call out_string
pop ax
mov cx, 1
mov bx, 500h
call read
movzx ax, byte [50Dh]
mov [sect_per_clust], ax
; determine file system
cmp dword [536h], 'FAT1'
jz fat1x
cmp dword [552h], 'FAT3'
jz fat32
cmp dword [503h], 'NTFS'
jz ntfs
mov si, errfs_msg
call out_string
jmp next_partition
fat1x:
mov si, fat16_msg
call out_string
jmp next_partition
fat32:
mov si, fat32_msg
call out_string
movzx eax, word [50Bh] ; bytes_per_sect
movzx ebx, byte [50Dh] ; sects_per_clust
mul ebx
mov [cluster_size], eax
movzx ebx, word [50Eh] ; reserved_sect
mov [fat_start], ebx
movzx eax, byte [510h] ; num_fats
mul dword [524h] ; sect_fat
add eax, ebx
; cluster 2 begins from sector eax
movzx ebx, byte [50Dh] ; sects_per_clust
sub eax, ebx
sub eax, ebx
mov [data_start], eax
; parse image name
mov eax, [52Ch] ; root_cluster
mov [cur_obj], root_string
.parsedir:
push ax
mov si, [imgnameofs]
push si
@@:
lodsb
cmp al, 0
jz @f
cmp al, '\'
jnz @b
dec si
mov [missing_slash], si
inc si
@@:
xchg ax, [esp+2]
mov byte [si-1], 0
mov [imgnameofs], si
call fat32_parse_dir
call restore_slash
pop cx
test cl, cl
jz .end
test byte [di+0Bh], 10h
mov si, notdir_string
jz find_error_si
jmp .parsedir
.end:
test byte [di+0Bh], 10h
mov si, directory_string
jnz find_error_si
; parse FAT chunk
; runlist at 2000:0000
mov di, 5
push 2000h
pop es
mov byte [es:di-5], 1 ; of course, non-resident
mov dword [es:di-4], 1
stosd
.parsefat:
push es
push ds
pop es
call next_cluster
pop es
jnc .done
mov ecx, [es:di-8]
add ecx, [es:di-4]
cmp eax, ecx
jz .contc
mov dword [es:di], 1
scasd
stosd
jmp .parsefat
.contc:
inc dword [es:di-8]
jmp .parsefat
.done:
xor eax, eax
stosd
jmp read_img_file
 
ntfs:
mov si, ntfs_msg
call out_string
movzx eax, word [50Bh] ; bpb_bytes_per_sect
push eax
movzx ebx, byte [50Dh] ; bpb_sects_per_clust
mul ebx
mov [cluster_size], eax
mov [data_start], 0
mov ecx, [540h] ; frs_size
cmp cl, 0
jg .1
neg cl
xor eax, eax
inc eax
shl eax, cl
jmp .2
.1:
mul ecx
.2:
mov [frs_size], eax
pop ebx
xor edx, edx
div ebx
mov [frs_sectors], ax
; read first MFT record - description of MFT itself
mov [cur_obj], mft_string
movzx eax, byte [50Dh] ; bpb_sects_per_clust
mul dword [530h] ; mft_cluster
mov cx, [frs_sectors]
mov bx, 4000h
mov di, bx
push bx
call relative_read
call restore_usa
; scan for unnamed $DATA attribute
pop di
mov ax, 80h ; $DATA
mov bx, 700h
call load_attr
mov si, nodata_string
jc find_error_si
mov [free], bx
; load kolibri.img
; parse image name
mov eax, 5 ; root cluster
mov [cur_obj], root_string
.parsedir:
push ax
mov si, [imgnameofs]
push si
@@:
lodsb
cmp al, 0
jz @f
cmp al, '\'
jnz @b
dec si
mov [missing_slash], si
inc si
@@:
xchg ax, [esp+2]
mov byte [si-1], 0
mov [imgnameofs], si
call ntfs_parse_dir
call restore_slash
pop cx
test cl, cl
jnz .parsedir
read_img_file:
xor si, si
push es
pop fs
; yes! Now read file to 0x100000
lods byte [fs:si]
cmp al, 0 ; assume nonresident attr
mov si, invalid_read_request_string
jz find_error_si
mov si, 1
xor edi, edi
; read buffer to 1000:0000 and move it to extended memory
push 1000h
pop es
xor bx, bx
.img_read_block:
lods dword [fs:si] ; eax=length
xchg eax, ecx
jecxz .img_read_done
lods dword [fs:si] ; eax=disk cluster
.img_read_cluster:
pushad
; read part of file
movzx ecx, byte [50Dh]
mul ecx
add eax, [data_start]
call relative_read
; move it to extended memory
mov ah, 87h
mov ecx, [cluster_size]
push ecx
shr cx, 1
mov si, movedesc
push es
push ds
pop es
int 15h
pop es
test ah, ah
mov si, exmem_string
jnz find_error_si
pop ecx
add [dest_addr], ecx
popad
inc eax
loop .img_read_cluster
jmp .img_read_block
.img_read_done:
; kolibri.img loaded; now load kernel.mnt
load_kernel:
push ds
pop es
mov [cur_obj], kernel_mnt_name
; read boot sector
xor eax, eax
mov bx, 500h
mov cx, 1
call read_img
; init vars
mov ax, [50Eh] ; reserved_sect
add ax, [51Ch] ; hidden
mov word [fat_start], ax
xchg ax, bx
movzx ax, byte [510h] ; num_fats
mul word [516h] ; fat_length
add ax, bx
; read root dir
mov bx, 700h
mov cx, [511h] ; dir_entries
add cx, 0Fh
shr cx, 4
call read_img
add ax, cx
mov [img_data_start], ax
shl cx, 9
mov di, bx
add bx, cx
mov byte [bx], 0
.scan_loop:
cmp byte [di], 0
mov si, notfound_string
jz find_error_si
mov si, kernel_mnt_name
call fat_compare_name
jz .found
and di, not 1Fh
add di, 20h
jmp .scan_loop
.found:
and di, not 1Fh
mov si, directory_string
test byte [di+0Bh], 10h
jnz find_error_si
; found, now load it to 1000h:0000h
mov ax, [di+1Ah]
; first cluster of kernel.mnt in ax
; translate it to sector on disk in kolibri.img
push ax
dec ax
dec ax
movzx cx, byte [50Dh]
mul cx
add ax, [img_data_start]
; now ax is sector in kolibri.img
mov [kernel_mnt_in_img], ax
div [sect_per_clust]
; now ax is cluster in kolibri.img and
; dx is offset from the beginning of cluster
movzx eax, ax
push 2000h
pop ds
mov si, 1
.scani:
sub eax, [si]
jb .scanidone
; sanity check
cmp dword [si], 0
push invalid_read_request_string
jz find_error_sp
pop cx
; next chunk
add si, 8
jmp .scani
.scanidone:
add eax, [si] ; undo last subtract
add eax, [si+4] ; get cluster
push 0
pop ds
movzx ecx, [sect_per_clust]
push dx
mul ecx ; get sector
pop dx
movzx edx, dx
add eax, edx
add eax, [data_start]
mov [kernel_mnt_1st], eax
pop ax
push 1000h
pop es
.read_loop:
push ax
xor bx, bx
call img_read_cluster
shl cx, 9-4
mov ax, es
add ax, cx
mov es, ax
pop ax
call img_next_cluster
jc .read_loop
mov ax, 'KL'
mov si, loader_block
jmp 1000h:0000h
 
img_next_cluster:
mov bx, 700h
push ax
shr ax, 1
add ax, [esp]
mov dx, ax
shr ax, 9
add ax, word [fat_start]
mov cx, 2
push es
push ds
pop es
call read_img
pop es
and dx, 1FFh
add bx, dx
mov ax, [bx]
pop cx
test cx, 1
jz .1
shr ax, 4
.1:
and ax, 0FFFh
mov si, bad_cluster_string
cmp ax, 0FF7h
jz find_error_si
ret
img_read_cluster:
dec ax
dec ax
movzx cx, byte [50Dh] ; sects_per_clust
mul cx
add ax, [img_data_start]
movzx eax, ax
; call read_img
; ret
read_img:
; in: ax = sector, es:bx->buffer, cx=length in sectors
pushad
movzx ebx, bx
mov si, movedesc
shl eax, 9
add eax, 93100000h
mov dword [si+sou_addr-movedesc], eax
mov eax, 9300000h
mov ax, es
shl eax, 4
add eax, ebx
mov [si+dest_addr-movedesc], eax
mov ah, 87h
shl cx, 8 ; mul 200h/2
push es
push 0
pop es
int 15h
pop es
cmp ah, 0
mov si, exmem_string
jnz find_error_si
popad
ret
 
movedesc:
times 16 db 0
; source
dw 0xFFFF ; segment length
sou_addr dw 0000h ; linear address
db 1 ; linear address
db 93h ; access rights
dw 0
; destination
dw 0xFFFF ; segment length
dest_addr dd 93100000h ; high byte contains access rights
; three low bytes contains linear address (updated when reading)
dw 0
times 32 db 0
 
find_error_si:
push si
find_error_sp:
mov si, error_msg
call out_string
mov si, [cur_obj]
call out_string
mov si, colon
call out_string
pop si
call out_string
mov si, newline
call out_string
or [fat_cur_sector], -1
mov [imgnameofs], kolibri_img_name
call restore_slash
mov sp, 0xFFFE
jmp next_partition
 
file_not_found:
mov si, [esp+2]
mov [cur_obj], si
push notfound_string
jmp find_error_sp
 
restore_slash:
mov si, [missing_slash]
test si, si
jz @f
and [missing_slash], 0
mov byte [si], '\'
@@: ret
 
include 'fat32.inc'
include 'ntfs.inc'
 
write1st:
; callback from kernel.mnt
; write first sector of kernel.mnt from 1000:0000 back to disk
push cs
pop ds
push cs
pop es
; sanity check
mov bx, 500h
mov si, bx
mov cx, 1
push cx
mov eax, [kernel_mnt_1st]
push eax
call relative_read
push 1000h
pop es
xor di, di
mov cx, 8
repz cmpsw
mov si, data_error_msg
jnz find_error_si
; ok, now write back to disk
or byte [read.patch1+2], 1
or byte [read.patch2+2], 1
xor bx, bx
pop eax
pop cx
call relative_read
and byte [read.patch1+1], not 1
and byte [read.patch2+2], not 2
; and to image in memory (probably this may be done by kernel.mnt itself?)
mov dword [sou_addr], 93010000h
movzx eax, [kernel_mnt_in_img]
shl eax, 9
add eax, 93100000h
mov dword [dest_addr], eax
mov si, movedesc
push ds
pop es
mov ah, 87h
mov cx, 100h
int 15h
cmp ah, 0
mov si, exmem_string
jnz find_error_si
retf
 
loader_block:
db 1 ; version
dw 1 ; flags - image is loaded
dw write1st ; offset
dw 0 ; segment
 
fat_cur_sector dd -1
imgnameofs dw kolibri_img_name
 
; -----------------------------------------------
; ------------------ Settings -------------------
; -----------------------------------------------
 
; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
kernel_mnt_name db 'kernel.mnt',0
kolibri_img_name db 'kolibri.img',0
 
; change next variable if you want to boot from other physical drive
boot_drive db 80h
 
total_kaput db 13,10,'Fatal: image is not found.',13,10,0
missing_slash dw 0
align 2
 
cur_partition_ofs dw 0xF1BE
extended_part_start dd 0
extended_part_cur dd 0
extended_parent dd 0
 
; uninitialized data follows
drive_size dd ? ; in sectors
heads dw ?
sectors dw ?
cyls dw ?
partition_start dd ?
free dw ?
cur_obj dw ?
data_start dd ?
img_data_start dw ?
sect_per_clust dw ?
kernel_mnt_in_img dw ?
kernel_mnt_1st dd ?
; NTFS data
cluster_size dd ? ; in bytes
frs_size dd ? ; in bytes
frs_sectors dw ? ; in sectors
mft_data_attr dw ?
index_root dw ?
index_alloc dw ?
ofs dw ?
dir dw ?
; FAT32 data
fat_start dd ?
cur_cluster dd ?
; file must be 16 sectors long
 
repeat 0F000h - $
db 2
end repeat
/programs/hd_load/mtldr/ntfs.inc
0,0 → 1,531
restore_usa:
; Update Sequence Array restore
mov bx, [di+4]
mov cx, [di+6]
inc bx
add bx, di
inc bx
add di, 1feh
dec cx
@@:
mov ax, [bx]
stosw
inc bx
inc bx
add di, 1feh
loop @b
ret
 
find_attr:
; in: di->file record, ax=attribute
; out: di->attribute or di=0 if not found
add di, [di+14h]
.1:
; attributes codes are formally dwords, but all they 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: si->attribute, es:di->buffer
; out: di->buffer end
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
jmp .loop
.done:
xor eax, eax
stosd
ret
 
load_attr:
; in: ax=attribute, es:bx->buffer, di->base record
; out: bx->buffer end; CF set if not found
push di
push ax
mov byte [es:bx], 1
inc bx
push bx
mov [ofs], bx
; scan for attrubute
add di, [di+14h]
@@:
call find_attr.1
test di, di
jz .notfound1
cmp byte [di+8], 0
jnz .nonresident
jmp .resident
.aux_resident:
push di
popad
; resident attribute
.resident:
mov si, di
pop di
dec di
mov al, 0
stosb
mov ax, [si+10h]
stosw
xchg ax, cx
add si, [si+14h]
rep movsb
mov bx, di
pop ax
pop di
ret
.nonresident:
; nonresident attribute
cmp dword [di+10h], 0
jnz @b
; read start of data
mov si, di
pop di
call process_mcb_nonres
sub di, 4
push di
.notfound1:
; $ATTRIBUTE_LIST is always in base file record
cmp word [esp+2], 20h
jz .nofragmented
; scan for $ATTRIBUTE_LIST = 20h
mov di, [esp+4]
mov ax, 20h
call find_attr
test di, di
jz .nofragmented
; load $ATTRIBUTE_LIST itself
push es
mov bx, 0C000h
mov di, [esp+6]
push bx
push [ofs]
push ds
pop es
call load_attr
pop [ofs]
pop si
mov bx, 8000h
push bx
push si
call read_attr_full
pop si
pop bx
add dx, bx
mov ax, [esp+4]
pop es
.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
push ax
mov ax, [esp+2]
cmp ax, [ofs]
pop ax
jnz .continue1
@@:
pushad
mov eax, [bx+10h]
mov bx, dx
push [ofs]
push es
push ds
pop es
call read_file_record
pop es
pop [ofs]
popad
pushad
pop di
mov di, dx
add di, [di+14h]
.2:
call find_attr.1
cmp byte [di+8], 0
jz .aux_resident
mov eax, [bx+8]
cmp eax, [di+10h]
jnz .2
mov si, di
mov di, [esp+1Eh]
call process_mcb_nonres
sub di, 4
mov [esp+1Eh], di
push di
popad
.continue1:
add bx, [bx+4]
cmp bx, dx
jb .1
.nofragmented:
pop bx
pop ax
pop di
cmp bx, [ofs]
jnz @f
dec bx
stc
ret
@@:
add bx, 4
ret
 
read_attr_full:
; in: si->decoded attribute data, bx->buffer
; out: edx=length in bytes
lodsb
cmp al, 0
jnz .nonresident
; resident
lodsw
movzx edx, ax
xchg ax, cx
mov di, bx
rep movsb
ret
.nonresident:
; nonresident :-)
xor edx, edx
.loop:
lodsd
xchg ecx, eax
jecxz .loopend
lodsd
xchg edi, eax
; read ecx clusters from cluster edi to es:bx
.intloop:
push ecx
; read 1 cluster from physical cluster edi to es:bx
mov ecx, [cluster_size]
mov eax, edi
mul ecx
push bx
call relative_read
pop bx
pop ecx
inc edi
mov eax, [cluster_size]
add edx, eax
shr eax, 4
mov bp, es
add bp, ax
mov es, bp
loop .intloop
jmp .loop
.loopend:
mov es, cx
ret
 
read_file_record:
; in: eax=index of record, bx=buffer
mov si, 700h
mov ecx, [frs_size]
mul ecx
push bx
push [cur_obj]
mov [cur_obj], mft_string
call read_attr
pop [cur_obj]
pop di
call restore_usa
ret
read_attr:
; in: edx:eax=offset in bytes, ecx=size in bytes, bx=buffer, si=attribute
push invalid_read_request_string
cmp byte [si], 0
jnz .nonresident
test edx, edx
jnz find_error_sp
cmp eax, 10000h
jae find_error_sp
cmp ecx, 10000h
jae find_error_sp
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:
mov edi, [cluster_size]
div edi
mov [ofs], dx
add cx, dx
push eax
xchg eax, ecx
xor edx, edx
dec eax
div edi
inc eax
xchg eax, ecx
pop eax
add si, 1
xor edx, edx
push bx
; eax=offset in clusters, ecx=size in clusters
.scan:
mov ebx, [si]
test ebx, ebx
jz .notfound
add edx, ebx
add si, 8
cmp eax, edx
jae .scan
mov edi, [si-4]
; now edx=end of block, ebx=length of block, edi=start of block on disk
; eax=required offset, ecx=required length
push edx
push edi
sub edx, eax
add edi, ebx
sub edi, edx
cmp edx, ecx
jb @f
mov edx, ecx
@@:
; read (edx) clusters from (edi=disk offset in clusters) to ([esp+8])
cmp [ofs], 0
jnz .ofs_read
.cont:
pushad
movzx ebx, byte [50Dh]
; xchg eax, edx
; mul ebx
xchg ax, dx
mul bx
xchg cx, ax
xchg eax, edi
mul ebx
mov bx, [esp+8+20h]
call relative_read
mov [esp+8+20h], bx
popad
.cont2:
add eax, edx
sub ecx, edx
.cont3:
pop edi
pop edx
jnz .scan
pop bx
pop ax
ret
.ofs_read:
push ecx
movzx ecx, byte [50Dh] ; bpb_sects_per_clust
mov eax, edi
push edx
mul ecx
push 1000h
pop es
xor bx, bx
call relative_read
mov cx, bx
push si
push di
mov si, [ofs]
mov di, [esp+8+12]
sub cx, si
push ds
push es
pop ds
pop es
rep movsb
mov [esp+8+12], di
push es
pop ds
pop di
pop si
pop edx
pop ecx
inc edi
mov [ofs], 0
inc eax
dec ecx
jz .cont3
dec edx
jnz .cont
jmp .cont2
.notfound:
mov si, invalid_read_request_string
jmp find_error_si
 
ntfs_parse_dir:
; in: eax=directory iRecord, [word sp+2]=filename
; out: si=$DATA attribute of file
mov bx, [free]
mov [dir], bx
push bx
call read_file_record
mov ax, word [frs_size]
add [free], ax
pop di
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
mov ax, 90h ; $INDEX_ROOT
push di
mov bx, [free]
mov [index_root], bx
call load_attr
mov si, noindex_string
jc find_error_si
mov [free], bx
pop di
mov ax, 0A0h ; $INDEX_ALLOCATION
mov bx, [free]
mov [index_alloc], bx
call load_attr
jnc @f
mov [index_alloc], 0
@@:
mov [free], bx
; search for entry
mov si, [index_root]
mov bx, [free]
call read_attr_full
mov ebp, [bx+8] ; subnode_size
add bx, 10h
.scan_record:
add bx, [bx]
.scan:
test byte [bx+0Ch], 2
jnz .not_found
mov si, [esp+2]
movzx cx, byte [bx+50h] ; namelen
lea di, [bx+52h] ; name
xor ax, ax
@@:
lodsb
cmp al, 'a'
jb .notletter
cmp al, 'z'
ja .notletter
or byte [di], 20h
.notletter:
scasw
loopz @b
jb .not_found
ja @f
cmp byte [esi], 0
jz .file_found
@@:
add bx, [bx+8]
jmp .scan
.not_found:
test byte [bx+0Ch], 1
jz file_not_found
cmp [index_alloc], 0
jz file_not_found
add bx, [bx+8]
mov eax, [bx-8]
mul [cluster_size]
mov si, [index_alloc]
mov ecx, ebp
mov bx, [free]
call read_attr
mov di, [free]
call restore_usa
mov bx, [free]
add bx, 18h
jmp .scan_record
.file_found:
mov si, [esp+2]
mov [cur_obj], si
cmp byte [esp+4], 0
jz .need_file
mov si, notdir_string
test byte [bx+48h+3], 10h
jz find_error_si
mov eax, [bx]
mov bx, [dir]
mov [free], bx
ret 2
.need_file:
mov si, directory_string
test byte [bx+48h+3], 10h ; directory?
jnz find_error_si
; read entry
mov eax, [bx]
mov bx, [dir]
mov [free], bx
mov bx, 4000h
push bx
call read_file_record
pop di
mov ax, 80h
push 2000h
pop es
xor bx, bx
call load_attr
mov si, nodata_string
jz find_error_si
mov [free], bx
ret 2
/programs/hd_load/mtldr/vista_install.bat
0,0 → 1,4
bcdedit /create {AA48ABEF-FF35-4f09-874F-4CFF92467DC4} /d "KolibriOS" /application BOOTSECTOR
bcdedit /set {AA48ABEF-FF35-4f09-874F-4CFF92467DC4} DEVICE PARTITION=C:
bcdedit /set {AA48ABEF-FF35-4f09-874F-4CFF92467DC4} PATH \mtldr
bcdedit /displayorder {AA48ABEF-FF35-4f09-874F-4CFF92467DC4} /addlast
/programs/hd_load/mtldr/vista_remove.bat
0,0 → 1,0
bcdedit /delete {AA48ABEF-FF35-4f09-874F-4CFF92467DC4}