Форум программистов, компьютерный форум, киберфорум
Наши страницы
ОС на Assembler
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
TechnoDesert
0 / 0 / 0
Регистрация: 02.09.2016
Сообщений: 26
1

Int 13h и пародия на ОС

28.03.2017, 20:15. Просмотров 1160. Ответов 15

Здравствуйте! Решил написать ОС с по-настоящему красивыми обоями. Имеется первичный загрузчик loader0.asm:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
org 0x7C00
 
section .text
 
start0:
 
mov AH, 0x00 ;display cleaning
mov AL, 0x03
 
int 0x10
 
mov AX, 0x00
 
sti
mov SS, AX
mov SP, start0
cli
 
mov ES, AX
mov DS, AX
 
mov AH, 0x02 ;reading sectors
mov DL, 0x00
mov DH, 0x00
mov CH, 0x00
mov CL, 0x02
mov AL, 10 ;***
mov BX, 0x7E00
 
int 0x13
 
jmp 0x0000:0x7E00
 
mov AL, AH ;ugly debug
add AH, 32
mov AH, 0x09
mov CX, 0x01
mov BH, 0x00
mov BL, 0x0F
 
int 0x10
 
end:
 
times 0x01FE - end + start0 db 0x00
db   0x55, 0xAA
Примечание: в строке с ком. Ugly debug и последующих 6 строках делается следующее: int 0x13 (AH = 0x02) в AH помещается код ошибки, затем к коду ошибки прибавляется 32 (это ужасно), для того чтобы была возможность вывести символ, номер_которого = код_ошибки + 32 (первые 32 символа ASCII не графические). Затем всё это д****о выводится.
Имеется вторичный загрузчик loader1.asm:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
section .text
 
global start1
extern kernel_start
 
start1:
 
mov AH, 0x09
mov AL, 0x21
mov CX, 0x01
mov BH, 0x00
mov BL, 0x0F
 
int 0x10
 
cli
call kernel_start
hlt
Который должен вывести '!' и запустить kernel_start() из kernel.c, приведенного ниже:
C
1
2
3
4
5
6
7
8
void kernel_start() {
 char *video_memory = (char*)0xb8000;
 
 for(int i = 0; i < 80 * 25 * 2; i++) {
  video_memory[i] = '0';
  video_memory[i + 1] = 0x0F;
 }
}
kernel_start(), в свою очередь должен заполнить экран 0 белого цвета на черном фоне.
Но это все в теории, на самом деле происходит вот что.
1) loader0 успешно загружается, но, судя по всему, не считывает сектора. С помощью ugly debug выводится ' ', так как ошибок нет.
2) loader1 не запускается и не запускает kernel_start().
Все это компилируется и собирается следующими командами:
1)
Bash
1
nasm -o loader0.bin loader0.asm
2)
Bash
1
nasm -f elf32 loader1.asm -o loader1.o
3)
Bash
1
gcc -m32 -c kernel.c -o kernel.o
4)
Bash
1
ld -m elf_i386 -T link.ld -o kernel loader1.o kernel.o
5)Затем loader0.bin и kernel засовываются в image.img, собственной утилитой
6)Все выполняется так:
Bash
1
qemu-system-x86_64 image.img
Примечание: link.ld
Bash
1
2
3
4
5
6
7
8
OUTPUT_FORMAT(elf32-i386)
ENTRY(start1)
SECTIONS {
 . = 0x00;
 .text : { *(.text)}
 .data : { *(.data)}
 .bss : { *(.bss)}
}
*** - 10 секторов потому что kernel.o получается размером 4972 байта и при целоч. делении на 512 (1 сектор) получается 9 + 1 (остаток)
И после компиляции, линковки, и сборки всего этого, kernel не выполняется. В чем может быть дело? Заранее спасибо. Извините за длиннопост.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.03.2017, 20:15
Ответы с готовыми решениями:

Как записать данные в загрузочный сектор без использования int 13h
Подскажите, пожалуйста, как записать данные в загрузочный сектор без помощи 13h прерывания.

Функция 48h int 13h
Расскажите, пожалуйста, про функцию 48h прерывания 13h. Где про Int 13h находил, там про такую...

