Я разрабатываю операционную систему, и мне нужно загрузить некоторые модули ДО того, как будет настроена подкачка. Так как на данный момент подкачка не настроена, мне нужно переместить все символы в программе на физический адрес. Моя проблема в том, что не все символы можно найти в таблице символов и не всю информацию о перемещении можно найти в rel.text. Как я могу заставить GCC экспортировать все данные символов???
Как заставить GCC экспортировать ВСЕ символы в выходной файл
Ответы (2)
Безусловно, ВСЕ, что требует перемещения, будет в таблице перемещений. Как еще его можно было загрузить? Независимо от того, включена подкачка или нет, перемещение работает точно так же — записи, которые являются абсолютными местоположениями в двоичном файле, перечислены со смещением, а затем обрабатываются программой загрузки. Все остальное должно быть в порядке без переезда.
Обратите внимание, что таблица символов сама по себе не имеет смысла для разрешения перемещений, поскольку она дает только местоположение символа.
Возможно, вы думаете о символах в самой вашей ОС? Если это так, то это действительно случай экспорта символов из вашей ОС соответствующим образом. В Linux есть EXPORT_SYMBOL(name), который строит таблицу символов внутри самого ядра. [Обратите внимание, что это НЕ символы, сгенерированные gcc
или ld
, а символы, созданные макросами и обработанные в ядре.
Отредактируйте, чтобы уточнить, так как мне не хватило места в «комментарии»: существует два типа «перемещений»: внутренние — когда у вас есть абсолютные ссылки на вещи в вашем собственном модуле, например. указатели на строки, указатели на функции, таблицы переходов для операторов switch и т. д. — это должен быть просто вопрос сложения текущего значения со смещением того места, где фактически находится двоичный файл (конечно, виртуальный адрес). Другой - "внешние ссылки", например, когда ваш модуль вызывает, скажем, spinlock()
- это не реализовано внутри модуля, поэтому у него будет "внешняя ссылка". В этом случае будет запись о перемещении с именем «spinlock» и смещением того места, где в модуле происходит вызов spinlock. Теперь вам, очевидно, нужна таблица символов, чтобы найти, где в вашем ядре находится «спин-блокировка» [и если вы хотите быть действительно сложным, разрешите модулям ссылаться на другие модули, но я бы оставил это до тех пор, пока у вас не будет загрузки одного модуля в порядке первый!].
На самом деле ваш вопрос касается компоновщика. И ответ зависит от компоновщика, который вы используете.
Если это стандартный компоновщик ld
в gcc, попробуйте опцию "-Wl,-r".