VirtualBox

Ignore:
Timestamp:
Feb 7, 2020 1:13:23 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
136039
Message:

bs3kit: Tried to improove the load time in the boot sector.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-bootsector.asm

    r82968 r83018  
    3636%include "iprt/asmdefs.mac"
    3737%include "iprt/x86.mac"
     38
     39
     40;*********************************************************************************************************************************
     41;*      Defined Constants And Macros                                                                                             *
     42;*********************************************************************************************************************************
     43;; Enabled faster loading.
     44%define BS3KIT_BOOTSECTOR_FASTER_LOAD
     45;; Enabled load progress dots.
     46%define BS3KIT_BOOTSECTOR_LOAD_DOTS
    3847
    3948
     
    106115        ; save the registers.
    107116        mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rax], ax
    108         mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rsp], sp
    109         mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.ss], ss
    110117        mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.ds], ds
    111118
    112         ; set up the segment reisters and stack.
     119        ; set up the DS segment reister so we can skip the CS prefix when saving more prefixes..
    113120        mov     ax, 0
    114121        mov     ds, ax
     122
     123        mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi], di
     124        mov     di, BS3_ADDR_REG_SAVE
     125        mov     [di + BS3REGCTX.rsp], sp
     126        mov     [di + BS3REGCTX.ss], ss
     127        mov     [di + BS3REGCTX.rcx], cx
     128        mov     [di + BS3REGCTX.es], es
     129        mov     [di + BS3REGCTX.rbp], bp
     130
     131        ; set up the stack.
    115132        mov     ss, ax
    116133        mov     sp, BS3_ADDR_STACK
    117 
    118         ; Save more registers, without needing cs prefix.
    119         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rcx], cx
    120         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi], di
    121         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.es], es
    122         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rbp], bp
    123134
    124135        ; Load es and setup bp frame.
    125136        mov     es, ax
    126137        mov     bp, sp
     138%if 0
    127139        mov     [bp], ax                ; clear the first 8 bytes (terminates the ebp chain)
    128140        mov     [bp + 02h], ax
    129141        mov     [bp + 04h], ax
    130142        mov     [bp + 06h], ax
     143%else
     144        mov     di, sp                  ; Combine clearing the rbp chain and register save area.
     145%endif
    131146
    132147        ; Save flags now that we know that there's a valid stack.
     
    136151        ; Clear the register area.
    137152        ;
     153%if 0
    138154        mov     di, BS3_ADDR_REG_SAVE
    139155        mov     cx, BS3REGCTX_size/2
     156%else
     157        mov     cx, (BS3_ADDR_LOAD - BS3_ADDR_STACK) / 2
     158%endif
    140159        cld
    141160        rep stosw
     
    144163        ; Do basic CPU detection.
    145164        ;
     165
     166        ; 0. Load the register save area address into DI to avoid absolute addressing
     167        ;    when saving additional state.  To avoid disp16, offset the address.
     168        mov     di, BS3_ADDR_REG_SAVE + 0x70
    146169
    147170        ; 1. bit 15-bit was fixed to 1 in pre-286 CPUs, and fixed to 0 in 286+.
     
    162185.is_80286:
    163186CPU 286
    164         smsw    [BS3_ADDR_REG_SAVE + BS3REGCTX.cr0]
     187        smsw    [di + BS3REGCTX.cr0 - 0x70]
    165188.pre_80286:
    166189CPU 8086
    167         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rbx], bx
    168         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rdx], dx
    169         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rsi], si
     190        mov     [di - 0x70 + BS3REGCTX.rbx], bx
     191        mov     [di - 0x70 + BS3REGCTX.rdx], dx
     192        mov     [di - 0x70 + BS3REGCTX.rsi], si
    170193        jmp     .do_load
    171194
     
    174197.is_386plus:
    175198        shr     eax, 16
    176         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rax+2], ax
     199        mov     [di - 0x70 + BS3REGCTX.rax+2], ax
    177200        mov     eax, esp
    178201        shr     eax, 16
    179         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rsp+2], ax
     202        mov     [di - 0x70 + BS3REGCTX.rsp+2], ax
    180203        mov     eax, ebp
    181204        shr     eax, 16
    182         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rbp+2], ax
    183         shr     edi, 16
    184         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi+2], di
     205        mov     [di - 0x70 + BS3REGCTX.rbp+2], ax
     206        mov     eax, edi
     207        shr     eax, 16
     208        mov     [di - 0x70 + BS3REGCTX.rdi+2], ax
    185209        shr     ecx, 16
    186         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rcx+2], cx
    187         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.fs], fs
    188         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.gs], gs
    189         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rbx], ebx
    190         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rdx], edx
    191         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rsi], esi
     210        mov     [di - 0x70 + BS3REGCTX.rcx+2], cx
     211        mov     [di - 0x70 + BS3REGCTX.fs], fs
     212        mov     [di - 0x70 + BS3REGCTX.gs], gs
     213        mov     [di - 0x70 + BS3REGCTX.rbx], ebx
     214        mov     [di - 0x70 + BS3REGCTX.rdx], edx
     215        mov     [di - 0x70 + BS3REGCTX.rsi], esi
    192216        mov     eax, cr2
    193         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.cr2], eax
     217        mov     [di - 0x70 + BS3REGCTX.cr2], eax
    194218        mov     eax, cr3
    195         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.cr3], eax
    196         mov     byte [BS3_ADDR_REG_SAVE + BS3REGCTX.bMode], BS3_MODE_RM
    197         mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.cs], cs
     219        mov     [di - 0x70 + BS3REGCTX.cr3], eax
     220        mov     byte [di - 0x70 + BS3REGCTX.bMode], BS3_MODE_RM
     221        mov     [di - 0x70 + BS3REGCTX.cs], cs
    198222        xor     eax, eax
    199223        mov     ax, start
    200         mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rip], eax
     224        mov     [di - 0x70 + BS3REGCTX.rip], eax
    201225
    202226        ; Pentium/486+: CR4 requires VME/CPUID, so we need to detect that before accessing it.
    203         mov     [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.cr4], eax
     227        mov     [di - 0x70 + BS3REGCTX.cr4], eax
    204228        popf                            ; (restores IOPL+NT)
    205229        pushfd
    206230        pop     eax
    207         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.rflags], eax
     231        mov     [di - 0x70 + BS3REGCTX.rflags], eax
    208232        xor     eax, X86_EFL_ID
    209233        push    eax
     
    214238        jne     .no_cr4
    215239        mov     eax, cr4
    216         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.cr4], eax
     240        mov     [di - 0x70 + BS3REGCTX.cr4], eax
    217241.no_cr4:
    218242        ; Make sure caching is enabled and alignment is off.
    219243        mov     eax, cr0
    220         mov     [BS3_ADDR_REG_SAVE + BS3REGCTX.cr0], eax
     244        mov     [di - 0x70 + BS3REGCTX.cr0], eax
    221245        and     eax, ~(X86_CR0_NW | X86_CR0_CD | X86_CR0_AM)
    222246        mov     cr0, eax
     
    284308        push    dx
    285309%define bMaxSector      byte [bp - 06h]
     310%define wMaxSector      word [bp - 06h]
    286311        xor     ax, ax
    287312        push    ax
     
    302327        mov     dl, bSavedDiskNo
    303328
    304         ;
    305         ; Reload all the sectors one at a time (avoids problems).
     329%if 0 ; bMaxSector=0x12 (18); bMaxHead=0x01; bMaxCylinder=0x4f (79)
     330        mov al, 'S'
     331        call bs3PrintChrInAl
     332        mov al, bMaxSector
     333        call bs3PrintHexInAl
     334        mov al, 'H'
     335        call bs3PrintChrInAl
     336        mov al, bMaxHead
     337        call bs3PrintHexInAl
     338        mov al, 'C'
     339        call bs3PrintChrInAl
     340        mov al, bMaxCylinder
     341        call bs3PrintHexInAl
     342        mov al, ';'
     343        call bs3PrintChrInAl
     344%endif
     345
     346%ifndef BS3KIT_BOOTSECTOR_FASTER_LOAD
     347        ;
     348        ; Load the sectors following the boot sector one at a time (avoids problems).
    306349        ;
    307350        mov     si, [g_cLargeTotalSectors] ; 16-bit sector count ==> max 512 * 65 535 = 33 553 920 bytes.
    308         dec     si
     351        dec     si                       ; Practically max: ca 575 KB, or 1150 sectors.  Linker set BS3_MAX_SIZE to 480KB.
     352
    309353        mov     di, BS3_ADDR_LOAD / 16  ; The current load segment.
    310354        mov     cx, 0002h               ; ch/cylinder=0 (0-based); cl/sector=2 (1-based)
    311355        xor     dh, dh                  ; dh/head=0
    312356.the_load_loop:
    313 %if 0
     357 %if 0
    314358        mov al, 'c'
    315359        call bs3PrintChrInAl
     
    326370        mov al, ';'
    327371        call bs3PrintChrInAl
    328 %endif
     372 %elifdef BS3KIT_BOOTSECTOR_LOAD_DOTS
     373        mov     al, '.'
     374        call bs3PrintChrInAl
     375 %endif
    329376        xor     bx, bx
    330377        mov     es, di                  ; es:bx -> buffer
     
    350397        dec     si
    351398        jnz     .the_load_loop
     399
     400%else ; BS3KIT_BOOTSECTOR_FASTER_LOAD
     401        ;
     402        ; Load the sectors following the boot sector, trying to load a whole
     403        ; side in each bios call, falling back on single sector reads if we
     404        ; run into DMA 64KB boundrary issues (BIOS must tell us).
     405        ;
     406        mov     si, [g_cLargeTotalSectors] ; 16-bit sector count ==> max 512 * 65 535 = 33 553 920 bytes.
     407        dec     si                      ; Skip the boot sector, it's not part of the test image we execute.
     408        mov     di, BS3_ADDR_LOAD / 16  ; The current load segment.
     409        mov     cx, 0002h               ; ch/cylinder=0 (0-based); cl/sector=0 (1-based)
     410        xor     dh, dh                  ; dh/head=0
     411.the_load_loop:
     412 %if 0
     413        mov al, 'c'
     414        call bs3PrintChrInAl
     415        mov al, ch
     416        call bs3PrintHexInAl
     417        mov al, 's'
     418        call bs3PrintChrInAl
     419        mov al, cl
     420        call bs3PrintHexInAl
     421        mov al, 'h'
     422        call bs3PrintChrInAl
     423        mov al, dh
     424        call bs3PrintHexInAl
     425        mov al, ';'
     426        call bs3PrintChrInAl
     427 %elifdef BS3KIT_BOOTSECTOR_LOAD_DOTS
     428        mov     al, '.'
     429        call bs3PrintChrInAl
     430 %endif
     431        mov     ax, wMaxSector          ; read to the end of the side by default.
     432        sub     al, cl
     433        inc     al
     434.read_again:
     435        cmp     si, ax
     436        jae     .do_read
     437        mov     ax, si
     438.do_read:
     439        mov     ah, 02h                 ; ah=read function
     440        xor     bx, bx
     441        mov     es, di                  ; es:bx -> buffer
     442        int     13h
     443        jnc     .advance_sector
     444
     445        cmp     ah, 9                   ; DMA 64KB crossing error
     446        jne     .failure
     447        mov     ax, 1                   ; Retry reading a single sector.
     448        jmp .read_again
     449
     450        ; advance to the next sector/head/cylinder and address.
     451.advance_sector:
     452        inc     cl
     453        cmp     cl, bMaxSector
     454        jbe     .adv_addr
     455
     456        mov     cl, 1
     457        inc     dh
     458        cmp     dh, bMaxHead
     459        jbe     .adv_addr
     460
     461        mov     dh, 0
     462        inc     ch
     463
     464.adv_addr:
     465        dec     si
     466        jz      .done_reading
     467        add     di, 512 / 16
     468        dec     al
     469        jnz     .advance_sector
     470        jmp     .the_load_loop
     471
     472.done_reading:
     473%endif ; BS3KIT_BOOTSECTOR_FASTER_LOAD
    352474%if 0
    353475        mov     al, 'D'
     476        call bs3PrintChrInAl
     477%elifdef BS3KIT_BOOTSECTOR_LOAD_DOTS
     478        mov     al, 13
     479        call bs3PrintChrInAl
     480        mov     al, 10
    354481        call bs3PrintChrInAl
    355482%endif
     
    365492        ;
    366493.failure:
     494%if 1
     495        hlt
     496        jmp .failure
     497%else
    367498        push    ax
    368499
     
    384515.s_szErrMsg:
    385516        db 13, 10, 'rd err! '
     517%endif
    386518.s_szErrMsgEnd:
    387519;ENDPROC bs3InitLoadImage - don't want the padding.
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette