Пытаюсь написать свою мини ОС. Я учусь на других проектах, поэтому понятия не имею, подходит ли мой код для загрузчика и ядра. Я использую сборку 16 бит, NASM, и загружаю загрузчик и ядро как файлы .bin на образ дискеты. Я запускаю ОС с qemu. Я дошел до того, что добавление дополнительных строк кода стирает отображаемые строки, которые появляются при запуске ОС. Например, если я запускаю операционную систему, и она говорит: «Добро пожаловать в мою ОС!», После добавления нескольких строк кода она будет выглядеть как «Добро пожаловать в м» (конец исчезает).
вот мой код:
bootloader.asm
[bits 16]
[org 0x7c00]
; Use the boot drive number passed to us by BIOS in register DL
start:
xor ax,ax ; We want a segment of 0 for DS
mov ds,ax ; Set AX to appropriate segment value
mov es,ax ; In this case we'll default to ES=DS
mov bx,0x8000 ; Stack segment can be any usable memory
mov ss,bx ; This places it with the top of the stack @ 0x80000.
mov sp,ax ; Set SP=0 so the bottom of stack will be @ 0x8FFFF
cld ; Set the direction flag to be positive direction
mov si, welcome_msg
call print_string
mov si, kernel_load
call print_string
pushf
stc
mov ah,00h ; Reset Disk Drive
int 13h
read_sector:
mov ax, 0x0
mov es, ax ; ES = 0
mov bx, 0x1000 ; BX = 0x1000. ES:BX=0x0:0x1000
; ES:BX = starting address to read sector(s) into
mov ah, 02 ; Int 13h/AH=2 = Read Sectors From Drive
mov al, 01 ; Sectors to read = 1
mov ch, 00 ; CH=Cylinder. Second sector of disk
; is at Cylinder 0 not 1
mov cl, 02 ; Sector to read = 2
mov dh, 00 ; Head to read = 0
; DL hasn't been destroyed by our bootloader code and still
; contains boot drive # passed to our bootloader by the BIOS
int 13h ; Read Sectors From Drive
jc error_kernel_load ; error loading kernel
popf
jmp 0x0:0x1000 ; jmp to kernel offset
cli ; Disable interrupts to circumvent bug on early 8088 CPUs
hlt ; halts the central processing unit (CPU) until the next external interrupt
error_kernel_load:
mov si, error_msg
call print_string
mov si, restart_msg
call print_string
mov ah,00 ; wait for key press
int 16h
xor ax,ax
int 19h ; reboot the computer
print_string: ; Routine: output string in SI to screen
lodsb ; Get character from string
or al,al
jz exit
mov ah,0x0e
int 10h ; int 10h 'print char' function
jmp print_string
exit:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Messages to print
welcome_msg db 'Welcome to Bootloader!!!',0x0D,0x0A,0
kernel_load db 'Loading kernel....',0x0D,0x0A,0
error_msg db 'Kernel.bin not found!',0x0D,0x0A,0
restart_msg db 'Press any key to restart..',0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 510-($-$$) db 0 ; Create padding to fill out to 510 bytes
dw 0xaa55 ; Magic number in the trailer of a boot secto
kernel.asm
[bits 16]
[org 0x1000]
section .data:
cursor_col: db 0 ; cursor column
cursor_row: db 0 ; cursor row
line_col: dw 0 ; line column
line_row: dw 0 ; line row
color: db 3Fh ; background and forground color (at start set random the formal way > number+letter)
mode: db 0
start:
mov ax, 07C0h ; Set up 4K stack space after this bootloader
add ax, 288 ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov byte [color], 3Fh
call clear_screen ; clear the screen and color it
; VVV print "Minerald welcome" message VVV
mov byte [cursor_col], 08
mov byte [cursor_row], 28
call set_cursor ; print at the requested position of the screen
mov si, welcome_string ; Put string position into SI
call print_string ; Call our string-printing routine
; VVV print "Press Space" message VVV
mov byte [cursor_col], 14
mov byte [cursor_row], 26
call set_cursor ; print at the requested position of the screen
mov si, press_key_string ; Put string position into SI
call print_string ; Call our string-printing routine
mov ah, 0h ; wait for key press
int 16h
mov byte [color], 1Fh
call clear_screen ; clear the screen and color it
mov byte [cursor_col], 2
mov byte [cursor_row], 0
call set_cursor ; print at the requested position of the screen
mov si, basic_background ; Put string position into SI
call print_string
mov byte [cursor_col], 22
mov byte [cursor_row], 0
call set_cursor ; print at the requested position of the screen
mov si, basic_background ; Put string position into SI
call print_string ; Call our string-printing routine
mov ah, 0 ; set display mode function.
mov al, 13h ; mode 13h = 320x200 pixels, 256 colors.
int 10h ; set it!
;================================= ; rectangles
mov byte [line_col], 80
mov byte [line_row], 165
call print_rectangle ; print rectangle
mov byte [line_col], 80
mov byte [line_row], 135
call print_rectangle ; print rectangle
;==================================
end:
jmp $ ; Jump here - infinite loop!
;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;
clear_screen:
mov ah, 06h ; Scroll up function
xor al, al ; Clear entire screen
xor cx, cx ; Upper left corner CH=row, CL=column
mov dx, 184Fh ; lower right corner DH=row, DL=column
mov bh, byte [color] ; set background and foreground color
int 10h
ret
;;;;;;;;;;
;;;;;;;;;;
print_string: ; Routine: output string in SI to screen
lodsb ; Get character from string
or al,al
jz exit
mov ah,0x0e ; int 10h 'print char' function
int 10h
jmp print_string
exit:
ret
;;;;;;;;;;
;;;;;;;;;;
set_cursor:
mov dh, byte [cursor_col] ; cursor col
mov dl, byte [cursor_row] ; cursor row
mov ah, 02h ; move cursor to the right place
xor bh, bh ; video page 0
int 10h ; call bios service
ret
;;;;;;;;;;
;;;;;;;;;;
print_rectangle:
%INCLUDE "print_rectangle.asm"
;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Messages to print
welcome_string db 'Welcome to my OS!', 0
press_key_string db 'Press any key to continue...', 0
enter_message_string db 'Enter your message below',0
APM_ERROR_string db 'APM Error...'
basic_background db '--------------------------------------------------------------------------------'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;END OF KERNEL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
это команды нагрузки:
nasm -f bin -o kernel.bin kernel.asm
nasm -f bin -o bootloader.bin bootloader.asm
dd if=bootloader.bin of=floppy.flp bs=512 seek=0 conv=notrunc
dd if=kernel.bin of=floppy.flp bs=512 seek=1 conv=notrunc
qemu-system-i386 -fda floppy.flp
редактировать:
из файла листинга nasm до усечения сообщений:
300 ; Messages to print
301 00000191 57656C636F6D652074- welcome_string db 'Welcome to my OS!', 0
302 0000019A 6F204D696E6572616C-
303 000001A3 644F532100
304 000001A8 507265737320616E79- press_key_string db 'Press any key to continue...', 0
305 000001B1 206B657920746F2063-
306 000001BA 6F6E74696E75652E2E-
307 000001C3 2E00
308 000001C5 456E74657220796F75- enter_message_string db 'Enter your message below',0
309 000001CE 72206D657373616765-
310 000001D7 2062656C6F7700
311 000001DE 41504D204572726F72- APM_ERROR_string db 'APM Error...'
312 000001E7 2E2E2E
313 000001EA 2D2D2D2D2D2D2D2D2D- basic_background db '--------------------------------------------------------------------------------'
из файла листинга nasm после усечения сообщений:
332 ; Messages to print
333 000001E8 57656C636F6D652074- welcome_string db 'Welcome to MineraldOS!', 0
334 000001F1 6F204D696E6572616C-
335 000001FA 644F532100
336 000001FF 507265737320616E79- press_key_string db 'Press any key to continue...', 0
337 00000208 206B657920746F2063-
338 00000211 6F6E74696E75652E2E-
339 0000021A 2E00
340 0000021C 456E74657220796F75- enter_message_string db 'Enter your message below',0
341 00000225 72206D657373616765-
342 0000022E 2062656C6F7700
343 00000235 41504D204572726F72- APM_ERROR_string db 'APM Error...'
344 0000023E 2E2E2E
345 00000241 2D2D2D2D2D2D2D2D2D- basic_background db '--------------------------------------------------------------------------------'
346 0000024A 2D2D2D2D2D2D2D2D2D-
-l kernel.lst
и скопируйте только несколько строк вокругwelcome_string
) - чтобы увидеть, как он компилируется и по какому смещению они размещаются. - person Ped7g   schedule 08.04.2018int 10,0E
службы является неверно, вы не устанавливаетеBH
на текущую страницу, и мне кажется, что может быть какое-то значение из чтения сектора, вероятно0x10
, что делает его, вероятно, работать случайно, но я не хочу копаться в коде, который написан небрежно и, вероятно, проверен, просто выполнив его и проверив вывод. Прекратите это делать, запустите его в отладчике, пошагово перебирая каждую инструкцию, и проверьте все предположения / эффекты инструкций, не полагайтесь на вывод. - person Ped7g   schedule 08.04.2018section
актуальна, поскольку вы используете форматbin
для вывода, поэтому ваше ядро, скорее всего, начинается с0000:1000
с байтами данных, а не с инструкциями , что, вероятно, является еще одной чистой удачей, поскольку вы получаете даже несколько значимый результат после выполнения данных. Смешиваниеsection
сorg
не имеет смысла, либо вы используетеsection
и более сложный исполняемый формат, где компоновщик будет сортировать макет памяти в соответствии с предоставленным скриптом компоновщика, либо вы используете двоичный файл, где вам нужно разметить себя. - person Ped7g   schedule 08.04.2018org
регулирует внутренние смещения во время сборки. - person Ped7g   schedule 08.04.2018ELF
(32 или 64 бит), в процессе сборки будут созданы первые объектные файлы, которые имеют только относительные локальные смещения внутри объектного файла, а не конечные адреса,org
вообще не используется. Затем объектные файлы собираются компоновщиком, и из них собирается окончательный исполняемый файл, соединяя различные символы между разными объектными файлами, а также помещая данные и код в [иногда отдельные] области, где они принадлежат согласно сценарию компоновщика, используемому для связывания, каждого данных или часть кода определила целевой раздел директивойsection
, которая предназначена для компоновщика. - person Ped7g   schedule 08.04.2018line_number address(offset) machine_code_bytes
- это буквально то, что у вас есть в файле .bin (ну, только часть машинного кода, номера строк и смещения - это просто информация для вас, откуда был взят машинный код. скомпилирован, и туда, где он приземлится) ... нашkernel.bin
начинается с нескольких нулей, созданныхdb 0
, и вы будете в загрузчикеjmp 0:0x1000
с этими байтами данных и выполнять их как инструкции. (поскольку для ЦП байт памяти - это байт памяти, он не может сказать, что такое код, а что такое данные, разницы нет). - person Ped7g   schedule 08.04.201800 00
- это код операции инструкцииadd [bx+si],al
... и т. Д., Так что это то, что вы выполняете. (db не является инструкцией, это директива для выдачи байтовых значений ассемблером, поэтому, когда вам нужен какой-то байт в машинном коде со значением13
, вам не нужно вспоминать, какая инструкция имеет код операции, начинающийся с13
, но вы можете написатьdb 13
.. . и наоборот, мнемоника инструкций поможет вам не вспоминать, чтоret
естьdb 195
(хотя это и работает, для большинства людей было бы слишком сложно запоминать все кодировки инструкций и записывать их в виде чисел). - person Ped7g   schedule 08.04.2018kernel.bin
(в linux install hd = hexdump? В Ubuntu вы можете найти его в пакете bsdmainutils), чтобы увидеть, как этот машинный код в листинге является единственным содержимым, которое заканчивается в файле bin, и это то, что ЦП видит + выполнение (но в двоичном формате, поскольку ЦП работает только с битами, т. е. с электричеством текущие уровни в ячейках, которые обрабатываются как логические значения 0 или 1). - person Ped7g   schedule 08.04.2018