DOS виснет на int 13h при чтении MBR жесткого диска
читаю MBR жесткого диска, досю гружу с флешки, как доходит до инт 13 - встает. masm .model small...

Будут ли работать функции прерывания int 13h с виртуальным флоппи диском
Все привет) Меня интересует будут ли работать функции прерывания int 13h с виртуальным флоппи...

int 13h. Не могу прочитать с винта за раз блок более 64кб
Я столкнулся с проблемой дело в том что через INT13h я не могу прочитать с винта за раз блок...

15
Argogo
639 / 240 / 40
Регистрация: 29.03.2013
Сообщений: 532
31.03.2017, 05:36 2
Цитата Сообщение от TechnoDesert Посмотреть сообщение
sti
mov SS, AX
mov SP, start0
cli
Да ты шутник!
(Дальше не смотрел.)

Добавлено через 14 минут
Я не понимаю, что мешает писателям boot-секторов начать со строк
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    ORG 7C00h
Start:
    cli
    mov ax, cs
    mov ss, ax
    mov sp, offset Start
    sti
    mov ds, ax
    mov es, ax
    ;
    ; вставляй ниже свой код
    ; компилируй как EXE-файл
    ; и отлаживай его из-под дебагера (Turbo Debugger от Borland Software Corporation для DOS вполне подойдёт)
    ; для 99% задач загрузчика этого вполне достаточно,
    ; в том числе и для чтения секторов с диска.
(естественно с поправками на диалект ассемблера)
0
TechnoDesert
0 / 0 / 0
Регистрация: 02.09.2016
Сообщений: 26
31.03.2017, 11:37  [ТС] 3
Делал по этой статье: http://sysbin.com/files/lowlevel/floppy_bootloader.htm

Добавлено через 8 минут
Цитата Сообщение от Argogo Посмотреть сообщение
Я не понимаю, что мешает писателям boot-секторов начать со строк
И с чего Вы решили, что AX по умолчанию равен 0? offset Start и Start дадут одинаковые результаты. Данный Вами ответ не относится к описанной мною проблеме.
0
Argogo
639 / 240 / 40
Регистрация: 29.03.2013
Сообщений: 532
31.03.2017, 13:15 4
Цитата Сообщение от TechnoDesert Посмотреть сообщение
И с чего Вы решили, что AX по умолчанию равен 0?
И где в моём коде сие утверждение?
0
TechnoDesert
0 / 0 / 0
Регистрация: 02.09.2016
Сообщений: 26
31.03.2017, 13:22  [ТС] 5
Оного утверждения нет, но если вспомнить 98% загрузчиков, код коих приведен в интернете, то нельзя найти среди них такой, в котором регистры ss, ds, es инициализировались бы не 0.
0
Argogo
639 / 240 / 40
Регистрация: 29.03.2013
Сообщений: 532
31.03.2017, 13:38 6
Цитата Сообщение от TechnoDesert Посмотреть сообщение
Делал по этой статье: http://sysbin.com/files/lowlevel/floppy_bootloader.htm
Молодец, вот непонятно только зачем CLI и STI местами поменял. Перечитай внимательно код в статье и сравни со своим, добавь проверку на ошибку выполнения INT 13h, затем внимательно перечитай комментарии в приведённом мной выше коде.

Добавлено через 2 минуты
Цитата Сообщение от TechnoDesert Посмотреть сообщение
Оного утверждения нет, но если вспомнить 98% загрузчиков, код коих приведен в интернете, то нельзя найти среди них такой, в котором регистры ss, ds, es инициализировались бы не 0.
Если все побегут с крыши прыгать, ты за ними побежишь? А строка
Цитата Сообщение от Argogo Посмотреть сообщение
mov ax, cs
тебе ни о чём не говорит?
1
TechnoDesert
0 / 0 / 0
Регистрация: 02.09.2016
Сообщений: 26
31.03.2017, 13:41  [ТС] 7
Спасибо! CLI и STI поменял так как надо. Int 13h работает правильно. Но kernel по-прежнему не запускается.

