這是引導加載程式小樣本的一部分代碼。
它僅顯示“myos”,但不顯示“ok”。
. . .
mov si, statement1
call print_string
; load second sector into memory
mov ah, 0x02 ; load second stage to memory
mov al, 1 ; numbers of sectors to read into memory
mov dl, 0x80 ; sector read from fixed/usb disk
mov ch, 0 ; cylinder number
mov dh, 0 ; head number
mov cl, 2 ; sector number
mov bx, _OS_Stage_2 ; load into es:bx segment :offset of buffer
int 0x13 ; disk I/O interrupt
jmp _OS_Stage_2 ; jump to second stage
. . .
statement1 db "myos", 0
; boot loader magic number
times ((0x200 - 2) - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
dw 0xAA55 ; boot signature 0xAA & 0x55
_OS_Stage_2:
. . .
mov si, statement2
call print_string
statement2 db "ok", 0
; add how much memory we need
times (1024 - ($-$$)) db 0x00
這是跳轉到_OS_Stage_2的代碼。這沒用。
此處包含完整的源代碼
bits 16] ; tell assembler that working in real mode(16 bit mode)
[org 0x7c00] ; organize from 0x7C00 memory location where BIOS will load us
start: ; start label from where our code starts
xor ax,ax ; set ax register to 0
mov ds,ax ; set data segment(ds) to 0
mov es,ax ; set extra segment(es) to 0
mov bx,0x8000
mov ax,0x13 ;clears the screen
int 0x10 ;call bios video interrupt
mov ah,02 ;clear the screen with big font
int 0x10 ;interrupt displayt
; cursor position
mov al, 2
mov ah, 0
mov bl, 4
mov bh, 0
int 0x10
mov si, command_prompt
call print_string
mov ax,0x00 ; get keyboard input
int 0x16 ; interrupt for hold & read input
; load second sector into memory
mov ah, 0x02 ; load second stage to memory
mov al, 1 ; numbers of sectors to read into memory
mov dl, 0x80 ; sector read from fixed/usb disk
mov ch, 0 ; cylinder number
mov dh, 0 ; head number
mov cl, 2 ; sector number
mov bx, _OS_Stage_2 ; load into es:bx segment :offset of buffer
int 0x13 ; disk I/O interrupt
jmp _OS_Stage_2 ; jump to second stage
int 0x19
print_string:
mov ah, 0x0E ; value to tell interrupt handler that take value from al & print it
.repeat_next_char:
lodsb ; get character from string
cmp al, 0 ; cmp al with end of string
je .done_print ; if char is zero, end of string
int 0x10 ; otherwise, print it
jmp .repeat_next_char ; jmp to .repeat_next_char if not 0
.done_print:
ret ;return
command_prompt db "myos", 0
; boot loader magic number
times ((0x200 - 2) - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
dw 0xAA55 ; boot signature 0xAA & 0x55
_OS_Stage_2:
mov al,2 ; set font to normal mode
mov ah,0 ; clear the screen
int 0x10 ; call video interrupt
mov si, statement
call print_string
statement db "ok", 0
; add how much memory we need
times (1024 - ($-$$)) db 0x00
上面的代碼由 NASM 組裝,如下所示,在 ubuntu 中使用 qemu 模擬器通過 ./build-linux.sh (file)。
#!/bin/sh
if test "`whoami`" != "root"
then
echo "You must be logged in as root to build (for loopback mounting)"
echo "Enter 'su' or 'sudo bash' to switch to root"
exit
fi
if [ ! -e disk_images/os.flp ] then
echo ">>> Creating new OS floppy image..."
mkdosfs -C disk_images/os.flp 1440 || exit
fi
echo ">>> Assembling bootloader..."
nasm -O0 -w orphan-labels -f bin -o source/bootload/nasma/boot.bin source/bootload/nasma/boot.asm || exit
echo ">>> Adding bootloader to floppy image..."
dd status=noxfer conv=notrunc if=source/bootload/nasma/boot.bin of=disk_images/os.flp || exit
echo ">>> Creating CD-ROM ISO image..."
rm -f disk_images/os.iso
mkisofs -quiet -V 'OS' -input-charset iso8859-1 -o disk_images/os.iso -b os.flp disk_images/ || exit
echo '>>> Done!'
test-linux(檔案)運行程式如下
#!/bin/sh
qemu-system-i386 -soundhw pcspk -drive format=raw,file=disk_images/os.flp,index=0,if=floppy
uj5u.com熱心網友回復:
主要問題:您正在硬編碼單元 80h 以從引導加載單元加載,但是您將映像作為軟盤驅動器傳遞給 qemu,因此您應該使用單元 00h。
dl解決方案:將暫存器(的一部分)保留dx為進入加載程式時的狀態。先前的加載程式在此暫存器中將當前引導加載單元傳遞給您,因此只需使用它即可。
額外的挑剔:
沒有錯誤處理,它只是在失敗時崩潰。
堆疊應由您的代碼設定,以避免可能干擾您的扇區負載。
完成運行后,您應該進行某種無限回圈來結束,而不是讓執行繼續超過代碼的末尾。
sti我在\周圍做了一個回圈hlt以節省電力。您列出的完整來源還有另一個錯誤,它缺少指令
[的左方括號。bits(這似乎是 NASM 允許的,但這是錯誤的。)洗掉右方括號也是有效的,bits指令有兩種形式,帶或不帶括號。您沒有在構建腳本中安裝任何內容,因此您不需要成為 root。
此時您不需要創建 ISO 映像,實際上也沒有使用它來運行您的程式。
如果您只是覆寫前兩個扇區,則不需要創建 DOS 檔案系統,這會使檔案系統無法使用。我用另一個
dd命令替換了它。
這是我的固定腳本和源代碼,除了仍然缺少的錯誤處理和堆疊設定。腳本:
#!/bin/sh
if [ ! -e disk_images/os.flp ]
then
echo ">>> Creating new OS floppy image..."
dd if=/dev/zero of=disk_images/os.flp bs=1024 count=1440 || exit
fi
echo ">>> Assembling bootloader..."
nasm -O0 -w orphan-labels -f bin -o source/bootload/nasma/boot.bin source/bootload/nasma/boot.asm || exit
echo ">>> Adding bootloader to floppy image..."
dd status=noxfer conv=notrunc if=source/bootload/nasma/boot.bin of=disk_images/os.flp || exit
echo '>>> Done!'
來源:(注意push dx,pop dx和sti\hlt回圈。)
[ bits 16] ; tell assembler that working in real mode(16 bit mode)
[org 0x7c00] ; organize from 0x7C00 memory location where BIOS will load us
start: ; start label from where our code starts
xor ax,ax ; set ax register to 0
mov ds,ax ; set data segment(ds) to 0
mov es,ax ; set extra segment(es) to 0
mov bx,0x8000
push dx
mov ax,0x13 ;clears the screen
int 0x10 ;call bios video interrupt
mov ah,02 ;clear the screen with big font
int 0x10 ;interrupt displayt
; cursor position
mov al, 2
mov ah, 0
mov bl, 4
mov bh, 0
int 0x10
mov si, command_prompt
call print_string
mov ax,0x00 ; get keyboard input
int 0x16 ; interrupt for hold & read input
; load second sector into memory
mov ah, 0x02 ; load second stage to memory
mov al, 1 ; numbers of sectors to read into memory
pop dx
; mov dl, 0x80 ; sector read from fixed/usb disk
mov ch, 0 ; cylinder number
mov dh, 0 ; head number
mov cl, 2 ; sector number
mov bx, _OS_Stage_2 ; load into es:bx segment :offset of buffer
int 0x13 ; disk I/O interrupt
jmp _OS_Stage_2 ; jump to second stage
int 0x19
print_string:
mov ah, 0x0E ; value to tell interrupt handler that take value from al & print it
.repeat_next_char:
lodsb ; get character from string
cmp al, 0 ; cmp al with end of string
je .done_print ; if char is zero, end of string
int 0x10 ; otherwise, print it
jmp .repeat_next_char ; jmp to .repeat_next_char if not 0
.done_print:
ret ;return
command_prompt db "myos", 0
; boot loader magic number
times ((0x200 - 2) - ($ - $$)) db 0x00 ;set 512 bytes for boot sector which are necessary
dw 0xAA55 ; boot signature 0xAA & 0x55
_OS_Stage_2:
mov al,2 ; set font to normal mode
mov ah,0 ; clear the screen
int 0x10 ; call video interrupt
mov si, statement
call print_string
haltloop:
sti
hlt
jmp haltloop
statement db "ok", 0
; add how much memory we need
times (1024 - ($-$$)) db 0x00
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/486320.html
上一篇:如何優雅地關閉nginx
下一篇:emu8086中的大陣列定義問題
