Загрузчик ОС не работает - PullRequest
4 голосов
/ 20 июля 2010

Я делаю пользовательскую операционную систему.У меня есть два файла nasm:

boot.asm:

[BITS 16]   ;tell the assembler that its a 16 bit code
[ORG 0x7C00]    ;Origin, tell the assembler that where the code will
;be in memory after it is been loaded

INT 0x13

JMP $       ;infinite loop

TIMES 510 - ($ - $$) db 0   ;fill the rest of sector with 0
DW 0xAA55           ; add boot signature

start.asm:

[BITS 16]
MOV AL, 72
CALL PrintCharacter
MOV AL, 101
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 111
CALL PrintCharacter
MOV AL, 44
CALL PrintCharacter
MOV AL, 32
CALL PrintCharacter

MOV AL, 87
CALL PrintCharacter
MOV AL, 111
CALL PrintCharacter
MOV AL, 114
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 100
CALL PrintCharacter
MOV AL, 33
CALL PrintCharacter

PrintCharacter: 
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
RET

TIMES 512 - ($ - $$) db 0

Я собираю их в файлы .bin с помощью следующих команд:

nasm boot.asm -f bin -o boot.bin
nasm start.asm -f bin -o start.bin

Затем добавьте их в образ дискеты с помощью следующих команд:

dd if=boot.bin bs=512 of=MyOS.img count=1
dd if=start.bin bs=512 of=MyOS.img count=2

Когда я загружаюсь с образа дискеты в VirtualBox, он показывает 2 восклицательных знака вместо одного и не делаетдаже загрузиться в QEmu (Q.app).Я новичок в разработке операционных систем, и было бы неплохо, если бы кто-то мог сказать мне, что я сделал не так, и дать несколько советов о том, как лучше настроить мою ОС.

Ответы [ 2 ]

5 голосов
/ 20 июля 2010

Конечно, он печатает два восклицательных знака. Давайте посмотрим на ваш код:

...
MOV AL, 33
CALL PrintCharacter    ;   |1
                       ;   |          ^     |4
PrintCharacter:        ;   v    |2    |     |
MOV AH, 0x0E           ;        |     |     |
MOV BH, 0x00           ;        |     |     |
MOV BL, 0x07           ;        |     |     |
INT 0x10               ;        |     |     |     5
RET                    ;        v     |3    v     ----> off to la-la land

Примечание. Я добавил несколько стрелок, иллюстрирующих ход выполнения программы.

Первые две строки отвечают за печать окончательного ! после того, как вы уже вывели Hello, World. Это достигается с помощью вызова вашей подпроцедуры PrintCharacter. (стрелки 1 и 2.) Когда возвращается PrintCharacter (стрелка 3), ваша программа просто продолжается прямо (стрелка 4) ... и следующая строка кода оказывается началом PrintCharacter снова. Поскольку регистр AL по-прежнему содержит 33 (т. Е. Код ANSI для !), печатается еще один восклицательный знак.

Затем выполнение снова достигает RET, но на этот раз, поскольку вы на самом деле не CALL PrintCharacter, не существует определенного места, куда можно вернуться, поэтому оно возвращается в ... какое-то неопределенное место наиболее вероятно (стрелка 5). Я полагаю, что это тот момент, когда ваша ОС перестает продолжать процесс загрузки.

Вывод: После того, как ваш код напечатает Hello, World!, он должен сделать что-то еще (по крайней мере, stop ), в противном случае не удивляйтесь, когда вы получите неопределенное поведение или зависание ...

1 голос
/ 01 ноября 2011

Я не знаю, как VirtualBox загружает ваш код, но я почти уверен, что qemu этого не делает, потому что вы неправильно настраиваете двоичные файлы на образе диска. Когда вы используете «dd» на образе диска, вам нужно передать ему опцию, чтобы он не обрезал диск, что-то вроде этого:

dd if=boot.bin of=MyOS.img bs=512 count=1 conv=notrunc status=noxfer
dd if=start.bin of=MyOS.img bs=512 count=1 conv=notrunc seek=1 status=noxfer

conv = notrunc сообщает 'dd', что он не должен обрезать диск, то есть удалять его и перезаписывать его своим двоичным файлом, status = noxfer делает его менее многословным, а seek = 1 записывает start.bin во второй сектор диск (начинается с 0).

Чтобы убедиться в том, что я говорю, попробуйте создать образ диска размером 1 МБ и используйте команду (т.е. dd), которую вы использовали, и вы увидите, что образ диска уменьшен до копии вашего двоичного файла.

Итак, в конце вы вызываете qemu, используя start.bin в качестве образа диска (MyOS.img становится его копией после последней команды 'dd'), и так как вы не использовали загрузочную подпись в конце в файле start.bin BIOS qemu не считает ваш диск загрузочным.

...