Добавлено через 1 минуту
Цитата Сообщение от Argogo Посмотреть сообщение
Если все побегут с крыши прыгать, ты за ними побежишь?
Нет. Но, как правило, большинство право.
0
Argogo
639 / 240 / 40
Регистрация: 29.03.2013
Сообщений: 532
31.03.2017, 13:51 8
Цитата Сообщение от TechnoDesert Посмотреть сообщение
Как правило, большинство право.
Да-да, миллионы мух не могут ошибаться...
Хотя что это я. Я тебе подсказываю самый простой способ как проверить свой загрузочный код в дебагере прямо из-под DOS'а, не перезагружаясь с дискеты(флэшки/hdd). Только проходя свой код пошагово в дебагере ты сам сможешь понять где ошибки: в коде, или в сборке, или ещё в чём.
0
TechnoDesert
0 / 0 / 0
Регистрация: 02.09.2016
Сообщений: 26
31.03.2017, 14:00  [ТС] 9
То есть Вы считаете, что все загрузчики код которых находится в интернете, неверен, а код написанный Вами единственный правильный. По-моему это смешно.
0
Constantin Cat
2983 / 1117 / 376
Регистрация: 28.02.2015
Сообщений: 2,457
Завершенные тесты: 1
31.03.2017, 14:23 10
Argogo, TechnoDesert, если быть откровенными до конца, то CLI / STI там не нужны.
0
Argogo
639 / 240 / 40
Регистрация: 29.03.2013
Сообщений: 532
01.04.2017, 09:52 11
Constantin Cat, мне известно что
Loading the SS register with a MOV instruction inhibits all interrupts until after the execution of the next instruction.
This operation allows a stack pointer to be loaded into the ESP register with the next instruction (MOV ESP,
stack-pointer value) before an interrupt occurs.
Однако я не помню начиная с какого проца. В голове вертится 80486, но точно утверждать не берусь.

Добавлено через 17 часов 27 минут
UPD: Intel "80286 AND 80287 PROGRAMMER'S REFERENCE MANUAL", стр.B-73:
Any move into SS will inhibit all interrupts until after the execution of the next instruction.

В "iAPX 86, 88, 186 and 188 User's Manual Programmer's Reference" я подобных примечаний не нашел, может плохо искал.
0
shmkv
1749 / 431 / 59
Регистрация: 21.07.2015
Сообщений: 1,127
04.04.2017, 12:00 12
Цитата Сообщение от TechnoDesert Посмотреть сообщение
Который должен вывести '!' и запустить kernel_start() из kernel.c, приведенного ниже:
Чем компилируешь это чудо? Судя по всему, на выходе код для 32(64)х-разрядного режима, а у тебя 16-тиразрядный.

Добавлено через 2 минуты
Цитата Сообщение от TechnoDesert Посмотреть сообщение
gcc -m32 -c kernel.c -o kernel.o
Так и есть.
0
TechnoDesert
0 / 0 / 0
Регистрация: 02.09.2016
Сообщений: 26
04.04.2017, 16:22  [ТС] 13
Цитата Сообщение от shmkv Посмотреть сообщение
а у тебя 16-тиразрядный.
Да, это так. При добавлении в kernel.c следующего кода: asm(".code16"); - всё начинает работать. Но я хотел бы переключиться в 32-разрядный режим. Каким образом это можно сделать?
0
shmkv
1749 / 431 / 59
Регистрация: 21.07.2015
Сообщений: 1,127
04.04.2017, 18:12 14
Цитата Сообщение от TechnoDesert Посмотреть сообщение
Каким образом это можно сделать?
в гугле по запросу "защищенный режим osdev"
https://www.google.ru/?gfe_rd=cr&ei=...%D0%BC+osdev&*
0
Ethereal
5200 / 1943 / 251
Регистрация: 17.02.2013
Сообщений: 2,882
27.04.2017, 09:05 15
Цитата Сообщение от Argogo Посмотреть сообщение
Однако я не помню начиная с какого проца.
Начиная с самых первых Intel 8088 и Intel 8086

В https://edge.edx.org/c4x/BITSPilani/..._Manual_1_.pdf
на странице 2-24 мелким шрифтом примечание внизу.

Разница между разными процессорами в этом семействе заключается в том, что на первых 8088 и 8086 прерывания запрещались на одну команду после записи в ЛЮБОЙ сегментный регистр. А вот начиная с 80286 (про 80186 не знаю) только после записи в сегментный регистр SS. Но цель достигалась в обоих случаях. Если пишешь mov ss и mov sp подряд, то cli sti не обязательно.

