Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 2782 → Rev 2783

/programs/hd_load/usb_boot/BOOT_F32.ASM
0,0 → 1,183
; KolibriOS bootloader
; bootsector for loading from FAT32 flash (or hard) drive
; intended for use with mtldr_f file in root folder
; this code has been written by diamond in 2005,2006,2007 specially for KolibriOS
 
; this code is loaded by BIOS to 0000:7C00
org 0x7C00
jmp @f
nop
; times 57h db 0
file 'bt2.dat':3,57h
@@:
xor eax, eax
mov ds, ax
mov ss, ax
mov sp, 7C00h
mov [boot_drive], dl
cld
sti
push 800h
pop es
movzx ebx, word [7C0Eh] ; reserved_sect
mov [fat_start], ebx
mov al, byte [7C10h] ; num_fats
mul dword [7C24h] ; sect_fat
add eax, ebx
; cluster 2 begins from sector eax
movzx ebx, byte [7C0Dh] ; sects_per_clust
add bx, bx
sub eax, ebx
mov [data_start], eax
mov eax, [7C2Ch] ; root_cluster
and eax, 0FFFFFFFh
fat32_parse_dir:
xor bx, bx
mov di, bx
push eax
call read_cluster
movzx cx, byte [7C0Dh] ; sects_per_clust
shl cx, 4 ; *0x200/0x20
scan_cluster:
cmp byte [es:di], 0
jz file_not_found
push cx di
mov cx, 11
mov si, mtldr_f
repz cmpsb
pop di cx
jz file_found
add di, 20h
loop scan_cluster
pop eax
call next_cluster
jnc file_not_found
jc fat32_parse_dir
file_found:
pop eax
mov ax, [es:di+14h]
and ax, 0FFFh
shl eax, 10h
mov ax, [es:di+1Ah]
; eax contains first cluster
@@:
xor bx, bx
push eax
call read_cluster
mov ax, es
movzx cx, byte [7C0Dh]
shl cx, 5
add ax, cx
mov es, ax
pop eax
call next_cluster
jc @b
jmp 0:8000h
 
file_not_found:
mov si, file_not_found_msg
sayerr:
call out_string
jmp $
 
read_cluster:
; in: eax = cluster, bx->buffer
movzx ecx, byte [7C0Dh]
mul ecx
add eax, [data_start]
 
; read procedure
; in: eax = absolute sector
; cx = number of sectors
; es:bx -> buffer
read:
add eax, [7C1Ch] ; hidden sectors
push es
read_loop:
pushad
; allocate disk address packet on the stack
; qword +8: absolute block number
push 0
push 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, limited to 7Fh
sub cx, 7Fh
sbb ax, ax
and ax, cx
add ax, 7Fh
push ax
shl ax, 5
mov cx, es
add cx, ax
mov es, cx
; word +0: size of packet = 10h
push 10h
; now pair ss:sp contain address of disk address packet
mov ax, 4200h
mov dl, [boot_drive]
mov si, sp
int 13h
mov si, disk_read_err
jc sayerr
popaw
popad
add eax, 7Fh
sub cx, 7Fh
ja read_loop
pop es
ret
 
next_cluster:
push es
push ds
pop es
mov bx, 7E00h
; 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 read
@@:
pop eax
and eax, 7Fh
mov eax, [7E00h+eax*4]
and eax, 0FFFFFFFh
cmp eax, 0FFFFFF7h
mov si, bad_cluster
jz sayerr
pop es
ret
 
out_string:
lodsb
test al, al
jz .xxx
mov ah, 0Eh
mov bx, 7
int 10h
jmp out_string
.xxx: ret
 
file_not_found_msg db 'Cannot find file '
mtldr_f db 'MTLD_F32 '
db 13,10,0
disk_read_err db 'Disk read error',13,10,0
bad_cluster db 'Bad cluster',13,10,0
fat_cur_sector dd -1
 
times (7DFEh - $) db 0
db 55h, 0AAh
 
