The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

10.6.1 Реализация совместно используемых библиотек в uClinux (libN.so)

10.6.1 Реализация совместно используемых библиотек в uClinux (libN.so)

Предыдущая  Содержание  Следующая V*D*V

Как мы уже видели, uClinux использует для исполняемых файлов формат bFLT. Загрузчик ядра uClinux выполняет работу по загрузке приложения в доступное место в памяти, настраивая необходимые разделы данных и кода. Напомним также, что если загружаемый файл bFLT имеет возможность выполнения на месте (XIP), то загрузчик ядра будет использовать один и тот же текстовый сегмент для несколько экземпляров приложения, а также создаст отдельные разделы данных для каждого экземпляра. Эта поддержка XIP используется в качестве базы для реализации в uClinux общих библиотек. Если текст не выполняем на месте, то общие библиотеки не могут работать. Это происходит потому, что общие текстовые страницы не могут существовать в памяти без поддержки MMU. Поэтому идея состоит в том, чтобы хранить их в общедоступном месте (флеш-памяти), и чтобы все программы обращались непосредственно к одному месту.

Для uClinux существует несколько реализаций различных типов совместно используемых библиотек. Мы обсудим реализацию динамических библиотек для m68k, которая использует файлы bFLT, известный в народе как метод libN.so. В этом методе общие библиотеки представляют собой бинарными файлы bFLT, но такие, которые содержат внутри определённый идентификатор библиотеки (ID). Это требует изменений в компиляторе, а также загрузчике. Каждый символ, на который есть ссылка в исполняемом модуле, имеет добавленный к нему определённый идентификатор библиотеки. Когда загрузчик должен обработать символ, он ищет ссылку с помощью ID, содержащегося в символе, и таким образом определяет необходимую библиотеку. Для упрощения поиска имена совместно используемых библиотек следуют определённому шаблону. Библиотека, которая имеет ID=X, имеет имя libX.so. Так что когда загрузчик должен обработать символ с ID=X в нём, он просто загружает файл /lib/libX.so.

Компилятор создаёт отдельный сегмент GOT и данных для приложения и для каждой библиотеки. Когда программа загружается, он обеспечивает, чтобы отдельные сегменты данных (в разделяемых библиотеках) были доступными с фиксированными смещениями от базового адреса. Уникальный идентификационный номер, выделенный для каждой библиотеки, используется для определения смещения, чтобы найти определённый сегмент данных. Приложение также должно использовать один и тот же метод обращений с использованием идентификатора и значение идентификатора 0 зарезервировано для приложения.

Поддержку совместно используемой библиотеки в ядре осуществляет компонент, выбираемый с помощью флага CONFIG_BINFMT_SHARED_FLAT. Основной структурой для поддержки разделяемой библиотеки в uClinux является  показанная ниже структура lib_info.

 

struct lib_info {

  struct {

    unsigned long start_code; /* Начало текстового сегмента */

    unsigned long start_data; /* Начало сегмента данных */

    unsigned long start_brk;  /* Конец сегмента данных */

    unsigned long text_len;   /* Длина текстового сегмента */

    unsigned long entry;      /* Начальный адрес для этого

                                 модуля */

    unsigned long build_date; /* Когда он был скомпилирован */

    short loaded;             /* Загружена ли эта библиотека? */

  } lib_list[MAX_SHARED_LIBS];

};

 

Макрос MAX_SHARED_LIBS определяется как 4, если CONFIG_BINFMT_SHARED_FLAT установлен, либо по умолчанию используется значение 1. Эта структура используется для хранения списка библиотек, загруженных для каждого приложения. Хотя теоретический предел максимального числа библиотек составляет 255 - 1, ядро определяет его как 4, что позволяет использовать 3 разделяемые библиотеки для каждого приложения. Значение ID равное 0 используется как относящееся к загружаемому приложению. Распознавание символа приложения, использующего разделяемую библиотеку, происходит внутри функции calc_reloc, показанной в Распечатке 10.5.

Обратите внимание на извлечение значения id, в которое будет переведено r, использующее id = (r >> 24) & 0xff. Изменения в компоновщике позволяют размещать значение id в старшем байте адреса символа. Например, если символ foo не определён в приложении, но определён в библиотеке с ID=3, то такой символ в данном приложении будет иметь запись форме 0x03XX_XXXX = (0x0300_0000 | адрес foo() в lib3.so). Таким образом, все внешние по отношению к приложению символы в своём старшем байте будут иметь id, соответствующий библиотеке.

Фактическая загрузка библиотеки в программную память происходит внутри функции load_flat_shared_library. Эта функция загружает файл /lib/libX.so используя обычную функции загрузчика файла типа "flat" load_flat_file, передавая соответствующее значение id=X. (* Обратите внимание, что во время выполнения двоичных файлов типа "flat", exec() использует эту же функцию с id=0.) Загрузчик двоичного файла "flat" поддерживает массив lib_info.lib_list[], чтобы отслеживать все загружаемые файлы, включая приложение, которое загружается по адресу 0. Загрузчик обеспечивает, чтобы были доступны все неопознанные/внешние символы, необходимые для исполнения.

Вышеописанная реализация является одной наиболее широко используемой для процессоров на основе m68k и была предложена Полом Дейлом. Для uClinux доступны и другие реализации совместно используемой библиотеки. XFLAT от Cadenux представляет собой другую реализацию совместно используемой библиотеки, широко используемую на процессорах ARM. FRV-uClinux также имеет реализацию разделяемой библиотеки. Каждая реализация было сделано с разными целями, решает разные проблемы.

 

Предыдущая  Содержание  Следующая