Главная страница
Навигация по странице:

  • Используемые функции

  • Содержимое файла

  • Служебные переменные

  • Содержимое файла /src/makefile

  • Makefile, описание цели “image”

  • 3. 5Исследование готовых файлов 5


    Скачать 438.97 Kb.
    Название3. 5Исследование готовых файлов 5
    Дата12.09.2018
    Размер438.97 Kb.
    Формат файлаdocx
    Имя файла1. MiniOS doc.docx
    ТипДокументы
    #50456
    страница3 из 6
    1   2   3   4   5   6

    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

    4.2.3Компиляция исходных кодов ядра


    Это действие производит 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
    1   2   3   4   5   6


    написать администратору сайта