/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 |