📄 memdisk.asm
字号:
movzx edi,word [es:si+6] ; Segment shl edi,4 add esi,edi jmp .got_address.linear_address: cmp dx,24 ; Must be large enough to hold linear address jb .baddapa cmp dword [es:si+20],0 ; > 4 GB addresses not supported jne .overrun mov esi,[es:si+16].got_address: cmp dword [es:si+12],0 ; LBA too large? jne .overrun movzx ecx, word [es:si+2] ; Sectors to transfer mov edi,[es:si+8] ; Starting sector mov eax,edi add eax,ecx jc .overrun cmp eax,[DiskSize] ja .overrun shl ecx,SECTORSIZE_LG2-2 ; Convert to dwords shl edi,SECTORSIZE_LG2 ; Convert to an offset add edi,[DiskBuf] pop es ret.baddapa: mov ax,0100h ; Invalid command pop es pop ax ; Drop setup_regs return address ret.overrun: and word [es:si+2],0 ; No sectors transferred mov ax,0200h pop es pop ax ret%endif ; EDD;; INT 15h intercept routines;int15_e820: cmp edx,534D4150h ; "SMAP" jne near oldint15 cmp ecx,20 ; Need 20 bytes jb err86 push ds push cs pop ds and ebx,ebx jne .renew mov ebx,E820Table.renew: add bx,12 ; Advance to next mov eax,[bx-4] ; Type and eax,eax ; Null type? jz .renew ; If so advance to next mov [es:di+16],eax mov eax,[bx-12] ; Start addr (low) mov [es:di],eax mov ecx,[bx-8] ; Start addr (high) mov [es:di+4],ecx mov eax,[bx] ; End addr (low) mov ecx,[bx+4] ; End addr (high) sub eax,[bx-12] ; Derive the length sbb ecx,[bx-8] mov [es:di+8],eax ; Length (low) mov [es:di+12],ecx ; Length (high) cmp dword [bx+8],-1 ; Type of next = end? jne .notdone xor ebx,ebx ; Done with table.notdone: mov eax,edx ; "SMAP" pop ds mov ecx,20 ; Bytes loadedint15_success: mov byte [bp+6], 02h ; Clear CF pop bp ireterr86: mov byte [bp+6], 03h ; Set CF mov ah,86h pop bp iretInt15Start: push bp mov bp,sp cmp ax,0E820h je near int15_e820 cmp ax,0E801h je int15_e801 cmp ax,0E881h je int15_e881 cmp ah,88h je int15_88oldint15: pop bp jmp far [cs:OldInt15] int15_e801: mov ax,[cs:Mem1MB] mov cx,ax mov bx,[cs:Mem16MB] mov dx,bx jmp short int15_successint15_e881: mov eax,[cs:Mem1MB] mov ecx,eax mov ebx,[cs:Mem16MB] mov edx,ebx jmp short int15_successint15_88: mov ax,[cs:MemInt1588] jmp short int15_success;; Routine to copy in/out of high memory; esi = linear source address; edi = linear target address; ecx = 32-bit word count ;; Assumes cs = ds = es;bcopy: push eax push ebx push edx push ebp test byte [ConfigFlags],CONFIG_RAW jz .anymode smsw ax ; Unprivileged! test al,01h jnz .protmode.realmode: TRACER 'r' ; We're in real mode, do it outselves pushfd push ds push es cli cld xor ebx,ebx mov bx,cs shl ebx,4 lea edx,[Shaker+ebx] mov [Shaker+2],edx ; Test to see if A20 is enabled or not xor ax,ax mov ds,ax dec ax mov es,ax mov ax,[0] mov bx,ax xor bx,[es:10h] not ax mov [0],ax mov dx,ax xor dx,[es:10h] not ax mov [0],ax or dx,bx push dx ; Save A20 status jnz .skip_a20e mov ax,2401h ; Enable A20 int 15h.skip_a20e: mov dl,[ConfigFlags] and dx,CONFIG_BIGRAW add dx,8 ; DX = 16 for BIGRAW, 8 for RAW ; 8 is selector for a 64K flat segment, ; 16 is selector for a 4GB flat segment. lgdt [cs:Shaker] mov eax,cr0 or al,01h mov cr0,eax mov bx,16 ; Large flat segment mov ds,bx mov es,bx a32 rep movsd ; DX has the appropriate value to put in ; the registers on return mov ds,dx mov es,dx and al,~01h mov cr0,eax pop es pop ds pop dx ; A20 status and dx,dx jnz .skip_a20d mov ax,2400h ; Disable A20 int 15h.skip_a20d: popfd jmp .done.protmode: TRACER 'p'.anymode:.copy_loop: push esi push edi push ecx cmp ecx,4000h jna .safe_size mov ecx,4000h.safe_size: push ecx ; Transfer size this cycle mov eax, esi mov [Mover_src1], si shr eax, 16 mov [Mover_src1+2], al mov [Mover_src2], ah mov eax, edi mov [Mover_dst1], di shr eax, 16 mov [Mover_dst1+2], al mov [Mover_dst2], ah mov si,Mover mov ah, 87h shl cx,1 ; Convert to 16-bit words int 15h cli ; Some BIOSes enable interrupts on INT 15h pop eax ; Transfer size this cycle pop ecx pop edi pop esi jc .error lea esi,[esi+4*eax] lea edi,[edi+4*eax] sub ecx, eax jnz .copy_loop ; CF = 0.error:.done: pop ebp pop edx pop ebx pop eax ret%ifdef DEBUG_TRACERSdebug_tracer: pushad pushfd mov bp,sp mov bx,[bp+9*4] mov al,[cs:bx] inc word [bp+9*4] mov ah,0Eh mov bx,7 int 10h popfd popad ret%endif section .data alignb 2Int13Funcs dw Reset ; 00h - RESET dw GetStatus ; 01h - GET STATUS dw Read ; 02h - READ dw Write ; 03h - WRITE dw Verify ; 04h - VERIFY dw Invalid ; 05h - FORMAT TRACK dw Invalid ; 06h - FORMAT TRACK AND SET BAD FLAGS dw Invalid ; 07h - FORMAT DRIVE AT TRACK dw GetParms ; 08h - GET PARAMETERS dw InitWithParms ; 09h - INITIALIZE CONTROLLER WITH DRIVE PARAMETERS dw Invalid ; 0Ah dw Invalid ; 0Bh dw Seek ; 0Ch - SEEK TO CYLINDER dw Reset ; 0Dh - RESET HARD DISKS dw Invalid ; 0Eh dw Invalid ; 0Fh dw CheckIfReady ; 10h - CHECK IF READY dw Recalibrate ; 11h - RECALIBRATE dw Invalid ; 12h dw Invalid ; 13h dw Invalid ; 14h dw GetDriveType ; 15h - GET DRIVE TYPE dw DetectChange ; 16h - DETECT DRIVE CHANGE%if EDD dw Invalid ; 17h dw Invalid ; 18h dw Invalid ; 19h dw Invalid ; 1Ah dw Invalid ; 1Bh dw Invalid ; 1Ch dw Invalid ; 1Dh dw Invalid ; 1Eh dw Invalid ; 1Fh dw Invalid ; 20h dw ReadMult ; 21h - READ MULTIPLE dw WriteMult ; 22h - WRITE MULTIPLE dw SetMode ; 23h - SET CONTROLLER FEATURES dw SetMode ; 24h - SET MULTIPLE MODE dw Invalid ; 25h - IDENTIFY DRIVE dw Invalid ; 26h dw Invalid ; 27h dw Invalid ; 28h dw Invalid ; 29h dw Invalid ; 2Ah dw Invalid ; 2Bh dw Invalid ; 2Ch dw Invalid ; 2Dh dw Invalid ; 2Eh dw Invalid ; 2Fh dw Invalid ; 30h dw Invalid ; 31h dw Invalid ; 32h dw Invalid ; 33h dw Invalid ; 34h dw Invalid ; 35h dw Invalid ; 36h dw Invalid ; 37h dw Invalid ; 38h dw Invalid ; 39h dw Invalid ; 3Ah dw Invalid ; 3Bh dw Invalid ; 3Ch dw Invalid ; 3Dh dw Invalid ; 3Eh dw Invalid ; 3Fh dw Invalid ; 40h dw EDDPresence ; 41h - EDD PRESENCE DETECT dw EDDRead ; 42h - EDD READ dw EDDWrite ; 43h - EDD WRITE dw EDDVerify ; 44h - EDD VERIFY dw Invalid ; 45h - EDD LOCK/UNLOCK MEDIA dw Invalid ; 46h - EDD EJECT dw EDDSeek ; 47h - EDD SEEK dw EDDGetParms ; 48h - EDD GET PARAMETERS%endifInt13FuncsEnd equ $Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1%if EDDEDD_DPT:.length dw 30 ; Bit 0 - DMA boundaries handled transparently ; Bit 3 - Device supports write verify.info dw 0009h.cylinders dd 0 ; No physical geometry.heads dd 0 ; No physical geometry.sectors dd 0 ; No physical geometry.totalsize dd 0, 0 ; Total number of sectors.bytespersec dw SECTORSIZE.eddtable dw -1, -1 ; Invalid EDD table%endif alignb 8, db 0Shaker dw ShakerEnd-$ dd 0 ; Pointer to self dw 0Shaker_RMDS: dd 0x0000ffff ; 64K data segment dd 0x00009300Shaker_DS: dd 0x0000ffff ; 4GB data segment dd 0x008f9300ShakerEnd equ $ alignb 8, db 0Mover dd 0, 0, 0, 0 ; Must be zero dw 0ffffh ; 64 K segment sizeMover_src1: db 0, 0, 0 ; Low 24 bits of source addy db 93h ; Access rights db 00h ; Extended access rightsMover_src2: db 0 ; High 8 bits of source addy dw 0ffffh ; 64 K segment sizeMover_dst1: db 0, 0, 0 ; Low 24 bits of target addy db 93h ; Access rights db 00h ; Extended access rightsMover_dst2: db 0 ; High 8 bits of source addyMover_dummy2: dd 0, 0, 0, 0 ; More space for the BIOS alignb 4, db 0MemDisk_Info equ $ ; Pointed to by installation checkMDI_Bytes dw 27 ; Total bytes in MDI structureMDI_Version db VER_MINOR, VER_MAJOR ; MEMDISK versionPatchArea equ $ ; This gets filled in by the installerDiskBuf dd 0 ; Linear address of high memory diskDiskSize dd 0 ; Size of disk in blocksCommandLine dw 0, 0 ; Far pointer to saved command lineOldInt13 dd 0 ; INT 13h in chainOldInt15 dd 0 ; INT 15h in chainOldDosMem dw 0 ; Old position of DOS mem endBootLoaderID db 0 ; Boot loader ID from header; ---- MDI structure ends here --- db 0, 0, 0 ; padMemInt1588 dw 0 ; 1MB-65MB memory amount (1K)Cylinders dw 0 ; Cylinder countHeads dw 0 ; Head countSectors dd 0 ; Sector count (zero-extended)Mem1MB dd 0 ; 1MB-16MB memory amount (1K)Mem16MB dd 0 ; 16MB-4G memory amount (64K)DriveNo db 0 ; Our drive numberDriveType db 0 ; Our drive type (floppies)DriveCnt db 0 ; Drive count (from the BIOS)ConfigFlags db 0 ; Bit 0 - readonlyMyStack dw 0 ; Offset of stackStatusPtr dw 0 ; Where to save status (zeroseg ptr)DPT times 16 db 0 ; BIOS parameter table pointer (floppies) ; End patch areaStack dd 0 ; Saved SS:ESP on invocation dw 0SavedAX dw 0 ; AX saved on invocation alignb 4, db 0 ; We *MUST* end on a dword boundaryE820Table equ $ ; The installer loads the E820 table hereTotalSize equ $ ; End pointer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -