вторник, 10 сентября 2013 г.

BeagleBone Black - Install Gentoo part 1: make microSD card, make & install u-Boot

Это вторая статья посвященная установке Gentoo Linux на BeagleBone Black. В этой части мы рассмотрим подготовку карты памяти для запуска Gentoo Linux, и заодно настроим, соберём и установим универсальный загрузчик Das U-Boot. Для данного раздела нам понадобится то же аппаратное обеспечение, что и в первой статье.

Подготовка карты памяти microSD

Начнем мы с подготовки носителя, эта схема противоположна схеме изложенной в оригинальном мануале. Однако лучше иметь готовый для использования носитель информации, так как после сборки U-Boot лучше всего убедиться что всё пошло именно так как мы и планировали.

Немного теории
Вообще, как известно из статьи про загрузку МП загрузка происходит в 2 этапа. Сначала идёт начальная инициализация процессора и периферии встроенным загрузчиком, который заодно находит источник загрузки и либо выполняет, либо скачивает с него основной загрузчик который и отвечает в дальнейшем за инициализацию периферии и прочее, включая загрузку ядра ОС. Так вот, для того чтобы встроенный загрузчик мог запускать основной ему необходимо его откуда-то взять. А для этого в соответствии со статьёй необходим специально подготовленный носитель. В этом мануале указана ручная подготовка носителя, однако в дальнейшем я выложу переработанную версию скрипта для автоматического разбиения носителя.

Планирование
Все примеры я буду показывать изначально на базе карты памяти microSD HC объёмом в 16 ГБ, поэтому некоторые размеры необходимо будет пересчитать исходя из вашего носителя. Итак подключив носитель к ПК и запустив утилиту fdisk мы получим следующую картину:

# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Команда (m для справки): p

Disk /dev/sdb: 15.7 GB, 15707668480 bytes, 30679040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00000000

Устр-во Загр     Начало       Конец       Блоки   Id  Система
/dev/sdb1            8192    30679039    15335424    c  W95 FAT32 (LBA)

В большинстве случаев из магазина карта памяти выглядит именно так. Удалим с неё раздел с FAT32, который нам не понадобится:

Команда (m для справки): d
Selected partition 1
Partition 1 is deleted

Разметка
Для нашего диска потребуется 2 раздела - первый загрузочный, в нём будет расположен U-Boot его размер примерно 50 МБ, а другой основной в котором будет располагаться основная система, ему отдадим всё оставшееся пространство:

Команда (m для справки): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
Номер раздела (1-4, default 1): 
Первый sector (2048-30679039, по умолчанию 2048): 
Используется значение по умолчанию 2048
Last sector, +sectors or +size{K,M,G} (2048-30679039, по умолчанию 30679039): +50M
Partition 1 of type Linux and of size 50 MiB is set

Команда (m для справки): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): 
Using default response p
Номер раздела (2-4, default 2): 
Первый sector (104448-30679039, по умолчанию 104448): 
Используется значение по умолчанию 104448
Last sector, +sectors or +size{K,M,G} (104448-30679039, по умолчанию 30679039): 
Используется значение по умолчанию 30679039
Partition 2 of type Linux and of size 14,6 GiB is set

Также не забываем дать для загрузочной партиции марку что она загрузочная и тип раздела - FAT16:

Команда (m для справки): a
Номер раздела (1,2, default 2): 1

Команда (m для справки): t
Номер раздела (1,2, default 2): 1
Hex code (type L to list all codes): 6

WARNING: If you have created or modified any DOS 6.xpartitions, please see the fdisk manual page for additionalinformation.

Changed type of partition 'Linux' to 'FAT16'

Размер последней партиции для вашего носителя может быть другим. Далее необходимо внести изменения на диск:

Команда (m для справки): w
Таблица разделов была изменена!

Вызывается ioctl() для перечитывания таблицы разделов.
Синхронизируются диски.

После того как мы сделали разделы необходимо им задать формат, так для загрузочного раздела это будет FAT16, а для основного Ext2:

# mkfs.vfat -F16 -n "boot" /dev/sdb1
mkfs.fat 3.0.22 (2013-07-19)
jane BBB # mkfs.ext2 -L "rootfs" /dev/sdb2
mke2fs 1.42.7 (21-Jan-2013)
Filesystem label=rootfs
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
956592 inodes, 3821824 blocks
191091 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=3917479936
117 block groups
32768 blocks per group, 32768 fragments per group
8176 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