Добавлено через 7 минут
Цитата Сообщение от Argogo Посмотреть сообщение
Loading the SS register with a MOV instruction
Цитата Сообщение от Argogo Посмотреть сообщение
Any move into SS
Видимо еще в этом разница. В старших процессорах эффектом запрещения прерываний на одну команду обладала только mov ss, в средних еще и pop ss, а в младших mov и pop в любой сегментный регистр.
1
Argogo
639 / 240 / 40
Регистрация: 29.03.2013
Сообщений: 532
27.04.2017, 15:53 16
Цитата Сообщение от Ethereal Посмотреть сообщение
В https://edge.edx.org/c4x/BITSPilani/..._Manual_1_.pdf
на странице 2-24 мелким шрифтом примечание внизу.
Видимо это:
There are a few cases in which an interrupt request is not recognized until after the the following instruction. Repeat, LOCK and segment override prefixes are considered "part of" the instructions they prefix; no interrupt is recognized between execution of a prefix and an instruction. A MOV (move) to segment register instruction and a POP segment register instruction are treated similarly: no interrupt is recognized until after the following instruction. This mechanism protects a program that is changing to a new stack (by updating SS and SP). If an interrupt were recognized after SS had been changed, but before SP had been altered, the processor would push the flags, CS and IP into the wrong area of memory. It follows from this that whenever a segment register and another value must be updated together, the segment register should be changed first, followed immediately by the instruction that changes the other value. There are also two cases, WAIT and repeated string instructions, where an interrupt request is recognized in the middle of an instruction. In these cases, interrupts are accepted after any completed primitive operation or wait test cycle.
Перевод Гугла с моей правкой:
Существует несколько случаев, когда запрос прерывания не распознается до окончания следующей инструкции.

Repeat, LOCK и префиксы переопределения сегментов считаются «частью» инструкций, которой они предшествуют; Прерывание не распознается между исполнением префикса и инструкцией.

Инструкция MOV (помещение) в сегментный регистр и команда POP для сегментного регистра обрабатываются аналогично: прерывание не распознается до окончания следующей команды. Этот механизм защищает программу, которая переходит в новый стек (путем обновления SS и SP). Если прерывание возникло бы после изменения SS, но до того, как SP был изменен, процессор поместил бы флаги, CS и IP в неправильную область памяти.

Из этого следует, что всякий раз, когда сегментный регистр и другое значение должны обновляться вместе, сначала должна быть выполнена инструкция изменения сегментного регистра, а затем сразу инструкция, которая изменяет другое значение.

Есть также два случая: WAIT и повторяющиеся строковые инструкции, в которых запрос прерывания распознается в середине инструкции. В этих случаях прерывания принимаются после любой завершенной примитивной операции или цикла ожидания ожидания.

Цитата Сообщение от Ethereal Посмотреть сообщение
Видимо еще в этом разница. В старших процессорах эффектом запрещения прерываний на одну команду обладала только mov ss, в средних еще и pop ss, а в младших mov и pop в любой сегментный регистр.
Тут есть один нюанс: если использовать одну инструкцию, которая запрещает прерывания до окончания выполнения следующей инструкции, а затем ещё одну, такого же плана, то блокировка прерывания на третью инструкцию распространятся не будет. Т.е. следующий код будет приводить к краху при определённых обстоятельствах:
Assembler
1
2
3
mov ss, zzz
mov ss, xxx
mov sp, yyy
пример притянут за уши, но если в первых процах действительно запрещались прерывания после изменения любого сегментного регистра, то во избежание возникновения ситуации, как в приведённом примере, "скобки" из CLI/STI - это гарантированный запрет на прерывания.
1
27.04.2017, 15:53
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.04.2017, 15:53

Одолеть 42h int 13h
Прошу форумчан указать на ошибку! Пытаюсь оседлать загрузчик с флешки и камнем преткновения стала...

Форматирование дискеты(1.44) int 13h
Здравствуйте! Есть задание: Форматировать дорожку № 7 нижней поверхности дисковода с размером...

Прерывание int 13h не отрабатывает - переходит по неправильному адресу
Добрый день уважаемые форумчане. Попытаюсь объяснить суть проблемы: Задача: нужно записать данные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru