This module contains the micro-FSD which is located between the partition bootsector and the actual data on the hard drive. The load segment was calculated in Phase 2 and for the Bochs drive image is 0x8800. The entry point is 8800:199C or 0x8999C with the registers (Bochs image) loaded as follows:
eax: 0x0000199C ecx: 0x00007FBE edx: 0x00000080 ebx: 0x00000000 esp: 0x00007C00 ebp: 0x00000000 esi: 0xFFFF0046 edi: 0x00000000 eflags 0x00000246 IOPL=0 id vip vif ac vm rf nt of df IF tf sf ZF af PF cf
Segment registers:
cs:s=0x8800 ds:s=0x8800 ss:s=0x0000 es:s=0x07C0 fs:s=0x3000
This is somewhat irrelevant because es, ds, and ss will be set to cs (0x8800 in this example) and sp set to 0x5000.
Items from previous loads:
- If INT13 Ext functions are supported then 3000:0000, segment contain in fs, has 58333149h, stored as 49 31 33 58. If not the location is zero.
- The storage area contains the results of Phase 2 — (Bochs disk) 0x8803E 3F, 0, 0 0, 0, 0, 0, 0 or 0x000000000000003F.
The JFS superblock procedure loads the super block and stores values at the following locations:
offset 1858 to 185B (0x89858 to 0x89858)
offset 185C to 185F (0x8985C to 0x8985F)
; module locations
ft_cfiles dw 3
ft_ldrseg dw 0
ft_ldrlen dd 0
ft_museg dw 0
ft_mulen dd 0x5000
ft_mfsseg dw 0
ft_mfslen dd 0
ft_ripseg dw 0
ft_riplen dd 0x0
; microFSD vector table
ft_muOpen dd seg:1A9C
ft_muRead dd seg:1BD4
ft_muClose dd seg:1DAE
ft_muTerminate dd seg:1DD4
88000 jmp short near ptr _entry ; Entry point from MBR code 88002 nop ; BIOS parameter block (BPB) 88003 db 'IBM 4.50' ; Partition creator 8800B db 0, 2 ; 0x0200 size of sector in bytes 8800D db 0 8800E db 0 8800F db 0 88010 db 0 88011 db 0 88012 db 0 88013 db 0 88014 db 0 88015 db F8 ; media type - hard disk 88016 db 0 88017 db 0 88018 db 3F, 0 ; BPB formatted geo: Sectors - 63 8801A db 20, 0 ; BPB formatted geo: Heads - 32 8801C db 3F, 0, 0 ,0 ; 0x0000003F hidden sectors 88020 db 41, 12, 13, 0 ; 0x00131241 Big number of sectors 88024 db 80 ; physical drive number 88025 db 80 ; Boot drive letter 88026 db 29 ; Ext-BPB signature 88027 db BD , 55, 9C, 69 ; Partition serial number 0x699c55bd 8802B db bochs, 0, 0, 0, 0, 0, 0 ; Partition label (11) 88036 db "JFS " ; Filesystem type (8) ; Used as temp storage 8803E db 0, 0, 0, 0 ; absolute number of the start of the sectors 88042 db 0, 0, 0, 0 ; DAP : Disk Address Packet (16 bytes) 88046 db 10 ; size of DAP = 16 = 10h 88047 db 0 ; unused, should be zero 88048 db 20 ; number of sectors to be read 88049 db 0 ; unused, should be zero 8804A db 0, 0, 0, 0 ;segment:offset pointer to the memory buffer 8804E db 0, 0, 0, 0, 0, 0, 0, 0
; esp: 0x00004ffe ebp: 0x00000000 esi: 0xffff160c edi: 0x00000040
; IOPL=0 id vip vif ac vm rf nt of df IF tf sf ZF af PF cf
; readdrive ; ; entry: ; ax contains number of sectors to read ; es segment for DAP structure ; ds segment for transfer buffer ; si offset for transfer buffer ; es:003E + 4 and es:0042 + 4 absolute number start sectors to read ; es:0024 drive index ; di (L) and bx (H) contain offset to absolute start for begin read readdrive proc near push ds ; save ds and dx push dx mov dx, ds push es pop ds ; set ds to entry es value ; DAP : Disk Address Packet (16 bytes) ; offset range size description ; 00h 1 byte size of DAP = 16 = 10h ; 01h 1 byte unused, should be zero ; 02h 1 byte number of sectors to be read, 0..127 (= 7Fh) ; 03h 1 byte unused, should be zero ; 04h..07h 4 bytes segment:offset pointer to the memory buffer ; to which sectors will be transferred ; 08h..0Fh 8 bytes absolute number of the start of the sectors to be read ; This routine DAP structure: ; ds:0046 size of DAP - 16 bytes always ; ds:0047 always zero ; ds:0048 number of sectors to read ; ds:0049 always zero ; ds:004A to 004D segment:offset pointer transfer buffer ; ds:004E to 0055 absolute number of the start of the sectors to be ; read (1st sector of drive has number 0) ; Load DAP mov ds:48h, ax ; number of sectors to read, ax contains on entry mov ds:4Ch, dx ; Buffer segment mov ds:4Ah, si ; Buffer offset mov si, 46h ; DAP offset mov eax, ds:3Eh ; move sector read start from storage area mov ds:4Eh, eax ; ds:003E to ds:0055 to DAP mov eax, ds:42h mov ds:52h, eax add ds:4Eh, edi adc ds:52h, ebx ; DAP located at ds:0046 mov ah, 42h ; 42h = function number for extended read mov dl, ds:24h ; drive index mov al, 0 int 13h ; cf Set On Error, Clear If No Error ; ah Return Code jnb short goodread or ah, ah jnz short readerror goodread: pop dx ; restore entry dx and ds before returning pop ds retn readerror: ; display some DAP info push ax mov eax, ds:52h shr eax, 10h call dispaddress mov eax, ds:52h call dispaddress mov eax, ds:4Eh shr eax, 10h call dispaddress mov eax, ds:4Eh call dispaddress mov ax, ds:48h shl eax, 10h pop ax mov al, dl mov si, 0DEh ; SYS02027 message call $+3 ; really a jump to displayerr - never returns readdrive endp ; displayerr ; Display error message pointed to by ds:(e)si and address ; then hang the system displayerr proc near cld push eax _dispnextchar: lodsb ; Load byte at address DS:(E)SI into AL test al, 0FFh jz short _endmessage mov ah, 0Eh mov bx, 7 int 10h jmp short _dispnextchar _endmessage: sti pop eax push eax and eax, 0FFFF0000h shr eax, 10h call dispaddress mov al, 3Ah mov ah, 0Eh mov bx, 7 int 10h pop eax call dispaddress _hangsystem: jmp short _hangsystem displayerr endp ; dispaddress ; Display address in hex dispaddress proc near push ax mov al, ah and al, 0F0h mov cl, 4 shr al, cl call dispchar pop ax push ax mov al, ah and al, 0Fh call dispchar pop ax push ax and al, 0F0h mov cl, 4 shr al, cl call dispchar pop ax push ax and al, 0Fh call dispchar pop ax retn dispaddress endp ; dispchar ; Output char from dispaddress dispchar proc near add al, 30h cmp al, 39h jle short _dispchar1 add al, 7 _dispchar1: mov ah, 0Eh mov bx, 7 int 10h retn dispchar endp
eax: 0x0000199c 6556
ecx: 0x00007fbe 32702
edx: 0x00000080 128
ebx: 0x00000000 0
esp: 0x00007c00 31744
ebp: 0x00000000 0
esi: 0xffff0046 -65466
edi: 0x00000000 0
eip: 0x0000199c
eflags 0x00000246
IOPL=0 id vip vif ac vm rf nt of df IF tf sf ZF af PF cf
; cs:s=0x8800 ds:s=0x8800 ss:s=0x0000 es:s=0x07c0 fs:s=0x3000
0x0008924a <bogus+ 0>: 0x03 0x00 0x00 0x10 0x00 0xae 0x00 0x00
0x00089252 <bogus+ 8>: 0x00 0x88 0x00 0x50 0x00 0x00 0x7c 0x00
0x0008925a <bogus+ 16>: 0xe9 0xea 0x00 0x00 0x00 0x00 0x00 0x00
0x00089262 <bogus+ 24>: 0x00 0x00 0x9c 0x1a 0x00 0x88
8924A ft_cfiles dw 0x0003 8924C ft_ldrseg dw 0x1000 8924E ft_ldrlen dd 0xAE ; will vary with version of os2ldr used 89252 ft_museg dw 0x0000 89254 ft_mulen dd 0 89258 ft_mfsseg dw 0 8925A ft_mfslen dd 0 8925E ft_ripseg dw 0 89260 ft_riplen dd 0 ; microFSD vector table 89264 ft_muOpen_OFF dw 0 89266 ft_muOpen_SEG dw 0 89268 ft_muRead_OFF dw 0 8926A ft_muRead_SEG dw 0 8926C ft_muClose_OFF dw 0 8926E ft_muClose_SEG dw 0 89270 ft_muTerminate_OFF dw 0 89272 ft_muTerminate_SEG dw 0
This is the main entry point from Phase 2:
(SEG:199C) _entry proc far push cs pop ax mov es, ax ; swap cs to es mov ds, ax ; set ds to cs ; setup stack cli mov ss, ax ; set ss to cs mov sp, 5000h sti ; es / ds / ss set to entry cs call readsuperblock mov ax, 202h push ds push ax push ds mov si, 2B2Fh ; ALTF2ON.$ location push si mov ax, cs mov word ptr cs:loc_899BC+3, ax loc_899BC: call ft_muOpen add sp, 8 ; clean up the stack - post C function? or ax, ax jnz short MAIN_JMP_1 ; ?? zero return is good result mov al, 1 mov ds:byte_8AB2E, al mov ax, cs mov word ptr cs:loc_899D3+3, ax loc_899D3: call ft_muClose MAIN_JMP_1: mov si, 1D6h ; os2boot file name mov di, 7Ch ; os2boot load address mov ds:ft_mfsseg, di ; miniFSD location call LoadFile test bx, 1 ; test if good load jz short good_os2boot mov si, 1274h ; SYS1475: The file OS2BOOT cannot be found call ErrorHangSys ; does not return good_os2boot: mov eax, ds:dword_88202 mov ds:ft_mfslen, eax ; miniFSD length mov si, 1CFh ; os2ldr file name mov di, 1000h ; os2boot load address mov ds:ft_ldrseg, di ; os2ldr location call LoadFile test bx, 1 ; test if good load jz short good_os2ldr mov si, 12ABh ; Missing OS2LDR call ErrorHangSys ; does not return good_os2ldr: mov eax, ds:dword_88202 mov ds:ft_ldrlen, eax ; os2ldr length ; loading 0Fh to DispCopyInd stops display ; of copyright message mov al, 0Fh mov ds:DispCopyRInd, al ; setup MicroFSD entry push ds pop ax mov ds:ft_museg, ax ; MicroFSD location mov eax, 5000h mov ds:ft_mulen, eax ; MicroFSD length ; number of entries mov ds:ft_cfiles, 3 ; sets up a function list mov ds:ft_muOpen_SEG, ds mov ds:ft_muOpen_OFF, 1A9Ch ; ds:1A9C mov ds:ft_muRead_SEG, ds mov ds:ft_muRead_OFF, 1BD4h ; ds:1BD4 mov ds:ft_muClose_SEG, ds mov ds:ft_muClose_OFF, 1DAEh ; ds:1DAE mov ds:ft_muTerminate_SEG, ds mov ds:ft_muTerminate_OFF, 1DAEh ; ds:1DD4 mov ds:ft_ripseg, 0 mov ds:ft_riplen, 0 push ds push cs pop ds mov eax, dword ptr ds:aJfs+8 mov ds:dword_8801C, eax pop ds assume ds:nothing xor di, di ; zero di mov es:[di], eax mov dl, ds:24h mov dh, dl mov ds:24h, dx mov dh, 14h mov si, 0Bh push ds pop es mov di, 124Ah mov ax, ds:124Ch push ax xor ax, ax push ax retf ; Should be a return which enters os2ldr _entry endp
readsuperblock proc near mov si, 160Ch ; 8800:160C buffer mov ax, 1 ; read 1 sector mov edi, 40h ; offset from beginning of partition mov ebx, 0 ; for read ; read 1 sector from offset of partition 0x40 (64) or 32,768 ; from the IBM docs this would be the superblock and it gets ; read into memory at offset 160C buffer ; see openJFS -- jfs_superblock.h call readdrive ; load superblock to 0x8960C mov eax, ds:161Ch bsf ecx, eax mov ds:1942h, cx ; 0x89942 mov edx, ds:163Ch and edx, 0FF000000h shr edx, 18h mov eax, ds:1640h shld edx, eax, cl shl eax, cl mov ds:1858h, eax ; 0x89858 mov ds:185Ch, edx ; 0x8985C mov dword ptr ds:23Eh, 2 ; 0x8823E push bp mov bp, sp xor ecx, ecx mov di, 3D45h call sub_8AA59 mov cl, al mov ch, 0 push cx mov di, 1509h call sub_8AA59 mov bx, 1 pop cx cmp cl, al jg short loc_8AA55 mov si, 3D45h mov di, 1509h mov bx, 1 repe cmpsb or cl, cl jnz short loc_8AA55 cmp byte ptr es:[di], 5Ch ; '\' jz short loc_8AA3E cmp byte ptr es:[di], 0 jnz short loc_8AA55 loc_8AA3E: mov al, [si-1] cmp al, es:[di-1] jnz short loc_8AA55 mov di, si mov al, 5Ch ; '\' stosb mov ds:14EFh, di xor ax, ax stosb xor bx, bx loc_8AA55: mov ax, bx pop bp retn readsuperblock endp