Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
linux_faq:сборка_системы_для_arm-роутера_на_pc [2020/05/31 09:00] – [Проблемы] admin | linux_faq:сборка_системы_для_arm-роутера_на_pc [2020/10/15 20:09] – [Сборка Armbian] admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | У меня есть такой роутер: | ||
+ | И собирать его я бы хотел на PC. \\ | ||
+ | Вот тут много информации (хотя и не всегда свежей) о сборке и загрузке debian на платформах Allwinner - https:// | ||
+ | Тем, кому не хочется ничего собирать - https:// | ||
+ | |||
+ | ====== Armbian ====== | ||
+ | При попытке загрузить образ **Armbian_20.02.1_Nanopi-r1_buster_current_5.4.20.img** система останавливалась при попытке распаковать ядро: | ||
+ | < | ||
+ | |||
+ | Uncompressing Linux... done, booting the kernel. | ||
+ | </ | ||
+ | В итоге **Armbian** удалось загрузить так: | ||
+ | - Берем официальный образ **nanopi-r1_sd_friendlycore-xenial_4.14_armhf_20191219.img**. На нем три раздела. Подключаем **loop-device** и потом монтируем куда-то: | ||
+ | - Берем образ **armbian** и также подключаем его как **loop-device**. | ||
+ | - Берем с образа **armbian** из директории **boot** файлики **zImage** и **initrd** (вернее файлики на которые указывают эти симлинки), | ||
+ | - На официальном образе удаляем всё с раздела **rootfs**. | ||
+ | - Переносим всю файловую систему с единственного раздела образа **armbian** на раздел **rootfs** официального образа: | ||
+ | - Отмонтируем **loop**-устройства и заливаем официальный образ (c ядром, initrd и файловой системой от armbian), на флеху. | ||
+ | Для сборки загружающегося образа я сделал скриптец: | ||
+ | < | ||
+ | armbian_img=' | ||
+ | friendlyarm_img=' | ||
+ | |||
+ | echo ' | ||
+ | cp $friendlyarm_img " | ||
+ | |||
+ | mkdir ./ | ||
+ | mkdir ./ | ||
+ | mkdir ./ | ||
+ | |||
+ | armbian_offset=`/ | ||
+ | |||
+ | echo " | ||
+ | |||
+ | mount -o loop, | ||
+ | |||
+ | friendlyarm_boot_offset=`/ | ||
+ | friendlyarm_rootfs_offset=`/ | ||
+ | |||
+ | mount -o loop, | ||
+ | |||
+ | echo " | ||
+ | cp -L ./ | ||
+ | |||
+ | echo " | ||
+ | cp -L ./ | ||
+ | |||
+ | echo " | ||
+ | rm -f ./ | ||
+ | cp ./ | ||
+ | |||
+ | umount ./ | ||
+ | |||
+ | mount -o loop, | ||
+ | rm -Rf ./ | ||
+ | |||
+ | echo " | ||
+ | rsync -a ./ | ||
+ | rm -rf ./ | ||
+ | |||
+ | umount ./ | ||
+ | umount ./ | ||
+ | |||
+ | echo ' | ||
+ | |||
+ | ==== Проблемы ==== | ||
+ | В один прекрасный момент интернет, | ||
+ | < | ||
+ | [482827.380448] WARNING: CPU: 0 PID: 0 at net/ | ||
+ | [482827.380459] NETDEV WATCHDOG: eth1 (r8152): transmit queue 0 timed out | ||
+ | [482827.380466] Modules linked in: nft_masq nft_nat nft_chain_nat nf_nat nft_counter nft_ct nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables_set nf_tables nfnetlink evdev brcmfmac brcmutil cfg80211 lima sun8i_codec_analog snd_soc_simple_card sun4i_gpadc_iio sun8i_adda_pr_regmap sun4i_i2s snd_soc_simple_card_utils gpu_sched rfkill snd_soc_core industrialio snd_pcm_dmaengine sun8i_thermal snd_pcm cdc_ether snd_timer usbnet option snd r8152 soundcore usb_wwan usbserial sunxi_cedrus(C) v4l2_mem2mem uio_pdrv_genirq gpio_keys uio cpufreq_dt zram sch_fq_codel usb_f_acm u_serial g_serial libcomposite ip_tables x_tables pwrseq_simple uas realtek | ||
+ | [482827.380668] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G | ||
+ | [482827.380674] Hardware name: Allwinner sun8i Family | ||
+ | [482827.380717] [< | ||
+ | [482827.380745] [< | ||
+ | [482827.380775] [< | ||
+ | [482827.380799] [< | ||
+ | [482827.380822] [< | ||
+ | [482827.380848] [< | ||
+ | [482827.380869] [< | ||
+ | [482827.380891] [< | ||
+ | [482827.380912] [< | ||
+ | [482827.380938] [< | ||
+ | [482827.380968] [< | ||
+ | [482827.380992] [< | ||
+ | [482827.381002] Exception stack(0xc0f01f20 to 0xc0f01f68) | ||
+ | [482827.381022] 1f20: 00000000 54e7da08 ef69ff34 c0116341 ffffe000 c0f04f68 c0f04fb0 00000001 | ||
+ | [482827.381041] 1f40: c0f04f48 00000000 c0ec48f0 c0ff67f6 ffffffff c0f01f70 c010792f c0107930 | ||
+ | [482827.381050] 1f60: 40070033 ffffffff | ||
+ | [482827.381074] [< | ||
+ | [482827.381100] [< | ||
+ | [482827.381121] [< | ||
+ | [482827.381146] [< | ||
+ | [482827.381158] ---[ end trace df317a78f05c9e9f ]--- | ||
+ | </ | ||
+ | Ядро: Linux nanopi-r1 5.4.32-sunxi #trunk SMP Sat Apr 25 21:48:40 UTC 2020 armv7l armv7l armv7l GNU/Linux | ||
+ | |||
+ | ===== Сборка Armbian ===== | ||
+ | / | ||
+ | | ||
+ | ./ | ||
+ | или так: | ||
+ | ./ | ||
+ | На **NanoPi R1** у меня работает вот так собранный **Armbian**: | ||
+ | sudo ./ | ||
+ | ==== Cобрать образ armbian с какой-то конкрентной версией ядра ==== | ||
+ | Нужно добавить строку вида: | ||
+ | KERNELBRANCH=' | ||
+ | в файл **build/ | ||
+ | Подробнее тут - https:// | ||
+ | Чтобы выяснить - откуда берутся сорцы ядра идем, например, | ||
+ | Там видим - **BOARDFAMILY=" | ||
+ | Значит дальше идем сюда: **./ | ||
+ | Там видим: **source " | ||
+ | И далее смотрим сюда: **config/ | ||
+ | < | ||
+ | legacy) | ||
+ | |||
+ | KERNELSOURCE=" | ||
+ | KERNELBRANCH=" | ||
+ | KERNELPATCHDIR=' | ||
+ | |||
+ | ;; | ||
+ | |||
+ | current) | ||
+ | |||
+ | KERNELSOURCE=" | ||
+ | KERNELBRANCH=" | ||
+ | KERNELPATCHDIR=' | ||
+ | |||
+ | ;; | ||
+ | |||
+ | dev) | ||
+ | |||
+ | KERNELSOURCE=" | ||
+ | KERNELBRANCH=" | ||
+ | KERNELPATCHDIR=' | ||
+ | BOOTBRANCH=' | ||
+ | |||
+ | ;; | ||
+ | esac | ||
+ | </ | ||
+ | Тут видно откуда берутся исходники и какие бранчи скрываются за псевдонимами (legacy, current, dev). | ||
+ | ====== Сборка ядра и u-boot для Nano Pi R1 (Allwinner H3)====== | ||
+ | http:// | ||
+ | Ставим софт: | ||
+ | apt-get install git swig python-dev python3-dev build-essential bc bison flex u-boot-tools screen gcc-arm-linux-gnueabi libncurses-dev | ||
+ | Распаковываем тулчейн (его можно найти [[https:// | ||
+ | tar xf arm-cortexa9-linux-gnueabihf-4.9.3-20160512.tar.xz -C / | ||
+ | export PATH=/ | ||
+ | export GCC_COLORS=auto | ||
+ | . ~/.bashrc | ||
+ | arm-linux-gcc -v | ||
+ | | ||
+ | ===== Собираем U-Boot ===== | ||
+ | cd ~ | ||
+ | git clone https:// | ||
+ | cd u-boot/ | ||
+ | make nanopi_h3_defconfig ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | make ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | в результате получится файлик **u-boot-sunxi-with-spl.bin**, | ||
+ | dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8 | ||
+ | |||
+ | ==== Собираем ядро ==== | ||
+ | Вариантов пара - собрать то что предлагает **FriendlyARM**, | ||
+ | В конце концов, | ||
+ | Mainline - новое и хорошее, | ||
+ | thermal thermal_zone0: | ||
+ | Зато с ядром от **FriendlyARM** собираются родные для этих устройств файлы **DTB**. | ||
+ | === Ядро от FriendlyARM - 4.14 === | ||
+ | cd ~ | ||
+ | git clone https:// | ||
+ | cd linux | ||
+ | touch .scmversion | ||
+ | make sunxi_defconfig ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | make zImage dtbs ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | Теперь образы ядра и файлики dtb можно скопировать на загрузочный разле флехи: | ||
+ | cp arch/ | ||
+ | cp arch/ | ||
+ | Теперь соберем модули: | ||
+ | cd ~/linux | ||
+ | make modules ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | и скопируем их на флеху. Считаем, | ||
+ | cd ~/linux | ||
+ | make modules_install INSTALL_MOD_PATH=/ | ||
+ | |||
+ | === Ядро Mainline === | ||
+ | < | ||
+ | cd mainline_linux | ||
+ | </ | ||
+ | Вот [[https:// | ||
+ | Для начала - скопируем файлик **sunxi_defconfig**, | ||
+ | cp ./ | ||
+ | Также, в **mainline** может не быть исходников некоторых модулей. Скопируем их: | ||
+ | cp ./ | ||
+ | | ||
+ | < | ||
+ | export GCC_COLORS=auto | ||
+ | ARCH=arm CROSS_COMPILE=arm-linux- make mrproper | ||
+ | make sunxi_defconfig ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | make ARCH=arm CROSS_COMPILE=arm-linux-</ | ||
+ | И соберем модули: | ||
+ | make modules ARCH=arm CROSS_COMPILE=arm-linux- | ||
+ | |||
+ | ====== Запуск в эмуляторе ====== | ||
+ | Вот тут страничка **qemu-system-arm**, | ||
+ | Судя по [[https:// | ||
+ | Вот тут описан запуск собранного u-boot и ядра: \\ | ||
+ | https:// | ||
+ | https:// | ||
+ | ===== Собираем последний qemu ===== | ||
+ | https:// | ||
+ | < | ||
+ | apt-get install git build-essential zlib1g-dev pkg-config libglib2.0-dev binutils-dev libboost-all-dev autoconf libtool libssl-dev libpixman-1-dev libpython-dev python-pip python-capstone virtualenv | ||
+ | git clone https:// | ||
+ | cd qemu | ||
+ | git submodule init | ||
+ | git submodule update --recursive | ||
+ | ./configure | ||
+ | make | ||
+ | </ | ||
+ | Теперь можно посмотреть список машин, который поддерживается и попробывать запустить собранное ядро или u-boot: | ||
+ | < | ||
+ | cd ~ | ||
+ | ./ | ||
+ | ... | ||
+ | ./ | ||
+ | kernel ./ | ||
+ | -append ' | ||
+ | -dtb ./ | ||
+ | </ | ||
+ | Так как никакой корневой файловой системы у нас нет, то всё закончится так:< | ||
+ | [ 4.075519] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0, | ||
+ | </ | ||
+ | Но ядро запустилось! | ||
+ | |||
+ | ====== Сборка образа минимальной системы debian ====== | ||
+ | https:// | ||
+ | \\ | ||
+ | https:// | ||
+ | https:// | ||
+ | https:// | ||
+ | sudo apt-get install multistrap kpartx qemu qemu-user-static binfmt-support dpkg-cross | ||
+ | |||
+ | ===== Создаем образ флехи ===== | ||
+ | < | ||
+ | fallocate -l 4G debian-stable.img | ||
+ | disk=' | ||
+ | sgdisk --zap-all $disk | ||
+ | sgdisk --mbrtogpt --clear $disk | ||
+ | sgdisk --new=1: | ||
+ | sgdisk --typecode=1: | ||
+ | sgdisk -N0 $disk | ||
+ | sgdisk --typecode=2: | ||
+ | Создадим loop-устройства и обнаружим на них партиции: | ||
+ | sudo kpartx -v -a ./ | ||
+ | В выводе будет что-то такое: | ||
+ | add map loop4p1 (253:2): 0 524289 linear 7:4 2048 | ||
+ | add map loop4p2 (253:3): 0 7860191 linear 7:4 528384 | ||
+ | Отформатируем эти партиции, | ||
+ | sudo mkfs.ext4 / | ||
+ | sudo mkfs.ext2 / | ||
+ | mkdir debian-stable | ||
+ | sudo mount / | ||
+ | sudo mkdir ./ | ||
+ | sudo mount / | ||
+ | |||
+ | |||
+ | ===== Заливка минимальной системы debian ===== | ||
+ | Для создания системы я применю [[https:// | ||
+ | ==== ./ | ||
+ | Минимальный конфигурационный файлик **Multistrap** | ||
+ | < | ||
+ | unpack=true | ||
+ | bootstrap=Debian | ||
+ | aptsources=Debian | ||
+ | # | ||
+ | |||
+ | [Debian] | ||
+ | packages=systemd libnss-systemd libpam-systemd dbus default-dbus-session-bus | ||
+ | source=http:// | ||
+ | keyring=debian-archive-keyring | ||
+ | suite=stable</ | ||
+ | |||
+ | ==== Заливаем систему ==== | ||
+ | Теперь на смонтированные разделы нашего файла-образа я залью минимальную систему **debian**. | ||
+ | sudo multistrap -a armhf -d ./ | ||
+ | При попытке собрать файловую систему появляется ошибка: | ||
+ | E: The repository ' | ||
+ | Причина в том, что в скрипте **multistrap** некорректно устанавливается значение опции **AllowUnauthenticated**. Описано тут: https:// | ||
+ | Патчим **multistrap**: | ||
+ | sudo sed -i ' | ||
+ | и пробуем снова (в конфигурации должна быть опция **keyring=debian-archive-keyring**, | ||
+ | sudo multistrap -a armhf -d ./ | ||
+ | В результате всё получается и в директории **./ | ||
+ | |||
+ | ==== Первичная конфигурация пакетов ==== | ||
+ | Запускать в **chroot** исполняемые файлы для архитектуры **arm** нам позволят ранее установленные в хостовой системе пакеты **qemu-user-static**, | ||
+ | Подключим **/dev** (что необходимо для работы с **/ | ||
+ | sudo mount -o bind /dev/ ./ | ||
+ | sudo LC_ALL=C LANGUAGE=C LANG=C DEBIAN_FRONTEND=noninteractive chroot debian-stable bash -c 'echo "dash dash/sh boolean false" | debconf-set-selections && | ||
+ | Для настройки некоторых пакетов нужно задать пароль **root**: | ||
+ | sudo chroot debian-stable/ | ||
+ | Теперь донастроим оставшиеся пакеты: | ||
+ | sudo LC_ALL=C LANGUAGE=C LANG=C DEBIAN_FRONTEND=noninteractive chroot debian-stable dpkg --configure -a | ||
+ | |||
+ | Теперь скопируем ядро и **dtb**: | ||
+ | sudo cp ./ | ||
+ | sudo cp ./ | ||
+ | Дальше нужно перенести в систему модули ядра, которые мы собрали раньше: | ||
+ | cd ./ | ||
+ | sudo PATH=/ | ||
+ | Теперь можно сделать файлик **/ | ||
+ | blkid / | ||
+ | / | ||
+ | blkid / | ||
+ | / | ||
+ | В итоге **/ | ||
+ | UUID=683177df-8d27-4733-a490-c8e69fb0b525 | ||
+ | UUID=85b026f4-afd7-4ecf-8679-dd0c87e628 | ||
+ | Заменим дефолтный target: | ||
+ | sudo rm -f ./ | ||
+ | sudo ln -s / | ||
+ | И создадим симлинк для того, чтобы появилось устройство **ttyS0**: | ||
+ | sudo ln -s / | ||
+ | Если этого не сделать - будут ошибки типа: | ||
+ | [ *** ] A start job is running for /dev/ttyS0 (1min 29s / 1min 30s) | ||
+ | [ TIME ] Timed out waiting for device /dev/ttyS0. | ||
+ | [DEPEND] Dependency failed for Serial Getty on ttyS0. | ||
+ | ==== Отмонтируем файл-образ и попробуем запуститься ==== | ||
+ | cd ~ | ||
+ | sudo umount ./ | ||
+ | sudo umount ./ | ||
+ | Удалим loop-устройства: | ||
+ | sudo kpartx -d ./ | ||
+ | И попробуем запуститься с ядром **mainline** и **dtb** из поставки ядра от **FriendlyARM**! | ||
+ | < | ||
+ | -nic user -nographic -kernel ./ | ||
+ | -append ' | ||
+ | -dtb ./ | ||
+ | -sd ./ | ||
+ | В итоге - не смотря на некоторые ошибки с сервисами **systemd**, | ||
+ | |||
+ | |||
+ | ===== Загрузка системы на реальной железке ===== | ||
+ | Самым логичным способом, | ||
+ | Я так и поступил. \\ | ||
+ | \\ | ||
+ | Но можно пойти трудным путем и пытаться сделать все вручную. | ||
+ | ==== Исследование конфигурации U-Boot ==== | ||
+ | Судя по начальным сообщениям: | ||
+ | < | ||
+ | CPU Freq: 408MHz | ||
+ | memory test: 1 | ||
+ | Pattern 55aa Writing...Reading...OK | ||
+ | Trying to boot from MMC2 | ||
+ | Boot device: emmc | ||
+ | |||
+ | |||
+ | U-Boot 2017.11 (Oct 18 2019 - 02:50:31 +0800) Allwinner Technology | ||
+ | |||
+ | CPU: | ||
+ | Model: FriendlyElec NanoPi H3 | ||
+ | DRAM: 1 GiB | ||
+ | CPU Freq: 1008MHz | ||
+ | MMC: SUNXI SD/MMC: 1, SUNXI SD/MMC: 0 | ||
+ | *** Warning - bad CRC, using default environment</ | ||
+ | И судя по тому, что начинает загружаться предустановленная система - я что-то сделал не так. \\ | ||
+ | Наверное надо взять официальный образ и посмотреть что внутри. \\ | ||
+ | Кстати, | ||
+ | < | ||
+ | baudrate=115200 | ||
+ | board=nanopi-r1 | ||
+ | board_name=sunxi | ||
+ | boot_a_script=load ${devtype} ${devnum}: | ||
+ | boot_efi_binary=if fdt addr ${fdt_addr_r}; | ||
+ | boot_extlinux=sysboot ${devtype} ${devnum}: | ||
+ | boot_mmc=2 | ||
+ | boot_net_usb_start=usb start | ||
+ | boot_prefixes=/ | ||
+ | boot_script_dhcp=boot.scr.uimg | ||
+ | boot_scripts=boot.scr.uimg boot.scr | ||
+ | boot_targets=fel mmc_auto usb0 pxe dhcp | ||
+ | bootcmd=fatload mmc 0:1 ${scriptaddr} boot.scr; source ${scriptaddr} | ||
+ | bootcmd_dhcp=run boot_net_usb_start; | ||
+ | bootcmd_fel=if test -n ${fel_booted} && test -n ${fel_scriptaddr}; | ||
+ | bootcmd_mmc0=setenv devnum 0; run mmc_boot | ||
+ | bootcmd_mmc1=setenv devnum 1; run mmc_boot | ||
+ | bootcmd_mmc_auto=run bootcmd_mmc0 | ||
+ | bootcmd_pxe=run boot_net_usb_start; | ||
+ | bootcmd_usb0=setenv devnum 0; run usb_boot | ||
+ | bootdelay=2 | ||
+ | bootm_size=0xa000000 | ||
+ | console=ttyS0, | ||
+ | cpu=h3 | ||
+ | dfu_alt_info_ram=kernel ram 0x42000000 0x1000000; | ||
+ | distro_bootcmd=for target in ${boot_targets}; | ||
+ | efi_dtb_prefixes=/ | ||
+ | ethaddr=02: | ||
+ | fdt_addr_r=0x43000000 | ||
+ | fdtcontroladdr=7bf4fa48 | ||
+ | fdtfile=sun8i-h3-nanopi-m1-plus.dtb | ||
+ | kernel_addr_r=0x42000000 | ||
+ | load_efi_dtb=load ${devtype} ${devnum}: | ||
+ | mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; | ||
+ | mmc_bootdev=1 | ||
+ | preboot=usb start | ||
+ | pxefile_addr_r=0x43200000 | ||
+ | ramdisk_addr_r=0x43300000 | ||
+ | scan_dev_for_boot=echo Scanning ${devtype} ${devnum}: | ||
+ | scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; | ||
+ | scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z " | ||
+ | scan_dev_for_extlinux=if test -e ${devtype} ${devnum}: | ||
+ | scan_dev_for_scripts=for script in ${boot_scripts}; | ||
+ | scriptaddr=0x43100000 | ||
+ | serial# | ||
+ | soc=sunxi | ||
+ | stderr=serial | ||
+ | stdin=serial, | ||
+ | stdout=serial | ||
+ | usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; | ||
+ | wifi_mac_node=[2 c5 42 99 8a 81]</ | ||
+ | |||
+ | Во-первых - **DTB** не от **nanopi-r1**, | ||
+ | |||
+ | |||
+ | |||