Журнал LinuxFormat - перейти на главную

LXF165-166: Raspberry Pi: Стро­им ди­ст­ри­бу­тив

Материал из Linuxformat
Версия от 02:11, 3 ноября 2018; Olkol (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск


Raspberry Pi За­пус­ка­ем свой кар­ман­ный ком­пь­ю­тер как нам угод­но

Содержание

Raspberry Pi: Cвой ди­ст­ри­бу­тив

Те­перь, что­бы взять­ся за де­ло, не нуж­но ждать, по­ка Raspberry Pi за­гру­зит­ся. Джон Лэйн соз­да­ет поль­зо­ва­тель­ский ди­ст­ри­бу­тив со всем не­об­хо­ди­мым.

(thumbnail)
Наш эксперт. За­бре­дя в Linux еще в 1994 го­ду, Джон Лэйн так в нем и ос­тал­ся, и за­был, ко­гда в по­след­ний раз поль­зо­вал­ся Windows. Он пи­шет и кон­суль­ти­ру­ет по Linux и от­кры­то­му ПО.

На этом уро­ке мы по­про­бу­ем соз­дать соб­ст­вен­ный ди­ст­ри­бу­тив для Raspberry Pi, где бу­дет толь­ко то, что вам нуж­но. Вы мо­же­те за­хо­теть вклю­чать в него дру­гие па­ке­ты, ме­нять на­строй­ки, воз­мож­но, да­же из­менить яд­ро. Об­раз ди­ст­ри­бу­ти­ва мож­но бу­дет за­пи­сать на SD-кар­ту и за­гру­зить с нее Pi или за­гру­зить его на ком­пь­ю­те­ре че­рез эму­ля­тор. Соз­да­вать свой об­раз мож­но пря­мо на Pi, но это бу­дет очень мед­лен­но, по­это­му мы за­од­но рас­смот­рим, как ском­пи­ли­ро­вать и да­же за­пустить ARM-код на ва­шем ком­пь­ю­те­ре.

Конеч­но, на­строй­ки мож­но бы­ло бы де­лать пря­мо в ра­бо­таю­щей сис­те­ме, но это опас­но, по­то­му что из-за од­ной ошиб­ки все мо­жет рух­нуть. Вдо­ба­вок эти ша­ги до­воль­но слож­но воспро­из­ве­сти и труд­но ав­то­ма­ти­зи­ро­вать.

Пер­вым де­лом нуж­но об­за­вес­тись под­хо­дя­щи­ми ин­ст­ру­мен­та­ми. Для на­ше­го уро­ка мы возь­мем Arch Linux, так как это пре­крас­ный ди­ст­ри­бу­тив, доступ­ный и для ПК, и для Pi. Бу­дем пред­по­ла­гать, что ис­поль­зу­ет­ся по­след­няя офи­ци­аль­ная вер­сия Arch Linux и что она об­нов­ле­на. За­гру­зи­те Arch Linux на сво­ем Pi и убе­ди­тесь, что необ­хо­ди­мые ути­ли­ты и дру­гие па­ке­ты уста­нов­ле­ны:

  1. pacman -Syu
  1. pacman -S base-devel python2 git parted dosfstools

Вы­би­ра­ем се­бе при­клю­че­ние

Пер­вый шаг на пу­ти к соб­ст­вен­но­му ди­ст­ри­бу­ти­ву – ре­шение, что в нем долж­но при­сут­ст­во­вать. Ра­зум­ный ва­ри­ант для на­ча­ла – ба­зо­вая груп­па па­ке­тов Arch Linux (base). Бе­ри­те ее и до­бав­ляйте и уда­ляй­те необ­хо­ди­мые па­ке­ты. Не­нуж­ные па­ке­ты яд­ра сто­ит уда­лить и до­ба­вить со­от­вет­ст­вую­щие па­ке­ты Raspberry Pi.

Сбор­ка но­во­го яд­ра необ­хо­ди­ма, ес­ли требуется до­ба­вить но­вые воз­мож­но­сти. Так­же сто­ит от­клю­чить ненуж­ные оп­ции яд­ра, что­бы умень­шить его раз­мер (учи­ты­вая ог­раничен­ные ре­сур­сы па­мя­ти у ма­лы­ша Pi). Учи­ты­вая то, что ком­пи­ля­ция яд­ра обыч­но занима­ет бо­лее де­ся­ти ча­сов, нам ну­жен аль­тер­на­тив­ный ме­тод. Одна из альтернатив – ис­поль­зо­вание кросс-ком­пи­ля­то­ра; мож­но так­же ис­поль­зо­вать distcc, но с ним все рав­но по­на­до­бит­ся кросс-ком­пи­ля­тор, по­то­му что «сер­вер» distcc дол­жен генери­ро­вать код ARM. Я ре­шил вы­полнить кросс-ком­пи­ля­цию яд­ра, и на нашем уро­ке опи­шу оба ме­то­да.

В иду­щих ниже ко­ман­дах для по­лу­чения спи­ска па­ке­тов груп­пы base ис­поль­зу­ет­ся Pacman, менед­жер па­ке­тов Arch Linux. За­тем уда­ля­ют­ся ненуж­ные па­ке­ты и до­бав­ля­ют­ся яд­ро RPi и про­шив­ка. Для до­бав­ления или уда­ления все­го про­че­го в со­от­вет­ст­вии со свои­ми по­треб­но­стя­ми (на­при­мер, вы мо­же­те за­хо­теть до­ба­вить openssh), употреби­те свой лю­би­мый тек­сто­вый ре­дак­то­р.

$ pacman -Sg base | awk ‘{print $2}’ | grep -v “^\(linux\|kernel\)” | tr ‘\n’ ‘ ‘ > base_packages

$ sed -i -e ‘s/$/linux-raspberrypi linux-headers-raspberrypi raspberrypi-firmware/’ base_packages

Воо­ру­жив­шись спи­ском па­ке­тов, уста­но­вим па­ке­ты для но­во­го об­раза. С ути­ли­той mkarchroot сде­лать это лег­ко. Она уста­но­вит па­ке­ты в под­ка­та­лог, и его вы за­тем пре­об­ра­зуе­те в об­раз дис­ка.

# mkarchroot archroot $(cat base_packages)

Соз­да­ст­ся но­вый под­ка­та­лог archroot, со­дер­жа­щий все необ­хо­ди­мое для пол­ной сис­те­мы. За­тем его мож­но сде­лать корневым, и это долж­но ра­бо­тать; на прак­ти­ке, это при­дет­ся де­лать при лю­бых из­менениях, на­при­мер, для за­дания па­ро­ля root или для до­бав­ления учет­ных за­пи­сей поль­зо­ва­те­лей.

Мы соз­да­дим об­раз сис­те­мы в фай­ле. Его мож­но соз­дать и пря­мо на SD-кар­те, но иметь об­раз по­лез­но, по­то­му что его мож­но бы­ст­ро пе­ре­за­пи­сать на кар­ту или за­гру­зить в эму­ля­то­ре да­же без за­пи­си на кар­ту. У яд­ра есть воз­мож­ность «пет­ли [loop]», при ко­то­рой файл рас­смат­ри­ва­ет­ся как фи­зи­че­­ский диск, ко­то­рый мож­но раз­бить на фай­ло­вые сис­те­мы. Для та­ко­го досту­па к фай­лу в ка­та­ло­ге /dev соз­да­ет­ся обыч­ный файл уст­рой­ст­ва.

Об­раз дол­жен быть доста­точ­но боль­шим для раз­ме­щения фай­ло­вых сис­тем, но и доста­точ­но ма­лень­ким, что­бы по­мес­тить­ся на SD-кар­ту. Мы соз­да­дим об­раз раз­ме­ром 2 ГиБ [здесь и да­лее ис­поль­зу­ют­ся дво­ич­ные при­став­ки; их от­ли­чие от со­от­вет­ст­вую­щих де­ся­тич­ных в том, что ум­но­жение про­из­во­дит­ся на сте­пени двой­ки; та­ким об­ра­зом, 1 КиБ (ки­би­байт) = 210 = 1024 бай­та, 1 МиБ (ме­би­байт) = 220 = 1 048 576 байт, 1 ГиБ (ги­би­байт) = 230 = 1 073 741 824 бай­та, – прим. пер.], та­ко­го же раз­ме­ра, как и офи­ци­аль­ный об­раз. Убе­ди­тесь, что мо­дуль яд­ра loop за­гру­жен, соз­дай­те файл и свя­жи­те с ним уст­рой­ст­во «пет­ли»:

# modprobe loop

$ truncate -s 2G myimage

$ device=$(losetup -f)

# losetup $device myimage

Мы поль­зу­ем­ся losetup два­ж­ды: для вы­де­ления имени уст­рой­ст­ву «пет­ли», обыч­но /dev/loop0, и для его соз­дания (имя уст­рой­ст­ва хранит­ся в пе­ре­мен­ной, что­бы об­ра­тить­ся к нему поз­же). Раз­де­лы на об­ра­зе долж­ны быть раз­би­ты осо­бым об­ра­зом: пер­вый раз­дел с фай­ло­вой сис­те­мой FAT16 дол­жен со­дер­жать за­гру­зоч­ные фай­лы и об­раз яд­ра. Вто­рой раз­дел ис­поль­зу­ет­ся для корневой фай­ло­вой сис­те­мы и дол­жен быть ти­па ext4. Ес­ли необ­хо­дим раз­дел под­кач­ки, его мож­но соз­дать треть­им. За­гру­зоч­ная про­шив­ка Raspberry Pi ищет таб­ли­цу раз­де­лов глав­ной за­гру­зоч­ной за­пи­си ти­па MS-DOS (в от­ли­чие от BIOS ПК, она не за­пуска­ет за­груз­чик из глав­ной за­гру­зоч­ной за­пи­си). Для соз­дания таб­ли­цы раз­де­лов на фай­ле об­раза упот­ре­би­те ко­ман­ду parted:

# parted -s $device mktable msdos

При соз­дании раз­де­лов сто­ит вы­равнивать их по бло­кам сти­рания на SD-кар­те. Де­лать это не обя­за­тель­но, но ре­ко­мен­ду­ет­ся. Ре­ко­мен­дуе­мый раз­мер об­лас­ти сти­рания для боль­шин­ст­ва карт – 4 МиБ, но мож­но про­ве­рить его и для кон­крет­ной кар­ты (в бай­тах):

$ cat /sys/class/block/mmcblk0/device/preferred_erase_size

Ес­ли этот раз­мер ра­вен 4 МиБ, то вы­равнивание про­из­во­дит­ся че­рез ка­ж­дые 8192 сек­то­ра (в сек­торе 512 байт, по­это­му чис­ло сек­то­ров – 4 МиБ/512). Значит, раз­де­лы долж­ны на­чи­нать­ся с сек­то­ра, крат­но­го 8192: в пер­вом блоке сти­рания 8192 сек­то­ра (0..8191), во вто­ром – сле­дую­щие 8192 сек­то­ра (8192..16383) и т. д. Сек­тор 0 ­ре­зер­ви­ро­ван для таб­ли­цы раз­де­лов, по­это­му пер­вый раз­дел дол­жен на­чи­нать­ся со сле­дую­ще­го вы­ровнен­но­го сек­то­ра, это сек­тор 8192. Хо­ро­ший раз­мер для за­гру­зоч­но­го раз­де­ла – 40 МиБ, то есть 81 920 сек­то­ров. Это­го доста­точ­но для раз­ме­щения за­гру­зоч­ных фай­лов, и к то­му же раз­дел за­кан­чи­ва­ет­ся на границе бло­ка сти­рания. Соз­дай­те за­гру­зоч­ный раз­дел, на­чи­ная с сек­то­ра 8192 и за­кан­чи­вая сек­то­ром 90111 (8192+81920-1):

# parted -s $device unit s mkpart primary fat32 8192 90111

Ес­ли вам ну­жен раз­дел под­кач­ки, вы­де­ли­те под него немно­го мес­та (о необ­хо­ди­мо­сти раз­де­ла под­кач­ки на SD-кар­те сто­ит по­ду­мать из-за мед­лен­ной ско­ро­сти и ог­раничен­но­го ко­ли­че­­ст­ва опе­ра­ций за­пи­си но­си­те­ля). На­при­мер, мы соз­да­дим раз­дел под­кач­ки раз­ме­ром 256 МиБ (это 524 288 сек­то­ра или 64 бло­ка за­пи­си).

Наш об­раз раз­ме­ром 2 ГиБ со­дер­жит 4 194 304 сек­то­ра (2 ГиБ / 512 = 4 194 304). Так как ну­ме­ра­ция сек­то­ров на­чи­на­ет­ся с 0, то по­следним сек­то­ром бу­дет 4 194 303. Для корнево­го раз­де­ла мож­но ис­поль­зо­вать все про­стран­ст­во ме­ж­ду раз­де­ла­ми boot и swap, он начнет­ся с вы­ровнен­но­го сек­то­ра 90 112 и за­кон­чит­ся на границе вы­равнивания, оста­вив раз­де­лу под­кач­ки 56 МиБ. Соз­да­дим их:

# parted $device unit s mkpart primary ext2 90112 3670015
# parted $device unit s mkpart primary linux-swap 3670016 4194303

При же­лании мож­но вы­вес­ти таб­ли­цу раз­де­лов ко­ман­дой parted -s $device unit s print. Те­перь соз­да­дим фай­ло­вые сис­те­мы. Уст­рой­ст­во «пет­ли» нуж­но пе­ре­соз­дать за­но­во, что­бы для раз­де­лов бы­ли соз­да­ны файл уст­ройств (это де­ла­ет па­ра­метр -P):

# losetup -d $device
# device=$(losetup -f)
# losetup -P $device myimage

По­ду­ма­ем о вы­равнивании внут­ренней струк­ту­ры фай­ло­вых сис­тем. В случае файловой сис­те­мы FAT нуж­но знать раз­мер ее таб­ли­цы размещения фай­лов (File Allocation Table – FAT), для чего при­дет­ся соз­дать фай­ло­вую сис­те­му:

mkfs.vfat -I -F 16 -n boot -s 16 -v ${device}p1 | grep “FAT size”

Струк­ту­ра фай­ло­вой сис­те­мы FAT по­ка­за­на на схе­ме. Для вы­равнивания из­мените раз­мер за­ре­зер­ви­ро­ван­но­го про­стран­ст­ва с це­лью вы­ров­нять на­ча­ло об­лас­ти дан­ных. Раз­мер это­го про­стран­ст­ва дол­жен со­от­вет­ст­во­вать ре­ко­мен­дуе­мо­му раз­ме­ру об­лас­ти сти­рания за вы­че­том раз­ме­ров двух таб­лиц вы­де­ления фай­лов. Ес­ли раз­мер FAT ра­вен 32 сек­то­рам, то раз­мер за­ре­зер­ви­ро­ван­но­го про­стран­ст­ва бу­дет ра­вен 8192 – (2 * 32) = 8128 сек­то­рам. Сно­ва соз­дай­те фай­ло­вую сис­те­му с ис­поль­зо­ванием этой ин­фор­ма­ции:

mkfs.vfat -I -F 16 -n boot -s 16 -R 8128 -v ${device}p1

Для корнево­го раз­де­ла ис­поль­зуй­те фай­ло­вую сис­те­му ext4. Бла­го­да­ря раз­ме­ру бло­ка в 4 КиБ она вы­равнива­ет­ся по бло­кам сти­рания. Соз­да­вай­те ее без жур­на­ли­ро­вания, так как это умень­шит ко­ли­че­­ст­во опе­ра­ций за­пи­си на SD-кар­ту:

$ mkfs.ext4 -O has_journal -L root ${device}p2

Смон­ти­руй­те фай­ло­вые сис­те­мы и ско­пи­руй­те фай­лы в со­от­вет­ст­вую­щее ме­сто из ка­та­ло­га archroot. За­гру­зоч­ный раз­дел мон­ти­ру­ет­ся в ка­та­лог /boot на корневом раз­де­ле, что­бы за­гру­зоч­ные фай­лы по­мес­ти­лись на вер­ный раз­дел:

# mount ${device}p2 /mnt
# mkdir /mnt/boot
# mount ${device}p1 /mnt/boot
# (cd archroot ; cp -a * /mnt)
# umount /mnt/boot /mnt

Те­перь за­пи­ши­те об­раз на SD-кар­ту (ес­ли на ней на­хо­дит­ся корневая сис­те­ма Pi, нуж­но ско­пи­ро­вать изо­бра­жение на дру­гой ком­пь­ю­тер че­рез кард-ри­дер):

dd if=myimage of=/dev/mmcblk0 bs=4M

Вы­клю­чи­те Pi, вставь­те но­вую кар­ту и за­гру­зи­тесь. Ли­бо ско­пи­руй­те об­раз на ком­пь­ю­тер и за­пусти­те его в эму­ля­то­ре...

Па­кет linux-raspberry, ко­то­рый мы вклю­чи­ли в об­раз, со­дер­жит офи­ци­аль­ный об­раз яд­ра, но из­менить его до­воль­но про­сто. Для его пре­вра­щения в ис­пол­няе­мый об­раз яд­ра нам по­на­до­бят­ся ис­ход­ный код яд­ра и ком­пи­ля­тор.

Обыч­но ком­пи­ля­тор фор­ми­ру­ет ис­пол­няе­мый код для то­го про­цес­со­ра, на ко­то­ром за­пу­щен; но с по­мо­щью кросс-ком­пи­ля­то­ра мож­но соз­да­вать ис­пол­няе­мые фай­лы для раз­лич­ных про­цес­со­ров. То есть мож­но восполь­зо­вать­ся ре­сур­са­ми бо­лее мощ­но­го «же­ле­за» x86 и ском­пи­ли­ро­вать код для ар­хи­тек­ту­ры ARM Raspberry Pi го­раз­до бы­ст­рее, чем на са­мом Pi (ком­пи­ля­ция яд­ра 3.2.27 на Pi занима­ет несколь­ко ча­сов, а с кросс-ком­пи­ля­то­ром на Intel i7 на нее ухо­дит две с по­ло­ви­ной ми­ну­ты!). По­это­му на вре­мя от­ло­жи­те Pi в сто­ро­ну и при­го­товь­тесь к ком­пи­ля­ции на сво­ем ком­пь­ю­те­ре. «Род­ной» ком­пи­ля­тор для на­шей ар­хи­тек­ту­ры – gcc, а вер­сия кросс-ком­пи­ля­то­ра для ARM на­зы­ва­ет­ся arm-linux-gnueabigcc. Его нет в ре­по­зи­то­ри­ях, но его про­сто со­брать с Yaourt (еще од­на ути­ли­та для ра­бо­ты с ре­по­зи­то­рия­ми):

yaourt -S arm-linux-gnueabi-gcc

Не от­хо­ди­те от тер­ми­на­ла, что­бы от­ве­тить на мно­го­чис­лен­ные во­про­сы Yaourt (вы­бе­ри­те «нет» на во­прос об из­менении PKG­BUILD и «да» на во­прос о том, хо­ти­те ли вы со­брать или уста­но­вить па­кет; сбор­ка про­хо­дит по эта­пам, по­это­му всегда вы­би­рай­те «да» для за­ме­ны кон­флик­тую­щих па­ке­тов).

При­вет, мир!

Пе­ред тем как дви­гать­ся даль­ше, по­жа­луй, сто­ит про­ве­рить кросс-ком­пи­ля­тор. По мо­де ис­тин­ных про­грам­ми­стов мы на­пи­шем ко­рот­кий при­мер «При­вет, мир». Соз­дай­те но­вый файл hello.c:

#include <stdio.h>

int main ()

{

printf(“Hello, World!\n”);

return 0;

}

Ском­пи­ли­руй­те его для ARM и про­верь­те, что тип ука­зан вер­но:

$ arm-linux-gnueabi-gcc -o hello hello.c

$ file hello

hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.27,not stripped

Ес­ли ско­пи­ро­вать файл “hello” на Pi, он дол­жен там за­пус­тить­ся:

$ ./hello

Hello, World!

Ес­ли все про­шло успеш­но, то у нас есть кросс-ком­пи­ля­тор, и мы мо­жем пе­рей­ти к ком­пи­ля­ции поль­зо­ва­тель­ско­го яд­ра.

$ git clone --depth 1 git://github.com/raspberrypi/linux.git

$ cd linux

$ ssh root@alarmpi zcat /proc/config.gz > .config

$ make -j 8 ARCH=arm CROSS_COMPILE=arm-linuxgnueabi-menuconfig -k

Мы за­гру­жа­ем ис­ходники яд­ра из github. Бла­го­да­ря па­ра­мет­ру --depth 1 за­гру­жа­ет­ся толь­ко по­след­няя вер­сия, а не вся ис­то­рия из­менений – так го­раз­до бы­ст­рее. За­тем мы ко­пи­ру­ем на­строй­ки те­ку­ще­го яд­ра Raspberry Pi в файл .config и от­кры­ва­ем его в ре­дак­то­ре ме­ню яд­ра. В нем мож­но из­менить кон­фи­гу­ра­цию яд­ра со­гласно своим пожелания­м. За­кон­чив, вый­ди­те из ре­дак­то­ра, со­хранив об­нов­лен­ный файл .config. Те­перь все го­то­во к сбор­ке яд­ра и мо­ду­лей (ко­то­рые мы уста­но­вим в под­ка­та­лог):

$ make -j 8 ARCH=arm CROSS_COMPILE=arm-linuxgnueabi- -k

$ mkdir -p modules

$ make -j 8 -k ARCH=arm CROSS_COMPILE=arm-linuxgnueabi- modules_install INSTALL_MOD_PATH=modules

Когда сбор­ка за­кон­чит­ся, вы смо­же­те за­гру­зить но­вый об­раз яд­ра и мо­ду­ли в Pi и пе­ре­за­гру­зить его (ес­ли хо­ти­те, сде­лай­те пе­ред этим ре­зерв­ную ко­пию ста­ро­го яд­ра и ка­та­ло­гов с мо­ду­ля­ми):

$ scp arch/arm/boot/Image root@alarmpi:/boot/kernel.img

$ cd modules/lib/modules

$ tar cJf - * | ssh root@alarmpi ‘(cd /usr/lib/modules; tar xjf -)’

$ ssh root@alarmpi reboot

Его так­же мож­но уста­но­вить в де­ре­во archroot пе­ред соз­данием об­раза. Ско­пи­руй­те arch/arm/boot/Image в archroot/boot/kernel.img и modules/lib/modules в archroot/usr/lib.

А так­же эму­ля­тор

Этот об­раз так­же мож­но за­пустить в эму­ля­то­ре ARM и по­лу­чить вир­ту­аль­ный Raspberry Pi на сво­ем ком­пь­ю­те­ре x86. Эму­ля­тор про­цес­со­ра, умею­щий за­пускать код ARM на ком­пь­ю­те­ре с ар­хи­тек­ту­рой x86 – QEMU, а уста­нав­ли­ва­ет­ся он ко­ман­дой pacman -S qemu. Соз­дай­те ка­та­лог и ско­пи­руй­те ту­да свой об­раз. Вам так­же по­на­до­бит­ся поль­зо­ва­тель­ское яд­ро спе­ци­аль­но для эму­ля­то­ра. Под­хо­дя­щее яд­ро (kernel-qemu) най­дет­ся в ар­хи­вах – ско­пи­руй­те его ту­да же, где на­хо­дит­ся об­раз. Те­перь мож­но за­пустить эму­ля­тор ко­ман­дой:

qemu-system-arm -machine versatilepb -cpu arm1176 -m 256 \

-no-reboot -serial stdio -kernel kernel-qemu \

-append “root=/dev/sda2 panic=1” -hda myimage

С эму­ля­то­ром мож­но сде­лать еще од­ну хит­рость: за­пускать код ARM пря­мо с команд­ной стро­ки x86. Это на­зы­ва­ет­ся про­зрач­ной эму­ля­ци­ей; при этом для вы­полнения лю­бо­го ис­пол­няе­мо­го ко­да ARM в QEMU ис­поль­зу­ет­ся воз­мож­ность яд­ра binfmt-misc. Но для это­го нуж­но сде­лать еще кое-что...

Пре­ж­де все­го, у вас дол­жен быть доступ к /proc/sys/fs/binfmt_misc. Ес­ли его нет, смон­ти­руй­те ее:

  1. mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

За­тем нуж­но за­ре­ги­ст­ри­ро­вать дво­ич­ный фор­мат ARM в яд­ре. Так мы ска­жем ему, как фор­мат рас­по­зна­ет­ся и что с ним де­лать. Рас­по­зна­вание про­из­во­дит­ся по про­вер­ке за­го­лов­ка фай­ла. Для ре­ги­ст­ра­ции ис­пол­няе­мых фай­лов ARM вы­полните ко­ман­ду:

echo ‘:arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\

x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemuarm-static:’ > /proc/sys/fs/binfmt_misc/register

По­сле это­го при лю­бой по­пыт­ке за­пуска дво­ич­ных фай­лов ARM вме­сто это­го бу­дет за­пу­щен /usr/bin/qemu-arm-static. В ка­че­­ст­ве па­ра­мет­ра ему пе­ре­да­ет­ся путь к дво­ич­но­му фай­лу ARM. В ре­зуль­та­те QEMU про­зрач­но вы­пол­ня­ет дво­ич­ный файл ARM. По­мес­тив /usr/bin/qemu-arm-static в де­ре­во об­раза, вы смо­же­те пе­ре­клю­чить­ся в него по chroot, но что­бы это ра­бо­та­ло, нам нуж­на вер­сия QEMU, не ис­поль­зую­щая раз­де­ляе­мых биб­лио­тек, так как в chroot есть толь­ко биб­лио­те­ки ARM. Для это­го нам нуж­на qemu-arm-static. К со­жа­лению, ста­ти­че­­ски свя­зан­ный QEMU есть в немно­гих ди­ст­ри­бу­ти­вах, по­это­му при­дет­ся со­брать его са­мим. Со­б­ран­ную вер­сию для x86-64 вме­сте с ин­ст­рук­ция­ми по сбор­ке мож­но най­ти в ар­хи­ве. Нуж­но уста­но­вить ее как /usr/bin/qemu-arm-static.

Те­перь ес­ли по­мес­тить qemu-arm-static в ка­та­лог /usr/bin на ком­пь­ю­те­ре x86, а так­же в под­ка­та­лог archroot ка­та­ло­га archroot/usr/bin, у вас долж­на поя­вить­ся воз­мож­ность пе­ре­клю­чить­ся по chroot в эту фай­ло­вую сис­те­му ARM. По­сле это­го мож­но, на­при­мер, уста­но­вить дру­гие па­ке­ты с по­мо­щью pacman.

Хо­тя та­ким об­ра­зом мож­но лег­ко ком­пи­ли­ро­вать и вы­пол­нять код ARM на плат­фор­ме x86, все мо­жет немно­го усложнить­ся при сбор­ке па­ке­тов, так как в де­ло вклю­ча­ют­ся за­ви­си­мо­сти. В кросс-про­цес­сор­ной сре­де это мо­жет быть про­бле­мой, так как makepkg пред­по­ла­га­ет, что ее за­ви­си­мо­сти уста­нов­ле­ны, а за­ви­си­мо­сти ARM на x86 уста­но­вить нель­зя. Са­мый про­стой спо­соб упот­ре­бить ло­ша­ди­ные си­лы про­цес­со­ра x86 для сбор­ки па­ке­тов для про­цес­со­ра ARM – восполь­зо­вать­ся ути­ли­той distcc для сбор­ки на Pi, но рас­пре­де­лить ее за­да­чи ме­ж­ду одним или несколь­ки­ми рас­пре­де­лен­ны­ми кли­ен­та­ми, об­ла­даю­щи­ми боль­ши­ми вы­чис­ли­тель­ны­ми ре­сур­са­ми. С distcc сбор­ка па­ке­тов на Pi с makepkg по­зво­лит про­зрач­но ис­поль­зо­вать мощ­ность ком­пь­ю­те­ра x86 для ком­пи­ля­ции.

Что­бы восполь­зо­вать­ся distcc, на­до уста­но­вить его на Raspberry Pi и на на­столь­ный ком­пь­ю­тер. Ко­ман­да для уста­нов­ки од­на и та же: pacman -S distcc. Pi – это кли­ент, и он управ­ля­ет сбор­кой, на Pi за­пуска­ет­ся makepkg. На кли­ен­те нуж­но на­стро­ить толь­ко ис­поль­зо­вание distcc в makepkg. До­бавь­те в /etc/makepkg.conf па­ра­мет­ры сво­его сер­ве­ра distcc:

BUILDENV=(fakeroot distcc color !ccache)

DISTCC_HOSTS=”10.0.200.12”

MAKEFLAGS=”-j8”

Ваш ком­пь­ю­тер – это сер­вер, ко­то­рый вы­пол­ня­ет ком­пи­ля­цию. В на­строй­ках нуж­но ука­зать хосты, для ко­то­рых раз­ре­ше­но под­клю­чение, это де­ла­ет­ся в фай­ле /etc/conf.d/distccd. Сер­вер дол­жен за­пускать­ся как де­мон (что так­же мож­но де­лать ав­то­ма­ти­че­­ски при за­груз­ке сис­те­мы):

/etc/rc.d/distccd start

По­сле на­строй­ки кли­ен­та и сер­ве­ра при за­пуске makepkg на клиен­те (Raspberry Pi) бу­дет за­пускать­ся ком­пи­ля­ция на сер­ве­ре. Еще од­на на­строй­ка, ко­то­рую нуж­но сде­лать – ука­зать вер­ный ком­пи­ля­тор для сер­ве­ра distccd. Наш ком­пи­ля­тор на­зы­ва­ет­ся arm-linux-gnueabi-gcc, но distcc бу­дет ис­кать gcc, «род­ной» ком­пи­ля­тор x86. Что­бы это ис­пра­вить, соз­да­дим сим­во­ли­че­скую ссыл­ку и из­меним путь для distccd:

# ln -s /usr/bin/arm-linux-gnueabi/gcc /use/bin/arm-linuxgnueabi-gcc
# sed -i -e ‘/^PID=/iPATH=/usr/bin/arm-linuxgnueabi:\$PATH’ /etc/rc.d/distcc

Сто­ит соз­дать сим­во­ли­че­­ские ссыл­ки для всей це­поч­ки ути­лит. Есть ко­рот­кий скрипт, ко­то­рый де­ла­ет это на сай­те ар­хи­ва.

Вы­се­ля­ем корневую фай­ло­вую сис­те­му

При ра­бо­те с этим об­ра­зом вы мо­же­те ре­шить, что SD-кар­та – не луч­шее ме­сто для корневой фай­ло­вой сис­те­мы. Корневой раз­дел до­воль­но лег­ко пе­ренести на дру­гое уст­рой­ст­во, на­при­мер, на внешний USB-диск. Все, что нуж­но – ско­пи­ро­вать су­ще­ст­вую­щую корневую фай­ло­вую сис­те­му с SD-кар­ты в раз­дел на внешнем USB-дис­ке, при необ­хо­ди­мо­сти из­менив его раз­мер:

# dd if=/dev/mmcblk0p2 of=/dev/sda1 bs=4M
# fsck /dev/sda1
# resize2fs /dev/sda1

Из­мените рас­по­ло­жение корнево­го раз­де­ла в ко­ман­де за­груз­ки в фай­ле /boot/cmdline.txt. Из­мените root=/dev/mmcblk0p2 на root=/dev/sda1. Пе­ре­за­гру­зи­тесь, и корневой раз­дел бу­дет на же­ст­ком дис­ке. Для это­го необ­хо­ди­мо, что­бы в яд­ро бы­ли вком­пи­ли­ро­ва­ны со­от­вет­ст­вую­щие драй­ве­ры USB. В стан­дарт­ном яд­ре они есть, так что про­бле­мы тут быть не долж­но. |

Персональные инструменты
купить
подписаться
Яндекс.Метрика