Почему мой загрузчик не работает на последних ноутбуках? - PullRequest
1 голос
/ 13 мая 2019

Я хочу сделать простой загрузчик с нуля.Я хочу, чтобы он мог загружаться по USB на недавнем ноутбуке, то есть он имеет загрузку UEFI, но теоретически он поддерживает загрузку Legacy.

Поэтому я написал небольшой ассемблерный код, который просто печатает «hello world», искомпилировал его с помощью nasm -f bin boot.asm -o boot.com Затем я собрал дискету из двоичного файла с помощью dd.Дискета работала нормально с qemu-system-x86_64.Я перенес его в MBR флешки, отформатированной как FAT32, используя dd if = boot.bin из = / dev / sda.Но при загрузке на нем с моего последнего компьютера USB не отображается в загрузочных устройствах.

Я попытался: - загрузить его на Qemu (с помощью qemu-system-x86_64 -hdb / dev / sda) успешно - загрузите его на действительно старый компьютер с процессором Intel Pentium 4, и все заработало как положено.- включите устаревший режим в настройках BIOS - отключите безопасную загрузку - загрузите его на другом компьютере, где флешка появляется в загрузочных устройствах, но ничего не печатается.

Я нашел его в Интернете, поэтому сборка должнабыть правильным

;; A tiny, working bootloader for x86 PCs. Has a few subroutines
;; so it's slightly less useless than just printing "hello world".
;;
;; writeup here: http://joebergeron.io/posts/post_two.html
;;
;; Joe Bergeron, 2016.
;;
    bits 16

    mov ax, 07C0h
    mov ds, ax
    mov ax, 07E0h       ; 07E0h = (07C00h+200h)/10h, beginning of stack segment.
    mov ss, ax
    mov sp, 2000h       ; 8k of stack space.

    call clearscreen

    push 0000h
    call movecursor
    add sp, 2

    push msg
    call print
    add sp, 2

    cli
    hlt

clearscreen:
    push bp
    mov bp, sp
    pusha

    mov ah, 07h     ; tells BIOS to scroll down window
    mov al, 00h     ; clear entire window
        mov bh, 07h         ; white on black
    mov cx, 00h         ; specifies top left of screen as (0,0)
    mov dh, 18h     ; 18h = 24 rows of chars
    mov dl, 4fh     ; 4fh = 79 cols of chars
    int 10h         ; calls video interrupt

    popa
    mov sp, bp
    pop bp
    ret

movecursor:
    push bp
    mov bp, sp
    pusha

    mov dx, [bp+4]      ; get the argument from the stack. |bp| = 2, |arg| = 2
    mov ah, 02h         ; set cursor position
    mov bh, 00h     ; page 0 - doesn't matter, we're not using double-buffering
    int 10h

    popa
    mov sp, bp
    pop bp
    ret

print:
    push bp
    mov bp, sp
    pusha
    mov si, [bp+4]      ; grab the pointer to the data
    mov bh, 00h         ; page number, 0 again
    mov bl, 00h     ; foreground color, irrelevant - in text mode
    mov ah, 0Eh         ; print character to TTY
 .char:
    mov al, [si]        ; get the current char from our pointer position
    add si, 1       ; keep incrementing si until we see a null char
    or al, 0
    je .return          ; end if the string is done
    int 10h             ; print the character if we're not done
    jmp .char       ; keep looping
 .return:
    popa
    mov sp, bp
    pop bp
    ret


msg:    db "Oh boy do I sure love assembly!", 0

    times 510-($-$$) db 0
    dw 0xAA55

Я хочу иметь возможность загрузить USB на моем последнем компьютере с процессором i7-8550U и совместимым с UEFI / Legacy.На данный момент флешка не отображается в загрузочных устройствах.

РЕДАКТИРОВАТЬ: Спасибо за ваши ответы!Я попытался установить блок параметров Bios (BPB), добавив этот фрагмент кода:


ORG 0
BITS 16

jmp near start

db "MYBOOT  "      
dw 512           
db 1                
dw 1          
db 2             
dw 512                    
dw 65535          
db 0xf8     
dw 20      
dw 63            
dw 16    
dd 0            
dd 0        
db 0x29  
dd 0xffff  
db 0         
db 0         
db "NO NAME    "
db "FAT32   "

