|
3. 5Исследование готовых файлов 5
4.2Файлы для сборки 4.2.1Скрипт компоновщика Задача компоновщика — объединить (обработать все связи) несколько скомпилированных объектных файлов (с расширениями .o) в исполняемый бинарный файл формата ELF.
В проекте используется компоновщик ld. Скрипт настроек компоновщика – link.ld В нем указывается точка входа ядра и разделы выходного исполняемого файла.
Определяются разделы:
.text – исполняемый код
.data – инициализированные данные (значения переменных)
.rodata - содержит константные значения, этот раздел «только для чтения»
.bss – неинициализированные данные Переменные без начальных значений, не занимает места в исполняемом файле, сохраняется только его размер. При запуске программы раздел заполняется нулями.
Компоновщик запускается автоматически из Make файла/src/makefile
Результат работы компоновщика детально рассмотрен в исследовании исполняемого файла MiniOS.
Описание работы компоновщика: http://habrahabr.ru/post/150327/
Используемые функции
ENTRY(start) - позволяет задать входную точку для нашего ядра
ALIGN(4096) – устанавливает выравнивание начала раздела по 4096 байт (4 КБ)
Содержимое файла
ENTRY(start)
SECTIONS
{
.text 0x100000 :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
} .data :
{
data = .; _data = .; __data = .;
*(.data)
*(.rodata)
. = ALIGN(4096);
} .bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
} end = .; _end = .; __end = .;
}
4.2.2Make файлы автоматизации сборки make — утилита, автоматизирующая процесс преобразования файлов из одной формы в другую. Чаще всего это компиляция исходного кода в объектные файлы и последующая компоновка в исполняемые файлы или библиотеки.
Утилита использует специальные make-файлы, в которых указаны зависимости файлов друг от друга и правила для их удовлетворения. На основе информации о времени последнего изменения каждого файла make определяет и запускает необходимые программы.
В проекте используется два make-файла:
• src/makefile — собирает бинарный исполняемый файл ядра см. Компиляция исходных кодов ядра
• makefile — основной файл, собирает загрузочный образ. Для сборки бинарного файла ядра использует предыдущий make файл. см. Сборка загрузочного образа
Синтаксис файлов описан в http://www.gnu.org/software/make/manual/make.html Это действие производит src/makefile. Здесь описано его содержимое.
Этот файл запускается только из makefile в папке проекта.
Результатом работы этого скрипта является исполняемый файл MiniOS.bin. Его структура описана в Таблица Структура исполняемого файла (MiniOS.bin).
Описание объектного файла формата ELF http://www.sco.com/developers/gabi/latest/contents.html
Служебные переменные:
• OBJFILES — список объектных файлов
• CFLAGS — ключи gcc для компиляции Си файлов
• LDFLAGS — ключи компоновщика ld
• ASFLAGS — ключи nasm для компиляции кода на ассемблере
Ключи gcc:
• Wall — включает вывод предупреждений
• fno-builtin — не использовать встроенные функции компилятора gcc
• fno-stack-protector — не использовать защиту стека от переполнения и выполнения произвольного кода (для защиты добавляются дополнительные интрукции)
• nostdinc — не искать заголовочные файлы в стандартных системных директориях
• nostdlib — не использовать стандартные библиотеки
• ggdb3 — добавить отладочную информацию 3 уровня (максимальную) для отладчика gdb
• m32 — генерировать 32 битный код (важно, если компилируется на 64 битной системе)
Ключи nasm:
• felf — ассемблировать в ELF-объектный файл
Используемые ключи компоновщика ld:
• Tlink.ld — использовать компоновочный скрипт из файла link.ld
• melf_i386 — эмулировать elf_i386
Содержимое файла /src/makefile
SOURCES=boot.o main.o monitor.o common.o descriptor_tables.o isr.o interrupt.o gdt.o timer.o
CFLAGS = -Wall -fno-builtin -fno-stack-protector -nostdinc -nostdlib -ggdb3 -m32
LDFLAGS=-Tlink.ld -melf_i386
ASFLAGS=-felf all: $(SOURCES) link clean:
rm -f * *.o MiniOS.bin MiniOS.bin.dbg link:
ld $(LDFLAGS) -o MiniOS.bin $(SOURCES)
cp MiniOS.bin MiniOS.bin.dbg
strip MiniOS.bin .s.o:
nasm $(ASFLAGS) $
4.2.4Сборка загрузочного образа (hdd.img) Сборку производит make файл в папке проекта. В результате получим загрузочный образ, который может быть записан на flash, или диск.
См. Error: Reference source not found
Makefile, описание цели “image”:
1. Создаем пустой файл, заполняем его нулями
dd (dataset definition) — программа UNIX, предназначенная для копирования файлов
Параметры:
if=файл — читает данные из файла вместо стандартного ввода of =файл - пишет данные в файл вместо стандартного ввода bs=n - размер блока count - сколько блоков скопировать 512*16065 байт - минимальный размер, с которым может работать утилита fdisk
dd if=/dev/zero of=./hdd.img bs=512 count=16065 1>/dev/null 2>&1
2. Монтируем этот файл на устройство loop1
losetup /dev/loop1 ./hdd.img
3. Производим с помощью утилиты fdisk создание начального загрузочного раздела FAT32
Вводим команды: с :- Переключения флага совместимости DOS u :- Изменения единиц измерения экрана / содержимого (цилиндры / секторы) - в цилиндры n :- Добавить новый раздел p :- Тип раздела – Первичный 1 - номер раздела - первый цилиндр 1
a :- Переключать загрузочный флаг (включаем на первом разделе) t :- Изменить тип раздела (t change a partition type) c :- тип W95 FAT32 (LBA) w :- Таблица записи на диск и выход
(echo c; echo u; echo n; echo p; echo 1; echo ; echo ; echo a; echo t; echo c; echo w;) | fdisk /dev/loop1 1>/dev/null 2>&1 || true
4. Монтируем сам раздел на /dev/loop2 (смотрим в таблице разделов начало и конец раздела)
losetup /dev/loop2 ./hdd.img \ --offset `echo \`fdisk -lu /dev/loop1 | sed -n 9p | awk '{print $$3}'\`*512 | bc` \ --sizelimit `echo \`fdisk -lu /dev/loop1 | sed -n 9p | awk '{print $$4}'\`*512 | bc`
Отмонтируем раздел /dev/loop1
losetup -d /dev/loop1
5. Форматируем раздел в FAT
mkdosfs /dev/loop2
6. Копируем ядро kernel.bin и файлы загрузчика Grub на этот раздел (монтируем раздел в папку tempdir)
@mkdir -p tempdir @mount /dev/loop2 tempdir @mkdir tempdir/boot @cp -r grub tempdir/boot/ @cp ./src/kernel.bin tempdir/ @cp ./initrd tempdir/ @sleep 1 @umount /dev/loop2 @rm -r tempdir @losetup -d /dev/loop2
7. Устанавливаем загрузчик Grub batch - включить неинтерактивный режим
@echo "device (hd0) hdd.img \n \ root (hd0,0) \n \ setup (hd0) \n \ quit\n" | grub --batch 1>/dev/null
|
|
|