virtual at 7A00h
fat_start dd ?
data_start dd ?
boot_drive db ?
end virtual
/programs/hd_load/usb_boot/MBR
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/programs/hd_load/usb_boot/fat32.inc
0,0 → 1,83
fat32_parse_dir:
; in: eax=directory cluster
; out: eax=entry cluster
xor bx, bx
mov di, bx
push eax
call read_cluster
movzx cx, byte [7C0Dh]
shl cx, 4
.scan_cluster:
pop eax
cmp byte [es: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, [es:di+14h]
and ax, 0xFFF
shl eax, 10h
mov ax, [es: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 [es: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
/programs/hd_load/usb_boot/inst.asm
0,0 → 1,492
format PE GUI 4.0
section '.text' code readable executable
entry start
start:
xor ebx, ebx
mov esi, a2_src
mov edi, a2
movsd
movsd
movsd
movsd
movsd
push 1
call [SetErrorMode]
push ebx ; lpParam
push 400000h ; hInstance
push ebx ; hMenu
push ebx ; hWndParent
push 100 ; nHeight
push 200 ; nWidth
mov eax, 80000000h
push eax ; y
push eax ; x
push 10EF0140h ; dwStyle
push WndName
push ClassName
push 388h ; dwExStyle
call [CreateWindowExA]
xchg edi, eax
push 0Ah ; OEM_FIXED_FONT
call [GetStockObject]
push ebx
push eax
push 30h ; WM_SETFONT
call ListCommand
call CollectDrivesInfo
push MyWndProc
push -4 ; GWL_WNDPROC
push edi
call [SetWindowLongA]
mov [OldWndProc], eax
sub esp, 20h
mov esi, esp
@@:
push ebx
push ebx
push ebx
push esi
call [GetMessageA]
test eax, eax
jz @f
push esi
call [TranslateMessage]
push esi
call [DispatchMessageA]
jmp @b
@@:
add esp, 20h
ret
 
ListCommand:
pop eax
push edi
push eax
jmp [SendMessageA]
 
MyWndProc:
push edi ebx
xor ebx, ebx
mov edi, [esp+12]
cmp dword [esp+16], 2 ; WM_DESTROY
jnz @f
push ebx
call [PostQuitMessage]
@@:
cmp dword [esp+16], 219h ; WM_DEVICECHANGE
jnz w
cmp dword [esp+20], 8000h ; DBT_DEVICEARRIVAL
jz @f
cmp dword [esp+20], 8004h ; DBT_DEVICEREMOVECOMPLETE
jnz w
@@:
call UpdateDrivesInfo
w:
cmp dword [esp+16], 203h ; WM_LBUTTONDBLCLK
jnz @f
push ebx
push ebx
push 188h ; LB_GETCURSEL
call ListCommand
cmp eax, -1
jz @f
push n
push eax
push 189h ; LB_GETTEXT
call ListCommand
mov eax, n
mov byte [eax+2], bl
mov edx, [eax]
mov [mtldr_out], dl
mov dword [eax], '\\.\'
mov dword [eax+4], edx
call install
@@:
pop ebx edi
pop eax
push [OldWndProc]
push eax
jmp [CallWindowProcA]
 
UpdateDrivesInfo:
push ebx
push ebx
push 184h ; LB_RESETCONTENT
call ListCommand
 
CollectDrivesInfo:
push esi
call [GetLogicalDrives]
mov esi, eax
mov edx, a
mov byte [edx], 'A'
l:
shr esi, 1
jnc d
mov [edx+2], bl
push edx
call [GetDriveTypeA]
; Uncomment following lines to allow hard drives
; cmp eax, 3 ; DRIVE_FIXED
; jz @f
cmp eax, 2 ; DRIVE_REMOVABLE
jnz d
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push ebx ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push ebx ; dwDesiredAccess
push a2
call [CreateFileA]
cmp eax, -1
jz d
push eax
push ebx
mov ecx, esp
push ebx ; lpOverlapped
push ecx ; lpBytesReturned
push 1024 ; nOutBufferSize
push n ; lpOutBuffer
push ebx
push ebx
push 70C00h ; IOCTL_DISK_GET_MEDIA_TYPES
push eax
call [DeviceIoControl]
pop ecx
pop eax
push ecx
push eax
call [CloseHandle]
pop ecx
jecxz @f ; not supported => OK
cmp byte [n+8], 11
jnz d
@@:
mov eax, a
mov ecx, n
mov byte [eax+2], '\'
push ecx
push ebx ; nFileSystemNameSize
push ebx ; lpFileSystemNameBuffer
push ebx ; lpFileSystemFlags
push ebx ; lpMaximumComponentLength
push ebx ; lpVolumeSerialNumber
push 1024 ; nVolumeNameSize
mov edx, [eax]
mov [ecx], edx
mov word [ecx+3], ' ['
add ecx, 5
mov byte [ecx], bl
push ecx ; lpVolumeNameBuffer
push eax ; lpRootPathName
call [GetVolumeInformationA]
pop eax
push eax
cmp byte [eax+5], bl
jz nol
@@:
inc eax
cmp byte [eax-1], bl
jnz @b
mov word [eax-1], ']'
; jmp @f
nol:
mov byte [eax+3], bl
@@:
push ebx
push 180h ; LB_ADDSTRING
call ListCommand
d:
mov edx, a
inc byte [edx]
test esi, esi
jnz l
pop esi
ret
 
install:
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push ebx ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push 0C0000000h ; dwDesiredAccess = GENERIC_READ|GENERIC_WRITE
push eax
call [CreateFileA]
cmp eax, -1
jz deverre
push esi ebp
mov ebp, bootsect_dev
xchg esi, eax
push eax
mov eax, esp
push ebx
push eax
push 512
push ebp
push esi
call [ReadFile]
test eax, eax
jnz @f
deverrl:
push esi
call [CloseHandle]
pop eax
pop ebp esi
deverre:
push 10h
push ebx
push deverr
push edi
call [MessageBoxA]
ret
@@:
; make sure that this is FAT32 volume
cmp word [ebp+0Bh], 200h ; bytes per sector
jnz bootinv
cmp word [ebp+0Eh], bx ; reserved sectors
jz bootinv
cmp byte [ebp+10h], bl ; number of FATs
jz bootinv
cmp word [ebp+11h], bx ; root dir entries
jnz bootinv ; must be 0 for FAT32
cmp word [ebp+16h], bx ; length of one copy of FAT1x
jnz bootinv
cmp dword [ebp+20h], ebx ; length of one copy of FAT32
jz bootinv
cmp byte [ebp+42h], ')' ; magic value
jz @f
bootinv:
push 10h
push ebx
push nofat32
jmp re
@@:
; ok, this is really correct FAT32 volume, so start install
; copy file mtldr_f
push 80h
push mtldr_out
call [SetFileAttributesA]
push ebx ; bFailIfExists
push mtldr_out ; lpNewFileName
push mtldr_in ; lpExistingFileName
call [CopyFileA]
test eax, eax
jnz @f
push 10h
push ebx
push mterr
re:
push edi
call [MessageBoxA]
jmp r
@@:
push 7
push mtldr_out
call [SetFileAttributesA]
; load bootsector
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push ebx ; lpSecurityAttributes
push 1 ; dwShareMode = FILE_SHARE_READ
push 80000000h ; dwDesiredAccess = GENERIC_READ
push btname
call [CreateFileA]
cmp eax, -1
jnz @f
bterrc:
push 40h
push ebx
push bterr
jmp re
@@:
mov ecx, esp
push eax
push ebx
push ecx
push 512
push bootsect_new
push eax
call [ReadFile]
pop ecx
push eax
push ecx
call [CloseHandle]
pop eax
test eax, eax
jz bterrc
cmp dword [esp], 512
jnz bterrc
; patch bootsector with real values
push esi edi
mov esi, bootsect_new
mov edi, bootsect_dev
movsb
movsb
movsb
add esi, 57h
add edi, 57h
mov ecx, 200h-5Ah
rep movsb
pop edi esi
; write bootsector
push ebx
push ebx
push ebx
push esi
call [SetFilePointer]
test eax, eax
jnz deverrl
mov eax, esp
push ebx
push eax
push 512
push ebp
push esi
call [WriteFile]
test eax, eax
jz deverrl
cmp dword [esp], 512
jnz deverrl
; Patch backup copy of boot sector, ignore errors
movzx eax, word [ebp+50]
test eax, eax
jz done_succ
; sanity check: it must be in the reserved area, not in data
cmp ax, word [ebp+14]
jae done_succ
shl eax, 9
push ebx
push ebx
push eax
push esi
call [SetFilePointer]
cmp eax, -1
jz done_succ
mov eax, esp
push ebx
push eax
push 512
push ebp
push esi
call [WriteFile]
; done!
done_succ:
push 40h
push ok
push succ
push edi
call [MessageBoxA]
push ebx
call [PostQuitMessage]
r:
pop eax
push esi
call [CloseHandle]
pop ebp esi
ret
 
section '.rdata' data readable
 
data resource from 'rsrc.res'
end data
 
ClassName db 'LISTBOX',0
WndName db 'Select drive',0
deverr db 'Cannot open physical device or device error (no administrator rights?)',0
nofat32 db 'Not FAT32 volume. Sorry, only FAT32 is supported at moment.',0
ok db 'Success',0
succ db 'Kolibri flash loader was successfully installed!',10
db 'Now you can copy the image kolibri.img and boot!',0
mterr db 'Cannot copy MTLD_F32',0
bterr db 'Cannot load '
btname db 'BOOT_F32.BIN',0
 
data import
macro thunk a
{a#_thunk:dw 0
db `a,0}
dd 0,0,0, rva kernel32_name, rva kernel32_thunks
dd 0,0,0, rva user32_name, rva user32_thunks
dd 0,0,0, rva gdi32_name, rva gdi32_thunks
dd 0,0,0,0,0
kernel32_name db 'kernel32.dll',0
user32_name db 'user32.dll',0
gdi32_name db 'gdi32.dll',0
kernel32_thunks:
GetLogicalDrives dd rva GetLogicalDrives_thunk
GetDriveTypeA dd rva GetDriveTypeA_thunk
GetVolumeInformationA dd rva GetVolumeInformationA_thunk
CreateFileA dd rva CreateFileA_thunk
ReadFile dd rva ReadFile_thunk
WriteFile dd rva WriteFile_thunk
SetFilePointer dd rva SetFilePointer_thunk
CloseHandle dd rva CloseHandle_thunk
SetErrorMode dd rva SetErrorMode_thunk
CopyFileA dd rva CopyFileA_thunk
SetFileAttributesA dd rva SetFileAttributesA_thunk
DeviceIoControl dd rva DeviceIoControl_thunk
dw 0
thunk GetLogicalDrives
thunk GetDriveTypeA
thunk GetVolumeInformationA
thunk CreateFileA
thunk ReadFile
thunk WriteFile
thunk SetFilePointer
thunk CloseHandle
thunk SetErrorMode
thunk CopyFileA
thunk SetFileAttributesA
thunk DeviceIoControl
user32_thunks:
CreateWindowExA dd rva CreateWindowExA_thunk
GetMessageA dd rva GetMessageA_thunk
TranslateMessage dd rva TranslateMessage_thunk
DispatchMessageA dd rva DispatchMessageA_thunk
PostQuitMessage dd rva PostQuitMessage_thunk
CallWindowProcA dd rva CallWindowProcA_thunk
SetWindowLongA dd rva SetWindowLongA_thunk
SendMessageA dd rva SendMessageA_thunk
MessageBoxA dd rva MessageBoxA_thunk
dw 0
thunk CreateWindowExA
thunk GetMessageA
thunk TranslateMessage
thunk DispatchMessageA
thunk PostQuitMessage
thunk CallWindowProcA
thunk SetWindowLongA
thunk SendMessageA
thunk MessageBoxA
gdi32_thunks:
GetStockObject dd rva GetStockObject_thunk
dw 0
thunk GetStockObject
end data
 
a2_src:
db '\\.\'
db '?:',0,0
db '?:\'
db 'MTLD_F32',0
 
section '.data' data readable writable
 
;a2 db '\\.\'
;a db '?:',0,0
;mtldr_out db '?:\'
;mtldr_in db 'MTLD_F32',0
a2 rb 4
a rb 4
mtldr_out rb 3
mtldr_in rb 9
 
align 4
OldWndProc dd ?
devpath rb 1024
n rb 1032
bootsect_dev rb 512
bootsect_new rb 512
/programs/hd_load/usb_boot/mtldr.asm
0,0 → 1,453
; KolibriOS bootloader
; this code has been written by diamond in 2005,2006,2007 specially for KolibriOS
 
; this code is loaded by our bootsector to 0000:8000
format binary
use16
 
out_string = 0x7DA2
read_cluster = 0x7D0A
relative_read = 0x7D18
next_cluster = 0x7D5C
 
org 0x8000
start:
; cs=ds=0, es undefined, ss=0, sp=7C00
movzx esp, sp
push 1000h
pop es
; say hi to user
mov si, start_msg
call out_string
; parse image name
mov eax, [7C2Ch] ; root_cluster
and eax, 0xFFFFFFF
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 [es:di+0Bh], 10h
mov si, notdir_string
jz find_error_si
jmp .parsedir
.end:
test byte [es:di+0Bh], 10h
mov si, directory_string
jnz find_error_si
; parse FAT chunk
; runlist at 5000:0000
mov di, 4
push 5000h
pop es
mov dword [es:di-4], 1
stosd
.parsefat:
call next_cluster
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
read_img_file:
xor si, si
push es
pop fs
; yes! Now read file to 0x100000
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 esi, byte [7C0Dh]
mul esi
add eax, [7A04h]
push ax
mov ax, 0x200
div si
cmp cx, ax
jb @f
mov cx, ax
@@:
pop ax
add [esp+1Ch], ecx
sub [esp+18h], cx
imul cx, si
push cx
call relative_read
pop cx
; move it to extended memory
mov byte [sou_addr+2], 1
.move_loop:
push cx
cmp cx, 80h
jbe @f
mov cx, 80h
@@:
mov ah, 87h
xchg cl, ch
mov si, movedesc
push cx es
push ds
pop es
int 15h
pop es cx
test ah, ah
mov si, exmem_string
jnz find_error_si
add [dest_addr], ecx
add [dest_addr], ecx
inc byte [sou_addr+2]
mov al, ch
mov ah, cl
pop cx
sub cx, ax
jnz .move_loop
popad
test cx, cx
jnz .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
movzx cx, byte [7C0Dh]
div cx
; now ax is cluster in kolibri.img and
; dx is offset from the beginning of cluster
movzx eax, ax
push 5000h
pop ds
xor si, si
mov si, 1
.scani:
sub eax, [si]
jb .scanidone
; sanity check
cmp dword [si], 0
push data_error_msg
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, byte [7C0Dh]
push dx
mul ecx ; get sector
pop dx
movzx edx, dx
add eax, edx
add eax, [7A04h]
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
jmp $
 
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'
 
if 0
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
else
write1st = 0
end if
 
loader_block:
db 1 ; version
dw 1 ; flags - image is loaded
dw write1st ; offset
dw 0 ; segment
 
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
 
missing_slash dw 0
 
start_msg db 2,' KolibriOS bootloader, FAT32 flash version'
newline db 13,10,0
error_msg db 'Error'
colon db ': ',0
root_string db '\',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
exmem_string db 'extended memory error',0
bad_cluster_string db 'bad cluster',0
data_error_msg db 'data error',0
 
align 2
 
; uninitialized data follows
cur_obj dw ?
img_data_start dw ?
kernel_mnt_in_img dw ?
fat_start dw ?
kernel_mnt_1st dd ?
/programs/hd_load/usb_boot/readme.txt
0,0 → 1,48
 êîìïëåêò ïîñòàâêè âõîäÿò:
BOOT_F32.BIN - áóòñåêòîð äëÿ FAT32;
MTLD_F32 - âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà;
inst.exe - óñòàíîâùèê ïîä ëèíåéêó WinNT+;
setmbr.exe - óñòàíàâëèâàåò ñòàíäàðòíûé MBR (÷èòàéòå íèæå);
readme.txt - ýòîò ôàéë.
 
Äëÿ óñòàíîâêè íåîáõîäèìà ôëåøêà ñ ôàéëîâîé ñèñòåìîé FAT32, ñâîáîäíîãî ìåñòà
íà êîòîðîé äîñòàòî÷íî äëÿ ðàçìåùåíèÿ ôàéëà kolibri.img è ïëþñ åù¸ ïàðà Êá
íà çàãðóç÷èê.
 
Óñòàíîâêà äëÿ ïîëüçîâàòåëåé WinNT+:
Çàïóñêàåòå inst.exe, ïîÿâëÿåòñÿ ñïèñîê ïîäêëþ÷¸ííûõ ôëåøåê, âûáèðàåòå
òó, íà êîòîðóþ õîòèòå óñòàíîâèòü, è äâàæäû ù¸ëêàåòå ïî íåé. Îá óñïåõå ïðîãðàììà
ñîîáùèò. Î íåóñïåõå (íå óäàëîñü ïðî÷èòàòü/çàïèñàòü íà äèñê èëè äèñê íå
ÿâëÿåòñÿ FAT32-òîìîì) - òîæå.
Êîïèðóåòå íà ôëåøêó ôàéë kolibri.img ñ íóæíîé âàì âåðñèåé
äèñòðèáóòèâà. (Ýòè äâà äåéñòâèÿ ìîæíî îñóùåñòâëÿòü â ëþáîì ïîðÿäêå.)
Òåïåðü ñ ôëåøêè ìîæíî ãðóçèòüñÿ.
 
ß ñòîëêíóëñÿ ñ ñèòóàöèåé, êîãäà (íåäàâíî âûïóùåííàÿ) ôëåøêà îòêàçûâàåòñÿ
çàãðóæàòüñÿ, âûäàâàÿ ñîîáùåíèå "Pen drive Without Operating System.Remove
Pen Drive And Reboot." Åñëè âìåñòî çàãðóçêè ïîÿâëÿåòñÿ
òàêîå æå èëè ïîäîáíîå ñîîáùåíèå, ñêîðåå âñåãî, ïîìîæåò setmbr.exe.
Åãî íóæíî çàïóñêàòü ñ ïðàâàìè àäìèíèñòðàòîðà. Ïîñëå çàïóñêà â ïîÿâèâøåìñÿ
ñïèñêå íóæíî äâàæäû ù¸ëêíóòü ïî äèñêó, ñîîòâåòñòâóþùåìó âàøåé ôëåøêå.
Îá óñïåõå è íåóñïåõå ïðîãðàììà ñîîáùèò.
 
Óñòàíîâêà äëÿ ïîëüçîâàòåëåé äðóãèõ îïåðàöèîííûõ ñèñòåì:
àâòîìàòè÷åñêàÿ - ïîêà íå ïîääåðæèâàåòñÿ. Åñëè âû óìååòå ðàáîòàòü ñ ðåäàêòîðîì
äèñêîâ, âàì ïîìîãóò ñëåäóþùèå ñâåäåíèÿ: inst.exe ïðè óñòàíîâêå äåëàåò
ñëåäóþùåå:
- ñ÷èòûâàåò áóòñåêòîð, óáåæäàåòñÿ, ÷òî îí äåéñòâèòåëüíî FAT32;
- êîïèðóåò íà ôëåøêó ôàéë MTLD_F32, ïîïóòíî óñòàíàâëèâàÿ åìó àòðèáóòû
"ñêðûòûé","ñèñòåìíûé","òîëüêî äëÿ ÷òåíèÿ" (äëÿ ñàìîãî çàãðóç÷èêà àòðèáóòû
ðîëè íå èãðàþò, ýòî ÷òîáû ôàéë íå ëåç íà ãëàçà êîìó íå íàäî);
- ñ÷èòûâàåò ôàéë BOOT_F32.BIN; â ïðî÷èòàííûõ äàííûõ çàìåíÿåò ïàðàìåòðû
íà÷èíàÿ ñî ñìåùåíèÿ 3 è çàêàí÷èâàÿ 0x5A (0x57 áàéò) èç áóòñåêòîðà ôëåøêè;
- òî, ÷òî ïîëó÷èëîñü, çàïèñûâàåò íàçàä â áóòñåêòîð ôëåøêè,
à òàêæå â ðåçåðâíóþ êîïèþ áóòñåêòîðà, åñëè îíà åñòü (ïîëå ðàçìåðîì â 2 áàéòà
ñî ñìåùåíèåì 0x32) (ðåçåðâíóþ êîïèþ ìåíÿòü íà ñàìîì äåëå íåîáÿçàòåëüíî,
âñ¸ ðàâíî â ðåàëüíîé æèçíè îíà íå íóæíà).
 
Íàïðèìåð, ïîä Linux íîâûé áóòñåêòîð íà äèñê /dev/sdb1 (çàìåíèòå íà óñòðîéñòâî,
ñîîòâåòñòâóþùåå FAT32-òîìó) ìîæíî óñòàíîâèòü ïîñëåäîâàòåëüíîñòüþ èç äâóõ êîìàíä:
dd if=/dev/sdb1 of=BOOT_F32.BIN bs=1 skip=3 seek=3 count=87 conv=notrunc
dd if=BOOT_F32.BIN of=/dev/sdb1 bs=512 count=1 conv=notrunc
Êîïèðîâàíèå ôàéëîâ mtld_f32 è kolibri.img îñóùåñòâëÿåòñÿ îáû÷íûì ñïîñîáîì.
/programs/hd_load/usb_boot/rsrc.res
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/programs/hd_load/usb_boot/setmbr.asm
0,0 → 1,389
format PE GUI 4.0
section '.text' code readable executable
entry start
start:
xor ebx, ebx
push ebx ; lpParam
push 400000h ; hInstance
push ebx ; hMenu
push ebx ; hWndParent
push 100 ; nHeight
push 200 ; nWidth
mov eax, 80000000h
push eax ; y
push eax ; x
push 10EF0140h ; dwStyle
push WndName
push ClassName
push 388h ; dwExStyle
call [CreateWindowExA]
mov edi, eax
push 0Ah ; OEM_FIXED_FONT
call [GetStockObject]
push ebx
push eax
push 30h ; WM_SETFONT
push edi
call [SendMessageA]
call CollectDrivesInfo
push MyWndProc
push -4 ; GWL_WNDPROC
push edi
call [SetWindowLongA]
mov [OldWndProc], eax
sub esp, 20h
mov esi, esp
@@:
push ebx
push ebx
push ebx
push esi
call [GetMessageA]
test eax, eax
jz @f
push esi
call [TranslateMessage]
push esi
call [DispatchMessageA]
jmp @b
@@:
add esp, 20h
ret
 
MyWndProc:
push edi
mov edi, [esp+8]
cmp dword [esp+12], 2 ; WM_DESTROY
jnz @f
push 0
call [PostQuitMessage]
@@:
cmp dword [esp+12], 219h ; WM_DEVICECHANGE
jnz w
cmp dword [esp+16], 8000h ; DBT_DEVICEARRIVAL
jz @f
cmp dword [esp+16], 8004h ; DBT_DEVICEREMOVECOMPLETE
jnz w
@@:
call UpdateDrivesInfo
w:
cmp dword [esp+12], 203h ; WM_LBUTTONDBLCLK
jnz @f
push 0
push 0
push 188h ; LB_GETCURSEL
push edi
call [SendMessageA]
cmp eax, -1
jz @f
push n+4
push eax
push 189h ; LB_GETTEXT
push edi
call [SendMessageA]
mov dword [n], '\\.\'
mov byte [n+4+aPhysicalDrive.sz], 0
call install
@@:
pop edi
pop eax
push [OldWndProc]
push eax
jmp [CallWindowProcA]
 
UpdateDrivesInfo:
push 0
push 0
push 184h ; LB_RESETCONTENT
push edi
call [SendMessageA]
 
CollectDrivesInfo:
xor eax, eax
mov ecx, 32
push edi
mov edi, PhysicalDrives
rep stosd
pop edi
push esi
call [GetLogicalDrives]
mov esi, eax
mov [a], 'A'
l:
shr esi, 1
jnc d
mov [a+2], 0
push a
call [GetDriveTypeA]
; Uncomment following lines to allow hard drives
; cmp eax, 3 ; DRIVE_FIXED
; jz @f
cmp eax, 2 ; DRIVE_REMOVABLE
jnz d
@@:
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push 0 ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push 0 ; dwDesiredAccess
push a2
call [CreateFileA]
cmp eax, -1
jz d
push eax
push 0
mov ecx, esp
push 0 ; lpOverlapped
push ecx ; lpBytesReturned
push 12 ; nOutBufferSize
push sdn ; lpOutBuffer
push 0
push 0
push 2D1080h ; IOCTL_STORAGE_GET_DEVICE_NUMBER
push eax
call [DeviceIoControl]
pop ecx
pop edx
push eax
push edx
call [CloseHandle]
pop eax
test eax, eax
jz d ; probably it is floppy
mov eax, [sdn+4]
cmp eax, 32
jae d
movzx ecx, byte [a]
sub cl, 'A'
bts [PhysicalDrives+eax*4], ecx
d:
inc [a]
test esi, esi
jnz l
xor esi, esi
.physloop:
push esi
mov esi, [PhysicalDrives+esi*4]
test esi, esi
jz .physnext
push edi esi
mov esi, aPhysicalDrive
mov edi, n
@@:
lodsb
stosb
test al, al
jnz @b
pop esi
dec edi
mov eax, [esp+4]
cmp al, 10
jb .1dig
aam
add ah, '0'
mov byte [edi], ah
inc edi
.1dig:
add al, '0'
stosb
mov al, ':'
stosb
mov cl, 'A'-1
.logloop:
mov al, ' '
stosb
mov al, cl
stosb
@@:
inc byte [edi-1]
shr esi, 1
jnc @b
mov cl, [edi-1]
mov al, ':'
stosb
mov al, '\'
stosb
test esi, esi
jnz .logloop
mov al, 0
stosb
pop edi
push n
push 0
push 180h ; LB_ADDSTRING
push edi
call [SendMessageA]
.physnext:
pop esi
inc esi
cmp esi, 32
jb .physloop
pop esi
ret
 
install:
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition = OPEN_EXISTING
push 0 ; lpSecurityAttributes
push 3 ; dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
push 0C0000000h ; dwDesiredAccess = GENERIC_READ|GENERIC_WRITE
push n
call [CreateFileA]
cmp eax, -1
jnz @f
deverre:
push 10h
push 0
push deverr
push edi
call [MessageBoxA]
ret
@@:
push esi
mov esi, eax
push eax
mov eax, esp
push 0
push eax
push 512
push mbr_dev
push esi
call [ReadFile]
test eax, eax
jnz @f
deverrl:
push esi
call [CloseHandle]
pop eax
pop esi
jmp deverre
@@:
push esi edi
mov esi, mbr_new
mov edi, mbr_dev
mov ecx, 1B8h
rep movsb
mov al, [edi+6]
or al, [edi+16h]
or al, [edi+26h]
or al, [edi+36h]
test al, al
js @f
or byte [edi+6], 80h
@@:
pop edi esi
push 0
push 0
push 0
push esi
call [SetFilePointer]
test eax, eax
jnz deverrl
mov eax, esp
push 0
push eax
push 512
push mbr_dev
push esi
call [WriteFile]
test eax, eax
jz deverrl
cmp dword [esp], 512
jnz deverrl
; done!
done_succ:
push 40h
push ok
push succ
push edi
call [MessageBoxA]
push 0
call [PostQuitMessage]
r:
pop eax
push esi
call [CloseHandle]
pop esi
ret
 
section '.data' data readable writable
data resource from 'rsrc.res'
end data
 
ClassName db 'LISTBOX',0
WndName db 'Select drive',0
deverr db 'Cannot open physical device or device error (no administrator rights?)',0
ok db 'Success',0
succ db 'Standard MBR has been installed',0
a2 db '\\.\'
a db '?:',0,0
aPhysicalDrive db 'PhysicalDrive',0
.sz = $ - aPhysicalDrive
 
data import
macro thunk a
{a#_thunk:dw 0
db `a,0}
dd 0,0,0, rva kernel32_name, rva kernel32_thunks
dd 0,0,0, rva user32_name, rva user32_thunks
dd 0,0,0, rva gdi32_name, rva gdi32_thunks
dd 0,0,0,0,0
kernel32_name db 'kernel32.dll',0
user32_name db 'user32.dll',0
gdi32_name db 'gdi32.dll',0
kernel32_thunks:
GetLogicalDrives dd rva GetLogicalDrives_thunk
GetDriveTypeA dd rva GetDriveTypeA_thunk
CreateFileA dd rva CreateFileA_thunk
ReadFile dd rva ReadFile_thunk
WriteFile dd rva WriteFile_thunk
SetFilePointer dd rva SetFilePointer_thunk
CloseHandle dd rva CloseHandle_thunk
DeviceIoControl dd rva DeviceIoControl_thunk
dw 0
thunk GetLogicalDrives
thunk GetDriveTypeA
thunk CreateFileA
thunk ReadFile
thunk WriteFile
thunk SetFilePointer
thunk CloseHandle
thunk DeviceIoControl
user32_thunks:
CreateWindowExA dd rva CreateWindowExA_thunk
GetMessageA dd rva GetMessageA_thunk
TranslateMessage dd rva TranslateMessage_thunk
DispatchMessageA dd rva DispatchMessageA_thunk
PostQuitMessage dd rva PostQuitMessage_thunk
CallWindowProcA dd rva CallWindowProcA_thunk
SetWindowLongA dd rva SetWindowLongA_thunk
SendMessageA dd rva SendMessageA_thunk
MessageBoxA dd rva MessageBoxA_thunk
dw 0
thunk CreateWindowExA
thunk GetMessageA
thunk TranslateMessage
thunk DispatchMessageA
thunk PostQuitMessage
thunk CallWindowProcA
thunk SetWindowLongA
thunk SendMessageA
thunk MessageBoxA
gdi32_thunks:
GetStockObject dd rva GetStockObject_thunk
dw 0
thunk GetStockObject
end data
 
align 4
mbr_new:
file 'mbr'
 
align 4
OldWndProc dd ?
PhysicalDrives rd 32
sdn rd 3
n rb 1024
mbr_dev rb 512