start:
   blablabla (see above)

, и теперь на рабочем столе Ubuntu появляется USB-флешка (я заметил, что он исчезнет, ​​если я использую что-то еще, кроме'jmp near start', как 'jmp short start') Но он все еще не хочет появляться в моем меню загрузки BIOS. Я действительно не знаю, почему он не хочет видеть его в данный момент.У меня биос версии F.23, может есть какой нибудь особенный способ сделать это с этим биосом?

1 Ответ

1 голос
/ 14 мая 2019

Я не могу поместить это в комментарий, и я исправлю это, чтобы быть правильным ответом, если что-то из этого поможет. Предоставленный код МОЖЕТ быть решением проблемы. Это основано на сходном наборе обстоятельств с более новым BIOS, который был обнаружен в обсуждении на форуме OSDev несколько месяцев назад.

Можете ли вы попробовать скомпилировать и собрать MBR, используя это, и посмотреть, распознает ли ваш BIOS диск как загрузочный? Он содержит таблицу разделов с самостоятельными ссылками, если вы загружаетесь с разделенных носителей. Не знаете, какой USB-носитель эмулирует ваш BIOS, и вы хотите, чтобы вы просто протестировали его, чтобы увидеть, печатает ли он:

Привет, мир!

код:

bits 16
org 0x7c00

boot_start:
    xor ax, ax                  ; DS=0 since we use ORG 0x7c00. 0x0000<<4+0x7c00=0x7c00
    mov ds, ax
    mov es, ax

    ; If you will be reading data into memory outside of 0x7c00 to 0x7dff
    ; then you want to set the stack SS:SP - uncomment these lines
    ; mov ss, ax                ; Stack at 0x0000:0x7c00
    ; mov sp, 0x7c00            ;     Just below bootloader

    cld                         ; Forward movement of string instructions
                                ;     (MOVSB, SCASB, etc)

    mov si, HelloWorldMsg       ; Print hello world
    call print_string

end_loop:                       ; Loop forever to terminate
    hlt
    jmp end_loop

; Function: print_string
;           Display a string to the console on display page 0
;
; Inputs:   SI = Offset of address to print
; Clobbers: AX, BX, SI

print_string:
    mov ah, 0x0e                ; BIOS tty Print
    xor bx, bx                  ; Set display page to 0 (BL)
    jmp .getch
.repeat:
    int 0x10                    ; print character
.getch:
    lodsb                       ; Get character from string
    test al,al                  ; Have we reached end of string?
    jnz .repeat                 ;     if not process next character
.end:
    ret

HelloWorldMsg:   db "Hello, world!", 0x0d, 0x0a, 0

times 446-($-$$) db 0   ; Pad with 0s up until first partition entry
part1_entry:
db 0x80                 ; 0x80 = Active boot partition, 0x00=inactive
db 0x00, 0x01, 0x00     ; CHS of first absolute sector (MBR) of hard drive
                        ;     Head=0, Sector=1, Cylinder=0
db 0x0c                 ; Partition type (has to be non-zero)
                        ;     0x0c = Win 95 FAT32 (LBA)
db 0x00, 0x01, 0x00     ; CHS of last absolute sector (MBR) of hard drive
                        ;     Head=0, Sector=1, Cylinder=0
                        ;     We are effectively saying Size of partition is 1 sector
dd 0x0                  ; LBA of first absolute sector (0=MBR)
dd 0x1                  ; Number of sectors in partition. We set it to 1 but if you
                        ;     wish you could set it to the number of sectors on the disk

times 510-($-$$) db 0   ; Pad remainder of boot sector up to boot signature. This zeroes
                        ;     partition entries 2,3,4 effectively making them inactive

dw 0xAA55               ; The standard PC boot signature after partition table

Этот код может не сделать ваш диск видимым или даже загружать и выводить что-либо, однако результаты могут помочь сузить проблемное пространство. Часть меня думает, что есть вероятность, что это не просто проблема с BPB, учитывая то, как реагирует ваш BIOS.

...