Итак, у нас есть носитель, который можно использовать под свои цели. Т.е мы переходим к установке основного загрузчика.

U-Boot

Основной загрузчик это ядро системы на начальном этапе инициализации, без него невозможен запуск ядра OC на системах не имеющих BIOS, т.к. он производит инициализацию периферии.

Сборка и установка
После перехода в рабочую директорию (у меня это /root/BBB/), необходимо скачать исходный код загрузчика:

# wget ftp://ftp.denx.de/pub/u-boot/u-boot-2013.04.tar.bz2
И распаковать его
# tar xjpf u-boot-2013.04.tar.bz2 && cd u-boot-2013.04

Т.к. по умолчанию загрузчик приспособлен только под плату am335x-evm, то необходимо его доработать, скачав патчи с репозитория на github:

# git clone https://github.com/beagleboard/meta-beagleboard.git
Не забыв применить полученные патчи
# for i in meta-beagleboard/common-bsp/recipes-bsp/u-boot/u-boot-denx/00*; do patch -p1 < $i; done

Итак, получив готовый к использованию исходный код загрузчика, соберём его для получения загрузочного образа:

# make ARCH=arm CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi- am335x_evm_config
# make ARCH=arm CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi-

Если сборка прошла без ошибок, то можно проверить работу загрузчика установив первую его часть - предварительный загрузчик, оформленный в виде MLO образа и образ загрузчика. Для этого примонтируем первый раздел нашего носителя к заранее созданной директории и скопируем туда файл MLO и образ загрузчика u-boot.img, после можно отмонтировать раздел:

# mount /dev/sdb1 p1
# cp u-boot-2013.04/{MLO,u-boot.img} p1/
# umount p1

Небольшое отступление
Очень часто разработчики любой системы используют интересные особенности чтобы обойти ограничения тех или иных компонентов.

Этим ограничением стал размер статического ОЗУ у AM335x для выполнения первичного загрузчика.
Если внимательно просмотреть схему памяти то можно увидеть что у нас всего 64 кБ ОЗУ.
Однако размер образа MLO составляет 108 кБ (в моём случае, или 98 в случае загрузчика поставляемого вместе с платой и прошитого в eMMC). Обратившись к структуре загрузочной памяти можно увидеть что её объём составляет 128 кБ (адреса с 0x402f0400 по 0x4030ffff).
Это происходит потому что при инициализации МП объединяет её с памятью L3 кэша (называемого ещё L3 RAM), которая также имеет объём в 64 кБ: {{ Public RAM Memory Map }}

В памяти присутствует область отведённая под хранение загруженного образа исполняемого кода - до 110 кБ свободного места. Также присутствует 
выделенная область под стек - 6 кБ. А также прочие служебные структуры.

Итак что у нас происходит. Есть загруженный с карты памяти образ который целиком находится в нашей озу. И есть 2 варианта работы с ним.

Путь первый.
Так было сделано в StarterWare от TI. Размер образа 43276 байт. первые 2 слова которые и составляют заголовок у нас 0x0000a90c и 0x402f0400.
Размер как подсказывает КО и второй байт адрес совпадающий с тем по которому хранится образ. Всё просто - запустил: работает.

Путь второй.
Так было сделано в Das U-Boot. Размер образа 99904 (для образа поставляемого с платой). Тут всё оригинальней чем кажется. Причина в следующем: первые два байта имеют значения 0x00000040 и 0x0000000c. Человек неподготовленный может воспринять это как неправильные адреса инициализации, однако этому есть логическое объяснение - обновленный код инициализации. Более подробно про эту особенность вы можете узнать из моей статьи про обновлённую инициализацию AM335x.

Загрузка
Инициализация происходит начиная с SPL (код находящийся в MLO):

Далее в случае с U-Boot код проводит первичную инициализацию периферии и загружает в выделенный регион внешней ОЗУ дополнительный образ: u-boot.img. Который и выполняется:
Послесловие
В конце загрузчик пожаловался на то что не смог найти свой конфигурационный файл и образ ядра, который находится у нас на другом разделе. Ну и на последок короткое видео загрузки платы:

Итог
На этом я заканчиваю повествование, у нас теперь в наличии носитель с работающим основным загрузчиком, следующим этапом у нас будет сборка и установка ядра системы.

Комментариев нет:

Отправить комментарий