cheng_5103
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2012-03-21
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望228点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
阅读:6564回复:6

我把NTLDR的源代码贴上来,大家一起来讨论分析吧!

楼主#
更多 发布于:2005-04-22 17:35
;++
;
; Module name
;
;       su.asm
;
; Author
;
;       Thomas Parslow  (tomp)  Jan-15-91
;
; Description
;
;       Startup module for the 386 NT OS loader.
;
; Exported Procedures
;
;       EnableProtectPaging
;
; Notes
;       NT386 Boot Loader program. This assembly file is required in
;       order to link C modules into a \"/TINY\"  (single segment) memory
;       model.
;
;
; ** WHAT\'S MISSING **
; Still need to add:
;  o  a20 enable code
;  o  compaq speed code (??)
;  o  low/high memory size determination
;
;
;
; This file does the following:
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; 1) Defines the entry point for the boot loader\'s startup program
; 2) Computes what values should actually be in the DS and SS registers.
; 3) Provides the int bios functionality
; 4) Provides 386/486 mode (protect/paging) switching code.
;
; The OS/2 bootstrap routine (boot sector) loads the boot loader program at
; real-mode address 2000:0000 with the following register values:
;
;       CS = 2000
;       IP = 0000
;       DS = 07C0
;       ES = 1000
;       SS = 0000
;       SP = 7C00
;
; Build Notes:
; ~~~~~~~~~~~~
; The microsoft C compiler will not produce \"tiny\" model programs. In the
; tiny model, the entire program consists of only one segment. The small
; model produced by our compilers consists of two segments: DGROUP and _TEXT.
; If you convert a small model program into a tiny model program, DS (which
; should point to DGROUP (bss,const,data) will always be wrong. For this reason
; we need an assembly module to do a simple run-time fixup on SS and DS. To
; guarantee that DS will point to DGROUP no matter where os2ldr is loaded,
; the paragraph (shifted right four bits) offset of DGROUP from _TEXT must
; be added to the value in CS to compute DS and SS.
;
; We get the linker to fixup the offset of the beginning of the dgroup segment
; relative to the beginning of the code segment and it\'s this value added
; to the value in CS that allows us to build a \"tiny\" model program in C
; without a lot of munging around in order to get the data reference offsets
; in the code correct.
;
; If the _TEXT:DGROUP fixup appears in other files (which it does), the linker
; will not compute the correct value unless the accumulated data pointer is
; zero when it gets there. Therefore, no data should be placed in the data segment
; until after all instances of _TEXT:DGROUP have been encountered by the linker.
; The linker processes files from right to left on the command line.
;
; A Note About Stacks
; Initially we run on our internal stack (SuStack) which is only 160 bytes deep
; but seems to do the trick. Then we have to have a separate double fault stack.
; This stack can be in the middle of the stack/data segment. It will step on
; the loader image, but that\'s ok since the fault was either caused by 16bit
; code (which won\'t be in the loader image) or, it was caused by the 32bit
; loader (which has already been relocated) so we won\'t be stepping on code
; that may have caused the fault. And finally, we have the \"call back\" stack
; which  starts at the top of the stack/data segment. We use this during
; all call backs since the original loader source is no longer needed and
; this\'ll give us plenty of stack for bios calls etc.
;
;--

DoubleWord      struc
lsw     dw      ?
msw     dw      ?
DoubleWord      ends

;
; This is the structure used to pass all shared data between the boot sector
; and NTLDR.
;

SHARED  struc
        ReadClusters            dd      ?               ; function pointer
        ReadSectors             dd      ?               ; function pointer

        SectorBase              dd      ?               ; starting sector
                                                        ; for ReadSectors
                                                        ; callback
SHARED  ends


BPB     struc
        BytesPerSector          dw      ?
        SectorsPerCluster       db      ?
        ReservedSectors         dw      ?
        Fats                    db      ?
        DirectoryEntries        dw      ?
        Sectors                 dw      ?
        Media                   db      ?
        FatSectors              dw      ?
        SectorsPerTrack         dw      ?
        Heads                   dw      ?
        HiddenSectors           dd      ?
        SectorsLong             dd      ?
;
; The following byte is NOT part of the BPB but is set by SYS and format
;

        BootDriveNumber         db      ?
BPB     ends

SU_CODEMODULE    equ      1        ; Identifies this module to \"su.inc\"
include su.inc
include macro.inc

extrn _BootRecord:word
extrn _puts:near
extrn _MemoryDescriptorList:near
extrn _InsertDescriptor:near

MAXREAD     EQU 10000h
MAXSECTORS  EQU MAXREAD/0200h

_TEXT   segment para use16 public \'CODE\'
        ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
.386p

;
; Run-time fixups for stack and data segment
;

public Start
Start:
;
; The FAT boot sector only reads in the first 512 bytes of NTLDR.  This is
; the module that contains those 512 bytes, so we are now responsible for
; loading the rest of the file.  Other filesystems (i.e. HPFS, NTFS, RIPL)
; will load the whole file, so the default entrypoint branches around the
; FAT-specific code.
;
        jmp     RealStart

FatBegin:
.386
;
; If we\'re here, we\'ve booted off a FAT system and we must load the rest
; of NTLDR at 2000:0200 (right behind this sector)  NTLDR passes us the
; following:
;       BX = Starting Cluster Number of NTLDR
;       DL = INT 13h drive number we\'ve booted from
;       DS:SI -> boot media\'s BPB
;       DS:DI -> argument structure (see above struc definition)
;

;
; Save away the boot drive and the starting cluster number
;
        push    dx
        push    bx

;
; Blast the FAT into memory at 6000:0000 - 8000:0000
;

.386
        push    06000h
.8086
        pop     es
        xor     bx,bx                           ; (es:bx) = 6000:0000
        mov     cx,ds:[si].ReservedSectors
        mov     ds:[di].SectorBase.msw,0
        mov     ds:[di].SectorBase.lsw,cx       ; set up Sector Base

        mov     ax,ds:[si].FatSectors           ; (al) = # Sectors to read
        cmp     ax,080h
        jbe     FatLt64k

;  The FAT is > 64k, so we read the first 64k chunk, then the rest.
;  (A 16-bit FAT can\'t be bigger than 128k)

        push    cx
        mov     ax,080h         ; (al) = # of sectors to read
        call    ds:[di].ReadSectors
        pop     cx                      ; (cx) = previous SectorBase
.386
        push    07000h
.8086
        pop     es
        xor     bx,bx                   ; (es:bx) = 7000:0000
        mov     ax,ds:[si].FatSectors
        sub     ax,080h                 ; (ax) = # Sectors left to read
        add     cx,080h                 ; (cx) = SectorBase for next read
        mov     ds:[di].SectorBase.lsw,cx
        adc     ds:[di].SectorBase.msw,0        ; set up SectorBase

;
; (al) = # of sectors to read
;
FatLt64k:
        call    ds:[di].ReadSectors

;
; FAT is in memory, now we restore our starting cluster number
;
        pop     dx                      ; (dx) = starting cluster number
        xor     bx,bx

;
; set up FS and GS for reading the FAT
;
.386
        mov     ax,6000h
        mov     fs,ax
        mov     ax,7000h
        mov     gs,ax
.8086

;
; set up ES for reading in the rest of us
;
        push    cs
        pop     es

        mov     ah,MAXSECTORS           ; (ah) = number of sectors we can read
                                        ;        until boundary

FatLoop:
;
; (dx) = next cluster to load
;
        push    dx
        mov     al,ds:[si].SectorsPerCluster    ; (al) = number of contiguous sectors
                                                ;        found
        sub     ah,ds:[si].SectorsPerCluster                                                    ;        can read before 64k

;
; Check to see if we\'ve reached the end of the file
;
        cmp     dx,0ffffh
        jne     Fat10

;
; The entire file has been loaded.  Throw away the saved next cluster,
; restore the boot drive, and let NTLDR do its thing.
;
        pop     dx
        pop     dx
        jmp     RealStart

Fat10:
        mov     cx,dx
;
; (dx) = (cx) = last contiguous cluster
; (al) = # of contiguous clusters found
;

        call    NextFatEntry
;
; (dx) = cluster following last contiguous cluster

;
; Check to see if the next cluster is contiguous.  If not, go load the
; contiguous block we\'ve found.
;
        inc     cx
        cmp     dx,cx

        jne     LncLoad

;
; Check to see if we\'ve reached the 64k boundary.  If so, go load the
; contiguous block so far.  If not, increment the number of contiguous
; sectors and loop again.
;
        cmp     ah,0
        jne     Lnc20
        mov     ah,MAXSECTORS           ; (ah) = number of sectors until
                                        ;        boundary reached again
        jmp     short LncLoad

Lnc20:
        add     al,ds:[si].SectorsPerCluster
        sub     ah,ds:[si].SectorsPerCluster
        jmp     short Fat10


LncLoad:
;
; (TOS) = first cluster to load
; (dx)  = first cluster of next group to load
; (al)  = number of contiguous sectors
;
        pop     cx
        push    dx
        mov     dx,cx
        mov     cx,10                   ; (cx) = retry count

;
; N.B.
;       This assumes that we will never have more than 255 contiguous clusters.
;       Since that would get broken up into chunks that don\'t cross the 64k
;       boundary, this is ok.
;
; (dx) = first cluster to load
; (al) = number of contiguous sectors
; (TOS) = first cluster of next group to load
; (es:bx) = address where clusters should be loaded
;
FatRetry:
        push    bx
        push    ax
        push    dx
        push    cx

if 0
        push    dx
        call    PrintDbg
        mov     dx,ax
        call    PrintDbg
        pop     dx
endif

        call    [di].ReadClusters
        jnc     ReadOk
;
; error in the read, reset the drive and try again
;
if 0
        mov     dx, ax
        call    PrintDbg
endif
        mov     ax,01h
        mov     al,ds:[si].BootDriveNumber
        int     13h
if 0
        mov     dx,ax
        call    PrintDbg
endif
        xor     ax,ax
        mov     al,ds:[si].BootDriveNumber
        int     13h

;
; pause for a while
;
        xor     ax,ax
FatPause:
        dec     ax
        jnz     FatPause

        pop     cx
        pop     dx
        pop     ax
        pop     bx

        dec     cx
        jnz     FatRetry

;
; we have re-tried ten times, it still doesn\'t work, so punt.
;
        push    cs
        pop     ds
        mov     si,offset FAT_ERROR
FatErrPrint:
        lodsb
        or      al,al
        jz      FatErrDone
        mov     ah,14           ; write teletype
        mov     bx,7            ; attribute
        int     10h             ; print it
        jmp     FatErrPrint

FatErrDone:
        jmp     $
FAT_ERROR       db      \"NTLDR: I/O error reading disk\",0dh,0ah
                db      \"       Please insert another disk\",0dh,0ah,0


ReadOk:
        pop     cx
        pop     dx
        pop     ax
        pop     bx
        pop     dx                      ; (dx) = first cluster of next group
                                        ;        to load.

.386
;
; Convert # of sectors into # of bytes.
;
        mov     cl,al
        xor     ch,ch
        shl     cx,9
.8086
        add     bx,cx
        jz      FatLoopDone
        jmp     FatLoop

FatLoopDone:
;
; (bx) = 0
;   This means we\'ve just ended on a 64k boundary, so we have to
;   increment ES to continue reading the file.  We are guaranteed to
;   always end on a 64k boundary and never cross it, because we
;   will reduce the number of contiguous clusters to read
;   to ensure that the last cluster read will end on the 64k boundary.
;   Since we start reading at 0, and ClusterSize will always be a power
;   of two, a cluster will never cross a 64k boundary.
;
        mov     ax,es
        add     ax,01000h
        mov     es,ax
        mov     ah,MAXSECTORS
        jmp     FatLoop

;++
;
; NextFatEntry - This procedure returns the next cluster in the FAT chain.
;                It will deal with both 12-bit and 16-bit FATs.  It assumes
;                that the entire FAT has been loaded into memory.
;
; Arguments:
;    (dx)   = current cluster number
;    (fs:0) = start of FAT in memory
;    (gs:0) = start of second 64k of FAT in memory
;
; Returns:
;    (dx)   = next cluster number in FAT chain
;    (dx)   = 0ffffh if there are no more clusters in the chain
;
;--
NextFatEntry    proc    near
        push    bx

;
; Check to see if this is a 12-bit or 16-bit FAT.  The biggest FAT we can
; have for a 12-bit FAT is 4080 clusters.  This is 6120 bytes, or just under
; 12 sectors.
;
; A 16-bit FAT that\'s 12 sectors long would only hold 3072 clusters.  Thus,
; we compare the number of FAT sectors to 12.  If it\'s greater than 12, we
; have a 16-bit FAT.  If it\'s less than or equal to 12, we have a 12-bit FAT.
;
        call    IsFat12
        jnc     Next16Fat

Next12Fat:
        mov     bx,dx                   ; (fs:bx) => temporary index
        shr     dx,1                    ; (dx) = offset/2
                                        ; (CY) = 1  need to shift
        pushf                           ;      = 0  don\'t need to shift
        add     bx,dx                   ; (fs:bx) => next cluster number
.386
        mov     dx,fs:[bx]              ; (dx) = next cluster number
.8086
        popf
        jc      shift                   ; carry flag tells us whether to
        and     dx,0fffh                ; mask
        jmp     short N12Tail
shift:
.386
        shr     dx,4                    ; or shift
.8086

N12Tail:
;
; Check for end of file
;
        cmp     dx,0ff8h                ; If we\'re at the end of the file,
        jb      NfeDone                 ; convert to canonical EOF.
        mov     dx,0ffffh
        jmp     short NfeDone

Next16Fat:
        add     dx,dx                   ; (dx) = offset
        jc      N16high

        mov     bx,dx                   ; (fs:bx) => next cluster number
.386
        mov     dx,fs:[bx]              ; (dx) = next cluster number
.8086
        jmp     short N16Tail

N16high:
        mov     bx,dx
.386
        mov     dx,gs:[bx]
.8086

N16Tail:
        cmp     dx,0fff8h
        jb      NfeDone
        mov     dx,0ffffh               ; If we\'re at the end of the file
                                        ; convert to canonical EOF.

NfeDone:
        pop     bx
        ret
NextFatEntry    endp

;++
;
; IsFat12 - This function determines whether the BPB describes a 12-bit
;           or 16-bit FAT.
;
; Arguments - ds:si supplies pointer to BPB
;
; Returns
;       CY set -   12-bit FAT
;       CY clear - 16-bit FAT
;
;--
IsFat12 proc    near

.386
        push    eax
        push    ebx
        push    ecx
        push    edx

        movzx   ecx, ds:[si].Sectors
        or      cx,cx
        jnz     if10
        mov     ecx, ds:[si].SectorsLong
if10:
;
; (ecx) = number of sectors
;
        movzx   ebx, byte ptr ds:[si].Fats
        movzx   eax, word ptr ds:[si].FatSectors
        mul     ebx
        sub     ecx,eax

;
; (ecx) = (#sectors)-(sectors in FATs)
;
        movzx   eax, word ptr ds:[si].DirectoryEntries
        shl     eax, 5
;
; (eax) = #bytes in root dir
;
        mov     edx,eax
        and     edx,0ffff0000h
        div     word ptr ds:[si].BytesPerSector
        sub     ecx,eax

;
; (ecx) = (#sectors) - (sectors in fat) - (sectors in root dir)
;
        movzx   eax, word ptr ds:[si].ReservedSectors
        sub     ecx, eax
        mov     eax, ecx
        movzx   ecx, byte ptr ds:[si].SectorsPerCluster
        xor     edx,edx
        div     ecx

        cmp     eax, 4087
        jae     if20
        stc
        jmp     short if30
if20:
        clc
if30:
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
        ret
.8086
IsFat12 endp




PrintDbg       proc    near
        push    ax
        push    bx
        push    cx

        mov     cx,4
pd10:
.386
        rol     dx,4
.8086
        mov     ah,0eh
        mov     bx,7
        mov     al,dl
        and     al,0fh
        add     al,\'0\'
        cmp     al,\'9\'
        jbe     pd15
        add     al,\'A\'-(\'9\'+1)

pd15:
        int     010h
        loop    pd10

        mov     ah,0eh
        mov     al,\' \'
        mov     bx,7
        int     010h
        pop     cx
        pop     bx
        pop     ax

        ret

PrintDbg      endp




Free    EQU     512-($-Start)
if Free lt 0
        %out FATAL PROBLEM: FAT-specific startup code is greater than
        %out 512 bytes.  Fix it!
        .err
endif

RealStart:
.386p
;
; Compute the paragraph needed for DS
;
if 0
        mov     ax,0
        int     16h
endif

        mov     bx,offset _TEXT:DGROUP  ; first calculate offset to data
        shr     bx,4                       ; must be para aligned

        mov     ax,cs                   ; get base of code
        add     ax,bx                   ; add paragraph offset to data

        mov      ss,ax                      ; ints disabled for next instruct
        mov      sp,offset DGROUP:SuStack   ; (sp) = top of internal stack
;
; Build C stack frame for _SuMain
;
        xor     dh,dh
        push    dx                      ; pass bootdisk (dl) to main.
        push    ds                      ; segment of bios parameter block
        push    si                         ; offset to bios parameter block
        push    es                         ; segment of root directory
        push    di                         ; offset to root directory
;
; Make DS point to the paragraph address of DGROUP
;
        mov     ds,ax                   ; ds now points to beginning of DGROUP
;
; Compute the physical address of the end of the data segment (which
; will be the beginning of the prepended loader file).
;

        movzx    edx,ax
        shl      edx,4
        add      edx,offset DGROUP:_edata
        mov      dword ptr _FileStart,edx

;
; Force the upper parts of
; of EBP and ESP to be zero in real mode.
;

        xor      bp,bp
        movzx    ebp,bp
        movzx    esp,sp
        mov      [saveDS],ds

        call    _SuMain                 ; go to C code to do everything else.


;++
; _EnableProtectPaging
;
; Loads 386 protect mode registers.
; Enables 386 protection h/w
; Loads pagings registers
; Enables 386 paging h/w
;
;--

public _EnableProtectPaging
_EnableProtectPaging  proc near
;
; Sanitize ES and GS and clean out any junk in the upper 16bits
; of the flags that may have been left by the bios, before we go protected
;
        push     dword ptr 0
        popfd
        mov      bx,sp
        mov      dx,[bx+2]  ; are we enabling prot/paging for the first time?
        xor      ax,ax
        mov      gs,ax
        mov      es,ax


;
; FS must contain the selector of the PCR when we call the kernel
;
        push    PCR_Selector
        pop     fs
;
; Load the gdtr and idtr.
; We disable interrupts here since we can\'t handle interrups with the
; idt loaded while were in real mode and before we switch to protmode.

        cli
        lgdt     fword ptr [_GDTregister]
        lidt     fword ptr [_IDTregister]


;
; We have to stamp the segment portion of any real-mode far pointer with
; the corresponding selector values before we go protected.
;
        mov      si,offset _ScreenStart
        mov      word ptr [si+2],VideoSelector
        mov      si,offset _vp
        mov      word ptr [si+2],VideoSelector

;
; Enable protect and paging mode
;
        mov      eax,cr0

; If we\'re enabling protect mode for the first time, don\'t turn on paging
; because the osloader does all that.  However, if we\'re returning to
; protected mode, the page tables are already setup, therefore we do want
; to turn paging on.
        or      dx,dx
        jz      only_prot
        or      eax,PROT_MODE + ENABLE_PAGING
        mov     cr0,eax

;
; The following JMP must be DWORD-aligned in order to avoid an obscure i386
; hardware bug.  If not, it is possible (albeit unlikely) that the prefetch
; queue can get trashed.
;

ALIGN 4
        jmp     flush


only_prot:
        or       eax,PROT_MODE
        mov      cr0,eax
;
; Flush the prefetch queue
;

ALIGN 4
        jmp     flush
flush:


;
; Load CS with the SU module\'s code selector
;
        push    SuCodeSelector
        push    offset cs:restart
        retf
;
; Now load DS and SS with the SU module\'s protect mode data selector.
;

restart:
        mov      ax,SuDataSelector
        mov      ds,ax
        mov      ss,ax

;
; Load LDT with zero since it will never be used.
;
        xor      bx,bx
        lldt     bx

;
; Load the Task Register and return to the boot SU module.
;
        or       dx,dx
        jnz      epp10


        mov      bx,TSS_Selector
        ltr      bx


epp10:
        ret

_EnableProtectPaging endp

.286p
;** _biosint
;
;   Rom bios interrupt dispatcher
;

public _biosint
_biosint proc    near

        enter   0,0
        push    di
        push    si
        push    ds
        push    es

;       Get pointer to register parameter frame

        les     di,[bp+4]

;       Get requested interrupt number

        mov     ax,es:[di].intnum

;       Check that requested bios interrupt is supported

        sub     ax,10h          ; sub lowest int number supported
        jnc     short bios1
        mov     es:[di].intnum,FUNCTION_ERROR
        jmp     short biosx
bios1:
        shl     ax,1            ; shift if to make it a word offset
        cmp     ax,bios_cnt     ; offset beyond end of table?
        jb      short bios2

;       Error: requested interrupt not supported

        mov     es:[di].sax,FUNCTION_ERROR
        jmp     short biosx

bios2:  mov     bx,ax
        mov     ax,word ptr cs:bios_table[bx]
        push    es              ; save seg of address frame
        push    di              ; save stack register frame pointer
        push    ax              ; address of bios int

        mov     ax,es:[di].sax
        mov     bx,es:[di].sbx
        mov     cx,es:[di].scx
        mov     dx,es:[di].sdx
        mov     si,es:[di].ssi
        mov     es,es:[di].ses
        ret                     ; this sends us to the \"int #\" instruction

;       We return here from the jmp instruction following the int

bios_ret:

        pop     di              ; get address of register parameter frame
        pop     es              ; restore segment of parameter frame


bios5:  pushf
        pop     es:[di].sfg
        mov     es:[di].sax,ax
        mov     es:[di].sbx,bx
        mov     es:[di].scx,cx
        mov     es:[di].sdx,dx
        mov     es:[di].ssi,si
        mov     es:[di].ses,es

;       Restore original registers and return to caller

biosx:
        pop     es
        pop     ds
        pop     si
        pop     di
        leave
        ret

_biosint endp

;** Bios Interrupt Table
;


bios10: int     10h
        jmp     short bios_ret
bios11: int     11h
        jmp     short bios_ret
bios12: int     12h
        jmp     short bios_ret
bios13: int     13h
        jmp     short bios_ret
bios14: int     14h
        jmp     short bios_ret
bios15: int     15h
        jmp     short bios_ret
bios16: int     16h
        jmp     short bios_ret
bios17: int     17h
        jmp     short bios_ret
bios18: int     18h
        jmp     short bios_ret
bios19: int     19h
        jmp     short bios_ret

bios_table dw      bios10,bios11,bios12,bios13,bios14,bios15,bios16,bios17,bios18,bios19

bios_cnt        equ     $ - bios_table

.386p

;++
;
; _MoveMemory
;
; Routine Description
;
;       Moves dwords in memory from source to destination.
;
; Arguments
;
;       (TOS+4)  =  number of bytes to move
;       (TOS+8)  =  linear address of destination
;       (TOS+12) =  linear address of source
;
; Notes
;
;   1)  Valid page table entries must already exist for the
;       source and destination memory.
;
;   2)  ALL memory in the lower one megabyte is assumed to
;       be identity mapped if used.
;
; USES  ESI, EDI, ECX, FLAGS
;
;
;--


public _MoveMemory
_MoveMemory proc near

        enter    0,0
        push     ds
        push     es
;
; Get source, destination, and count arguments from the stack
; Make \"count\" the number of dwords to move.
;

        mov      esi,dword ptr [bp+4]
        mov      edi,dword ptr [bp+8]
        mov      ecx,dword ptr [bp+12]
        shr      ecx,2

;
; Load FLAT selectors into DS and ES
;

        mov      ax,KeDataSelector
        mov      ds,ax
        mov      es,ax

;
; Move the block of data.
;
assume es:FLAT, ds:FLAT

;
; move the dwords
;
        cld
        rep     movs    dword ptr [edi],dword ptr [esi]

;
; move the remaining tail
;
        mov     ecx, dword ptr [bp+12]
        and     ecx, 3
        rep     movs    byte ptr [edi],byte ptr [esi]


assume es:nothing, ds:DGROUP

        pop      es
        pop      ds
        leave
        ret

_MoveMemory endp



;++
;
; _ZeroMemory
;
; Routine Description
;
;       Writes zeros into memory at the target address.
;
; Arguments
;
;       (TOS+4)  =  linear address of target
;       (TOS+8)  =  number of bytes to zero
;
; Notes
;
;   1)  Valid page table entries must already exist for the
;       source and destination memory.
;
;   2)  ALL memory in the lower one megabyte is assumed to
;       be identity mapped if used.
;
; USES  ESI, EDI, ECX, FLAGS
;
;
;--

public _ZeroMemory
_ZeroMemory proc near


        enter    0,0
        push     es
;
; Get source, destination, and count arguments from the stack
; Make \"count\" the number of dwords to move.
;

        mov      edi,dword ptr [bp+4]
        mov      ecx,dword ptr [bp+8]
        shr      ecx,2

;
; Load FLAT selectors into DS and ES
;

        mov      ax,KeDataSelector
        mov      es,ax
        xor      eax,eax

;
; Zero the the block of data.
;
assume es:FLAT

;
; Zero the dwords
;
        cld
        rep     stos    dword ptr [edi]

;
; Zero the remaining bytes
;
        mov     ecx, dword ptr [bp+8]
        and     ecx, 3
        rep     stos    byte ptr [edi]

assume es:nothing, ds:DGROUP

        pop      es
        leave
        ret


_ZeroMemory endp




;++
;
; Turn Floppy Drive Motor Off
;
;--

public _TurnMotorOff
DriveControlRegister      equ      3f2h     ; Floppy control register

_TurnMotorOff proc near

        mov      dx,DriveControlRegister
        mov      ax,0CH
        out      dx,al
        ret

_TurnMotorOff endp


;
; Note: we do not save and restore the gdt and idt values because they
; cannot change while external services are being used by the OS loader.
; This is because they MUST remain identity mapped until all mode
; switching has ceased.
;

public _RealMode
_RealMode proc near

;
; Switch to real-mode
;

        sgdt     fword ptr [_GDTregister]
        sidt     fword ptr [_IDTregister]
        push     [saveDS]          ; push this so we can get to it later
        mov      ax,SuDataSelector
        mov      es,ax
        mov      fs,ax
        mov      gs,ax

        mov      eax,cr0
        and      eax, not (ENABLE_PAGING + PROT_MODE)
        mov      cr0,eax

;
; flush the pipeline
;
        jmp     far ptr here
here:

;
; Flush TLB
;

; HACKHACK - We don\'t know where the page directory is, since it was
;       allocated in the osloader.  So we don\'t want to clear out cr3,
;       but we DO want to flush the TLB....
;
        mov     eax,cr3

        nop                             ; Fill - Ensure 13 non-page split
        nop                             ; accesses before CR3 load
        nop                             ; (P6 errata #11 stepping B0)
        nop

        mov     cr3,eax
;
; switch to real mode addressing
;
; N. B. We need to do a far jump rather than a retf, because a retf will not
;       reset the access rights to CS properly.
;
        db      0EAh                    ; JMP FAR PTR
        dw      offset _TEXT:rmode      ; 2000:rmode
        dw      02000h
rmode:
        pop      ax
        mov      ds,ax
        mov      ss,ax
;
; Stamp video pointers for real-mode use
;
        mov     si,offset _ScreenStart
        mov     word ptr [si+2],0b800h
        mov     si,offset _vp
        mov     word ptr [si+2],0b800h
;
; re-enable interrups
;
        lidt    fword ptr [_IDTregisterZero]

;
; Re-enable interrupts
;

        sti
        ret

_RealMode endp








;** _TransferToLoader  - transfer control the the OS loader
;
;
;  Arguments:
;
;       None
;
;  Returns:
;
;       Does not return
;
;**

public _TransferToLoader
_TransferToLoader proc near

;  generates a double fault for debug purposes
;        mov      sp,0
;        push 0

        mov      ebx,dword ptr [esp+2]      ; get entrypoint arg
        xor      eax,eax
        mov      ax,[saveDS]

;
; Setup OS loader\'s stack. Compute FLAT model esp to id map to
; original stack.
;
        mov      cx,KeDataSelector
        mov      ss,cx
        mov      esp,LOADER_STACK  ;** TMP HACK *** BUGBUG BUGBUG
;
; Load ds and es with kernel\'s data selectors
;

        mov      ds,cx
        mov      es,cx

;
; Setup pointer to file system and boot context records
;
; Make a linear pointer to the Boot Context Record

        shl      eax,4
        xor      ecx,ecx
        mov      cx,offset _BootRecord
        add      eax,ecx
        push     eax

        push     1010h       ; dummy return address.
        push     1010h       ; dummy return address.

;
; Push 48bit address of loader entry-point
;
        db OVERRIDE
        push    KeCodeSelector
        push    ebx

;
; Pass control to the OS loader
;
        db OVERRIDE
        retf

_TransferToLoader endp




;++
; Description:
;
;       Gets memory block sizes for memory from zero to one meg and
;       from one meg to 64 meg. We do this by calling int 12h
;       (get conventional memory size) and int 15h function 88h (get
;       extended memory size).
;
; Arguments:
;
;       None
;
; Returns:
;
;       USHORT - Size of usable memory (in pages)
;
;--

public _IsaConstructMemoryDescriptors
BmlTotal        equ     [bp-4]
Func88Result    equ     [bp-6]
_IsaConstructMemoryDescriptors proc near
        push    bp                     ; save ebp
        mov     bp, sp
        sub     sp, 6
;
; Initialize the MemoryList to start with a zero entry.  (end-of-list)
;
        les     si, dword ptr _MemoryDescriptorList
        xor     eax,eax
        mov     es:[si].BlockSize,eax
        mov     es:[si].BlockBase,eax

;
; Get conventional (below one meg) memory size
;
        push    es
        push    si
        int     12h
        movzx   eax,ax
;
; EAX is the number of 1k blocks, which we need to convert to the
; number of bytes.
;
        shl     eax,10

        push    eax
        shr     eax, 12
        mov     BmlTotal, eax
        xor     eax,eax
        push    eax
        call    _InsertDescriptor
        add     sp,8

;
; Get extended memory size and fill-in the second descriptor
;

        mov     ah,88h

        int     15h

        mov     Func88Result,ax
        and     eax,0ffffh

;
; EAX is the number of 1k blocks, which we need to convert to the
; number of bytes.
;
        shl     eax,10
        push    eax
        shr     eax,12
        add     BmlTotal, ax
        mov     eax,0100000h
        push    eax
        call    _InsertDescriptor
        add     sp,8

;
; Try function E801, see if that is supported on this machine
;
        mov     ax,0E801h
        int     15h
        jc      short Isa50

        cmp     ax,Func88Result     ; Is extended memory same as 88?
        je      short Isa40         ; Yes, go add the rest

        cmp     ax, (16-1) * 1024   ; Is extended memory exactly 16MB?
        jne     short Isa50         ; No, conflict between 88 & E801

Isa40:
;
; Function looks like it worked
;
; AX = extended memory < 16M in 1k blocks
; BX = extended memory > 16M in 64k blocks
;
        and     ebx,0ffffh
        jz      short Isa50

        shl     ebx,16              ; ebx = memory > 16M in bytes (via E801)
        add     ebx, 16*1024*1024   ; ebx = end of memory in bytes (via E801)

        mov     ax, Func88Result
        and     eax,0ffffh
        shl     eax, 10             ; eax = memory > 1M in bytes (via 88)
        add     eax, 1*1024*1024    ; eax = end of memory in bytes (via 88)

        sub     ebx, eax            ; ebx = memory above eax
        jbe     short Isa50         ; if ebx <= eax, done

        push    ebx
        shr     ebx,12
        add     BmlTotal, bx
        push    eax
        call    _InsertDescriptor
        add     sp,8
        and     eax,0ffffh

Isa50:
        pop     si
        pop     es
        mov     eax, BmlTotal
        mov     sp, bp
        pop     bp
        ret

_IsaConstructMemoryDescriptors endp

;++
;
; BOOLEAN
; Int15E820 (
;     E820Frame     *Frame
;     );
;
;
; Description:
;
;       Gets address range descriptor by calling int 15 function E820h.
;
; Arguments:
;
; Returns:
;
;       BOOLEAN - failed or succeed.
;
;--

cmdpFrame       equ     [bp + 6]
public _Int15E820
_Int15E820 proc near

        push    ebp
        mov     bp, sp
        mov     bp, cmdpFrame           ; (bp) = Frame
        push    es
        push    edi
        push    esi
        push    ebx

        push    ss
        pop     es

        mov     ebx, [bp].Key
        mov     ecx, [bp].DescSize
        lea     di,  [bp].BaseAddrLow
        mov     eax, 0E820h
        mov     edx, \'SMAP\'             ; (edx) = signature

        INT     15h

        mov     [bp].Key, ebx           ; update callers ebx
        mov     [bp].DescSize, ecx      ; update callers size

        sbb     ecx, ecx                ; ecx = -1 if carry, else 0
        sub     eax, \'SMAP\'             ; eax = 0 if signature matched
        or      ecx, eax
        mov     [bp].ErrorFlag, ecx     ; return 0 or non-zero

        pop     ebx
        pop     esi
        pop     edi
        pop     es
        pop     ebp
        ret

_Int15E820 endp

_TEXT   ends

        end      Start

;***********************************************************
;++
;
; Module name
;
;       su.inc
;
; Author
;
;       Thomas Parslow  (tomp)  Mar-1-90
;
; Description
;
;       Include file for SU.ASM.
;
;
;--

.386

PAGE_SIZE               equ     1000h
MACHINE_TYPE_ISA        equ     0
MACHINE_TYPE_EISA       equ     1
MACHINE_TYPE_MCA        equ     2

;
; Define the segment:offset address pair of the location to
; load detection module.
; N.B. This definition *MUST* be the same as the ones defined
;      in ..\\constant.h
;

DETECTION_ADDRESS_SEG   equ     1000h
DETECTION_ADDRESS_OFFSET        equ     0

;
; Structure definitions and equates for INT 15 function E820
;

E820Frame struc
        ErrorFlag       dd      ?
        Key             dd      ?
        DescSize        dd      ?

        BaseAddrLow     dd      ?
        BaseAddrHigh    dd      ?
        SizeLow         dd      ?
        SizeHigh        dd      ?
        MemoryType      dd      ?
E820Frame ends

MemoryDescriptorFramePointer struc
        E820FramePointer    dd      ?
MemoryDescriptorFramePointer ends



;

BIOS_DISK_INTERRUPT     equ     13h
BIOS_READ_SECTOR        equ     2
IDT_ENTRIES             equ     100h

BIOS_KEYBOARD_INTERRUPT equ     16h

EXPORT_STACK            equ     07ffeh
RE_ENABLING             equ     1
LOADER_STACK            equ     061ffch

CR0_ET                  equ     10h

;
; Trap Number macro save eax on the stack and then pushes the
; number of the trap that\'s in progress.
;

TRAP_NUMBER      macro  num,addr
        IF num EQ 9
        push     eax  ; push place holder for error code
        ENDIF
        IF num LE 7
        push     eax  ; push place holder for error code
        ENDIF
        push     eax       ; save eax on stack first
        mov      eax,num
        push     eax
        jmp      addr
        endm

;;
;
; GetSector Stack Frame Structure
;
; Stack frame definition for GetSector call from OS loader
; to 16bit routines.
;
;;

GetSectorFrame          struc
        FunctionNumber  dd      ?
        DriveNumber     dd      ?
        HeadNumber      dd      ?
        TrackNumber     dd      ?
        SectorNumber    dd      ?
        NumberOfSectors dd      ?
        BufferPointer   dd      ?
GetSectorFrame          ends

;;
;
; GetEddsSector Stack Frame Structure
;
; Stack frame definition for GetEddsSector call from OS loader
; to 16bit routines.
;
;;

GetEddsSectorFrame      struc
        DriveNum        dd      ?
        LBNLow          dd      ?
        LBNHigh         dd      ?
        NumberOfBlocks  dd      ?
        BufPointer      dd      ?
GetEddsSectorFrame      ends

RebootFrame             struc
        BootType        dd      ?
RebootFrame             ends

;
; ABIOS services Stack Frame Structure
;
; Stack frame definition for ABIOS services call from OS loader
; to 16 bit routine.
;

AbiosServicesFrame      struc
        AbiosFunction   dd      ?
        CommonDataArea  dd      ?
        InitTable       dd      ?
        RamExtension    dd      ?
        AbiosRoutine    dd      ?
        LogicalId       dd      ?
        NumberLids      dd      ?
AbiosServicesFrame      ends

;
; Hardware detection frame structure
;
; Stack frame definition for DetectHardware call from OS loader
; to 16 bit routine.
;

DetectionFrame          struc
        HeapStart       dd      ?
        HeapSize        dd      ?
        ConfigTree      dd      ?
        HeapUsed        dd      ?
        LoadOptions     dd      ?
        OptionsLength   dd      ?
DetectionFrame          ends

;
; HardwareCursor Stack Frame Structure
;
; Stack frame definition for HardwareCursor call from OS loader
; to 16 bit routine.
;

HardwareCursorFrame     struc
        XCoord          dd      ?
        YCoord          dd      ?
HardwareCursorFrame     ends

;
; GetDateTime Stack Frame Structure
;
; Stack frame definition for GetDateTime call from OS loader
; to 16 bit routine.
;

GetDateTimeFrame        struc
        DateDword       dd      ?
        TimeDword       dd      ?
GetDateTimeFrame        ends


;
; ComPort Stack Frame Structure
;
; Stack frame definition for ComPort call from OS loader
; to 16 bit routine.
;

ComPortFrame            struc
        ComPortPort     dd      ?
        ComPortFunction dd      ?
        ComPortArg      dd      ?
ComPortFrame            ends

;
; IsMcaMachine Stack Frame Structure
;
; Stack frame definition for IsMcaMachine call from OS loader
; to 16 bit routine.
;

IsMcaMachineFrame       struc
        Dummy           dd      ?
IsMcaMachineFrame       ends

;;
;
; GetElToritoStatus Stack Frame Structure
;
; Stack frame definition for GetElToritoStatus call from OS loader
; to 16bit routines.
;
;;

GetElToritoStatusFrame     struc
        SpecPacketPointer  dd      ?
        ETDriveNum         dd      ?
GetElToritoStatusFrame     ends

;;
;
; Memory Descriptor Structure.
;
; Passed to OS loader as part of the boot context record
;
;;

MemoryDescriptor struc
        BlockBase       dd              ?
        BlockSize       dd              ?
MemoryDescriptor ends

;;
;
; File System Context Record Structure
;
;;

FsContextRecord struc
        BootDrive       dd              ?
        PointerToBpb    dd              ?
        Reserved        dd              ?
FsContextRecord ends

;;
;
; IDT Descriptor Structure
;
;;

TrapDesc        struc
        IDT_offset      dw              ?
        IDT_selector    dw              ?
        IDT_attribute   dw              ?
        IDT_reserved    dw              ?
TrapDesc        ends

;;
;
; GDT Descriptor Structure ;;
;
;;

GDTDesc         struc
        GDT_limit       dw              0
        GDT_base1       dw              0
        GDT_base2       db              0
        GDT_access      db              0
        GDT_limacc      db              0
        GDT_base3       db              0
GDTDesc         ends


;;
;
; GDT Selector Definitions
;
;;

NULL_Selector           equ     0h
KeCodeSelector          equ     8h
KeDataSelector          equ     10h
UsCodeSelector          equ     18h
UsDataSelector          equ     20h
TSS_Selector            equ     28h
PCR_Selector            equ     30h
TEP_Selector            equ     38h
BDA_Selector            equ     40h
KeLdtSelector           equ     48h
DblFltTskSelector       equ     50h
SuCodeSelector          equ     58h
SuDataSelector          equ     60h
VideoSelector           equ     68h
GDT_AliasSelector       equ     70h
DbCodeSelector          equ     78h
DbDataSelector          equ     80h
DebugUseSelector        equ    88h
ReservedSelector        equ    90h

;;
;
; Exception Frame Structure
; Note, this absolutely must match the corresponding structure
; defined in \"types.h\"
;
;;

ExceptionFrame struc
        Ftr     dw       0
        Fdr6    dd       0
        Fcr0    dd       0
        Fcr2    dd       0
        Fcr3    dd       0
        Fss     dw       0
        Fgs     dw       0
        Ffs     dw       0
        Fes     dw       0
        Fds     dw       0
        Fedi    dd       0
        Fesi    dd       0
        Febp    dd       0
        Fesp    dd       0
        Febx    dd       0
        Fedx    dd       0
        Fecx    dd       0
        TrapNum dd       0
        Feax    dd       0
        Error   dd       0
        Feip    dd       0
        Fcs     dd       0
        Feflags dd       0
ExceptionFrame  ends


tFsContext struc
        dw      0
tFsContext ends



tBootContext struc
        dd       0
        dd       0
tBootContext ends




FUNCTION_ERROR  equ     -1

;;
;
; Register Frame Structure
;
; For bios int calls
;
;;

reg_frame struc
        intnum  dw      ?
        sfg     dw      ?
        sax     dw      ?
        sbx     dw      ?
        scx     dw      ?
        sdx     dw      ?
        ssi     dw      ?
        ses     dw      ?
reg_frame ends


;;
;; Processor Flags
;;

PROT_MODE               equ     000000001       ; Enable protect mode operation
ENABLE_PAGING           equ     80000000h       ; Enable paging hardware
PD_PHYSICAL_ADDRESS     equ     99000h
TSS_SIZE                equ     80h
OVERRIDE                equ     66h

;
; Operand and Address size overrides
;

OPSIZE          macro
                db 66h
                endm
ADSIZE          macro
                db 67h
                endm


;
; External Procedures for SUDATA.ASM
;

IFDEF SU_CODEMODULE
extrn _SuMain:near
extrn _ScreenStart:near
extrn _vp:near
extrn _putx:near
extrn _TrapHandler:near
extrn _GDTregister:fword
extrn _IDTregister:fword
extrn _IDTregisterZero:fword
extrn saveDS:word
extrn SuStack:word
extrn _edata:word
extrn _FileStart:dword
ENDIF



;
; External Procedures for SUDATA.ASM
;

IFDEF SU_DATAMODULE
extrn  Trap0:far
extrn  Trap1:far
extrn  Trap2:far
extrn  Trap3:far
extrn  Trap4:far
extrn  Trap5:far
extrn  Trap6:far
extrn  Trap7:far
extrn  Trap8:far
extrn  Trap9:far
extrn  TrapA:far
extrn  TrapB:far
extrn  TrapC:far
extrn  TrapD:far
extrn  TrapE:far
extrn  TrapF:far
extrn  _edata:near
ENDIF



;
; Segment declarations for \"Small Model\" 16 bit Su Module.
;

_TEXT   segment para use16 public \'CODE\'
_TEXT   ends

_DATA   segment para use16 public \'DATA\'
_DATA   ends

CONST   segment para use16 public \'CONST\'
CONST   ends

_BSS    segment para use16 public \'BSS\'
_BSS    ends

DGROUP  group   const, _BSS, _DATA


;;; END OF FILE ;;;

;********************************************************
;++
;
; File Name:
;
;       macro.inc
;
; Author:
;
;       Thomas Parslow [tomp]
;
; Created:
;
;       27-Feb-91
;
; Abstract:
;
;       The macros used for creating the exported entry points the
;       OS loader will use for basic h/w dependent services. These
;       services are:
;
;       o       Disk I/O
;       o       Character I/O
;
;
;--


;++
;
; EXPORT_ENTRY_MACRO
; We arrive here from the OS loader with a 32bit CS. That is, we\'re
; executing the code with cs:eip where cs contains a selector for a
; 32bit flat segment. We want to get to a 16bit cs. That is, cs:ip.
; The entry points are exported as 32bit near pointers to the OS loader.
; All code in the SU module is identity mapped so the flat 32bit offset
; is equal to the physical address.
;
; Therefore, we export the 32bit physical address as the
; entry point and the code may be executed with either the 32bit
; flat cs or the SU module\'s 16bit based cs.  Before we can switch
; modes we must load all of the segment registers with selectors for
; 16bit segments.  We start by pushing a far pointer to a label in
; the macro and then doing a retf. This allows us to fall through
; to the next instruction, but we\'re now executing through cs:ip
; with a 16bit CS.
;
; Output:
;
;       (ebx) = pointer to stack frame (and top of 32bit stack).
;

EXPORT_ENTRY_MACRO  macro entryname
        LOCAL    exp1
_TEXT32 segment para use32 public \'CODE\'
        ASSUME CS:_TEXT32
ALIGN 4
Public  EntryName
EntryName LABEL near
;
; We\'ve go a 32bit CS:EIP - go to a 16bit CS:IP

        push     dword ptr SuCodeSelector
        push     dword ptr (offset exp1)

        retf
_TEXT32 ends
        ASSUME CS:_TEXT
ALIGN 4
exp1:
;
; Save caller\'s EBP register and stack pointer (ESP)
;

        push     ebp
        push     ebx
        push     esi
        push     edi
        mov      ebx,esp
;
; Load all the segment registers with 16bit segment selectors
;
        mov      ax,SuDataSelector
        mov      ds,ax
        mov      ss,ax
;
; Set the stack to the top of the segment. We can do this now since
; all of the OS loader\'s code has already be relocated. Also, we need
; plenty of stack since we\'ll be calling BIOS routines.
;
        mov      sp,EXPORT_STACK
        push     ebx                  ; save the caller\'s esp
        endm
;
; EXPORT_ENTRY_MACRO end
;



;++
;
; Name:
;
;       ExportExit
;
; Arguments:
;
;
; Notes:
;
;       EAX = return code and MUST be preserved by this macro.
;
;--

EXPORT_EXIT_MACRO macro
;
; Next get caller\'s esp that we saved upon entry on the 16bit stack
;
        pop      ebx                    ; get caller\'s esp
;
; Restore flat selectors in segment registers.
;
        mov      dx,KeDataSelector
        mov      ds,dx
        mov      ss,dx
        mov      es,dx
        mov      esp,ebx


;
; Restore callers\' ebp that we saved on the 32bit stack
;
        pop      edi
        pop      esi
        pop      ebx
        pop      ebp      ; (ebp) = caller\'s ebp

;
; Pull callers flat return address off stack and push the
; flat code selector followed by the return offset, then
; execute a far return and we\'ll be back in the OS loaders code space.
;
        pop      edx      ; (edx) = caller\'s return address
        push     dword ptr KeCodeSelector
        push     edx
        db OVERRIDE
        retf
        endm

;++
;
;
;
;--

RE_ENABLE_PAGING_MACRO macro
extrn _EnableProtectPaging:near
        push     RE_ENABLING
        call     _EnableProtectPaging
        add      sp,2
        endm

ENTER_REALMODE_MACRO macro
extrn _RealMode:near
        call    _RealMode
        endm



WAIT_FOREVER_MACRO macro
        LOCAL wf1
wf1:    jmp     wf1
        endm

;++
;
; MAKE_STACK_FRAME_MACRO
;
; Arguments:
;
;    _FrameName_ - is the name of the structure defining the
;                  stack frame layout.
;
;    _PointerRegister_ - is the register containing the linear pointer to
;                        the top of the stack frame.
; ProtectMode ONLY
;
;--

MAKE_STACK_FRAME_MACRO macro _FrameName_ , _PointerRegister_
Local msf1
        mov     ecx, (size _FrameName_)/2
        mov     esi,_PointerRegister_   ; (esi) = offset of argument frame
        add     esi,20                  ; account for ebp, ebx, esi, edi and
                                        ; return address
        push    KeDataSelector          ; (ax) = Flat 32bit segment selector
        pop     ds                      ; (ds:esi) points to argument frame
        push    ss                      ;
        pop     es                      ; (es) = 16bit stack selector
        sub     sp, size _FrameName_    ; make room for the arguments
        xor     edi,edi                 ; clear out upper 16bits of edi
        mov     di,sp                   ; (es:edi) points to top of stack
msf1:
        mov     ax,[esi]
        mov     es:[edi],ax
        add     esi,2
        add     edi,2
        loop    msf1
        push    es                      ;
        pop     ds                      ; put 16bit selector back into ds
        endm


REMOVE_STACK_FRAME_MACRO macro _FrameName_

        add     sp, size _FrameName_
        endm


;BuildDescriptor macro   Base,Limit,Access,Dpl,Stype
;        dw       (Limit AND 0ffffh)
;        dw       (Base AND 0ffffh)
;        db       ((Base SHR 16) AND 0ffh)
;        db       (Gran + Dpl + Stype)
;        db       ((Limit SHR 16) AND 0ffh)
;        db       ((Base SHR 24) AND 0ffh)
;        endm



;
;
;
RETURNCODE_IN_EAX_MACRO macro

        shl      edx,16
        mov      dx,ax
        mov      eax,edx
        endm
;以上代码为NTLDR的主框架。主要代码稍后发上来。
cheng
cheng_5103
驱动牛犊
驱动牛犊
  • 注册日期2003-10-06
  • 最后登录2012-03-21
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望228点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-04-22 17:43
哪位仁兄把英文注释翻译过来好吗?这源代码来自NT4源代码中一个字没改个,就是全英文的看不懂注释。可能我把这代码贴上来已经太晚了,大家也许都有了吧。但我只是想大家在这儿来一起分析讨论,都可以学习吗?这样分析起来也快一些。希望各位高手来此讨论!
代码太多了,我只能慢慢的组织出来。请大家原谅。
cheng
asmcat2000
驱动牛犊
驱动牛犊
  • 注册日期2004-05-16
  • 最后登录2010-06-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-04-23 11:41
这好象是装入ntldr的程序,ntldr那么大,这么点code也不对呀,
 似乎象是ntldr的头部。
fsfool
驱动牛犊
驱动牛犊
  • 注册日期2005-04-25
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分1分
  • 专家分0分
地板#
发布于:2005-04-26 00:22
这段代码主要完成给引导nt的程序定义一个入口点的作用,这段程序是所谓的nt自加载程序,计算出来的值实际上此时在DS和SS寄存器里;这段程序也为后面的程序提供bios功能的高程架构;另外一个重要的作用是提供将处理器由8086模式到保护的分页模式的代码转换,使用软件的方法屏蔽掉了Intel x86 处理器的分段机制,整个逻辑空间为一个连续的4GB空间(不扩展地址)再分页映射到虚拟的物理地址空间,nt实际上并不关心物理内存是多少。总之这是一段为加载ntlrd作软件和硬件准备的代码。应该是由BIOS加载后取得控制权的,它在加载了loader程序之后,向loader 交权,由loader分几步加载系统后再将控制交给系统。
你如由NT的原代码,应该将它在若干国内的网站上公开,且在公开之前你要提前一个月公告天下,这样才可以引发下载狂潮,而你也将因此而名利双收。记住,自古是先有名而后有利,名扬则利至,希望你能把物机会!
;啊;;哦;女篮;哦吧哦;;;袄 啊’解放‘案件’ 'oip面积草案平均机不啊
qiweixue
驱动小牛
驱动小牛
  • 注册日期2004-07-21
  • 最后登录2011-12-19
  • 粉丝0
  • 关注0
  • 积分1006分
  • 威望274点
  • 贡献值0点
  • 好评度268点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2007-05-17 19:30
貌似还有个ntloader.exe吧
tyeken8
驱动牛犊
驱动牛犊
  • 注册日期2007-04-26
  • 最后登录2007-08-13
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-08-13 22:48
ntdetect.com吧?
Yuna X Forever
gandalf
驱动牛犊
驱动牛犊
  • 注册日期2005-11-11
  • 最后登录2009-04-16
  • 粉丝0
  • 关注0
  • 积分330分
  • 威望46点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-08-22 10:19
可以考虑参考一下 ReactOS 的 Freeldr 的代码。^_^
游客

返回顶部