jmp vs (push,retn), не пойму в чем глюк
1. Одна таблица страниц, в которую спроецировано первые 3 мегабайта физической памяти
2. Один каталог страниц, в котором изначально прописана таблица страниц 2 раза для адресов 0x00XXXXXX и 0xf0XXXXXX.
Потом:
1. Передается управление коду по адресу 0xf0000200 (где-то там), все ок
2. Стирается из каталога страниц ссылка для адресов 0x00XXXXXX
3. Обнуляется кэш страниц (с сохранением)
После этого если передать управление на адрес 0xf0200000 ближним или межсегментным jmp-ом то происходит PageFault, если делать это с помощью
push 0xf0200000
retn
то все ок. Вот это мне совсем не понятно...
Кроме того если пропустить пункт 2 (обнуление) то все 3 метода работают.
Или я сошел с ума, или эмулятор :(
Использую bochs
Помогите, пожалуйста. Заранее спасибо.
потому что при переходе с помощью push ret селектор не меняется
При ближнем переходе jmp-ом селектор тоже не меняется...
Уже долго над этой проблемой сижу. Пробую параллельно загрузчик заново переписать. Если получится то хорошо, а если нет...
Цитата: disasm
2. Один каталог страниц, в котором изначально прописана таблица страниц 2 раза для адресов 0x00XXXXXX и 0xf0XXXXXX.
не понял, зачем 2 раза
Т.е. я делаю так:
1. перехожу в PM
2. инициализирую таблицы,каталог страниц, заргужаю cr3
3. включаю страничное преобразование заодно прыгаю на 0x000xxxxx
4. после этого только прыгаю на 0xf00xxxxx
5. удаляю ссылку для адресов 0x000xxxxx
6. прыгаю в область ядра
disasm, по любому "near jump" более "легкий" вариант, чем пара "push address/retn"! Вроде бы ты объяснял подробно, но все равно много непонятного. Где физически находятся загрузчик и ядро?
Ядро лежит по адресу 0x00200000
Первый байт ядра равен 0xf4, проверено прямо в загрузчике с помощью cmp.
Комманду hlt использую потому, что bochs останавливается при халте с запрещенными прерываниями, т.е. я могу определить что определенная точка программы достигнута.
Кроме того заметил, что не работает подсистема прерываний, при вызове прерывания происходит page fault, хотя все настроено правильно и раньше все работало (раньше это когда я не удалял нулевой элемент каталога страниц)
Кроме того мне не нравится, что в реальном режиме комманда
call *%ax
выполняется не так как надо, переход на адрес в %ax вообще не выполняется
В отличие от комбинации
call proc1
...
proc:
jmp *%ax
Может мне стоит поменять эмулятор?
Я в синтаксисе at&t плохо разбираюсь, но мне кажется, что * в jump'е используется в других ситуациях. Я бы написал так: call %ax. Потом ты бы протестировал свой код еще и на реальном железе, потому что иногда бывают случаи, когда эмуляторы не пропускают работоспособный код, хотя чаще случается наоборот. Лично я использую только бокс. У меня к этому эмулятору претензий нет. По поводу твоего бага у меня есть только предположения: может что-то нужное осталось в отлинкованных страницах... еще попробуй сначала очистить tlb, а потом сразу же очистить вхождение... если ты очищаешь не весь буфер, нужно отдельно сбрасывать каждую конечную страницу...