Ядро моей ОС в D: некоторые встроенные строки не работают - PullRequest
7 голосов
/ 22 декабря 2010

Я знаю, что на этот вопрос довольно сложно ответить, в основном потому, что есть так много вещей, которые могут быть не правы, и трудно что-то определить. Но я дам столько информации, сколько смогу; надеюсь, это поможет.

Я начал писать свое собственное ядро ​​с использованием языка D и компилятора Digital Mars D, и после многих трудностей с выяснением того, как генерировать плоские двоичные файлы, которые можно перемещать, я наконец-то пришел к мысли о генерации обычного PE-файл для адреса 0xC0000000 и замены всех его заголовков байтом 0x90 (код операции NOP). Это прекрасно работало, и я мог писать что-то на экране, настраивать подкачку страниц, входить в защищенный режим и т. Д. На отлично, конечно же, с помощью 16-разрядного загрузчика на основе сборок.

Все было хорошо, то есть я решил портировать библиотеку времени выполнения D для использования в моем ядре. Мне удалось извлечь часть библиотеки и изменить ее, чтобы она скомпилировалась в мое приложение. Затем я запустил свою программу. (Примечание: я не вообще использовал библиотеку; мой код был первым кодом, выполнявшимся после загрузки - первым, что произошло, было печать "Kernel" на экране, и никакой код времени выполнения до этого не вызывался.)

Массив D (и, следовательно, строка, поскольку строка - это просто char[]) - это не более чем структура с указателем и элементом размера, поэтому в 32-разрядной системе он будет иметь размер 8 байт. Самое смешное, что когда я запускал свою программу, члены структуры показывали ноль , то есть и указатель, и размер были равны нулю. (Я проверил это, напечатав значение указателя на экране, а также член длины - оба были равны нулю.) Как только я удалил исходный код для среды выполнения (которая никогда не выполнялась в любом случае), они работали нормально .

Я сузил это до двух возможностей:

  1. Стек был как-то настроен неправильно: я исключил это, потому что все работало без библиотеки времени выполнения, и я подтвердил, что никакой другой код не выполнялся до моего кода путем разборки файла.

  2. Что-то смешное в секциях PE-файла: я проверил и выяснил, что в версии с исполняемой версией было две переменные TLS (локальные для потока). Конечно же, когда я сделал их общими (а не локальными), мой код работал! Однако , мой код все еще показывал проблему , такую ​​же , когда я вызывал код, который я написал в другом файле - только kernel.d, который является файлом запуска, вел себя правильно со строками ; в других файлах массивы снова были равны нулю.

Теперь, кто-нибудь догадывается, почему это может происходить?

Если понадобится дополнительная информация, я буду рад опубликовать ее.

Спасибо!

Ответы [ 2 ]

6 голосов
/ 22 декабря 2010

Во-первых, отказ от ответственности: я не знаю, что первое о D.

Во-вторых, еще один отказ от ответственности: Основываясь на использовании термина "PE-файл", я собираюсь догадаться, что выиспользуя Windows.Я собираюсь дать предложение для цепочки инструментов GNU ...

Но ... Предполагая, что компилятор D генерирует объектные файлы, как и любые другие ... Почему бы не сделать следующее (это то, что я сделалкогда я работал над хобби ОС на C, тогда, когда у меня было время для таких вещей):

  • Генерация двоичного файла ELF для вашего ядра ... Для этого соберите все ваши объектные файлы как обычно,На этапе связывания введите скрипт компоновщика в ld, который будет определять такие вещи, как начальный адрес, порядок разделов (текст, данные, роды и т. Д.) Двоичного файла ...
  • Загрузите его сGRUB (Довольно просто сделать ... Вам нужно поместить некоторые магические слова в начало вашего двоичного файла. Это можно сделать с помощью операторов типа db или dw в файле .asm, при условии, что соответствующий объект будет связанв начале ядра. эта ссылка )

Таким образом, вы можете сосредоточиться на более интересных вещах, чем взлом PE-заголовка или написание загрузчика.

Конечно ... Звучит вполне возможно, что в самом коде есть какая-то проблема, а не то, как вы ссылаетесь.Это может быть информативным, чтобы запустить его во что-то, что позволит вам пошагово просмотреть результаты сборки.Эмулятор ПК x86 qemu имеет несколько параметров отладки, которые выводят сборку и регистрируют состояние в журнале.Я использовал это.

1 голос
/ 21 июня 2011

Год спустя ...

Решено! : D

(> '.')> (^ '.' ^) <('.')> (V '.' V) <('.' <) </p>

Это была проблема с моим загрузчиком: я читал слишком мало секторов в память. (А именно, 64 сектора вместо 128 125.)

...