# Все что есть по этому устройству | ||||||||||||||||||||||||||||||
Не рекомендую использовать нижепредставленное для каких либо целей отличных от ознакомительных. Состав основной платы,
Блок питания,
Дисплей,
Клавиатура,
Теперь картинки. Для начала наброски схемы основной платы, хотя нет, смотрите лучше EK от Atmel, чего одно и тоже перерисовывать. Начнем лучше с платы блока питания, итак, копипаста из даташитов, Схема, pow1833.png Плата, pow1833_b.png Фото, Дисплей, здесь схемы нет, она слишком простая, распиновка дисплея есть, инвертор включен по стандартной схеме, Плата, noklcd_b.png Фото, Клавиатура, оно же дополнение к блоку питания, система зарядки и разрядки аккумуляторов, и часы реального времени, Часть схемы, powch.png Плата, powch_b.png Фото, Преобразователь UART <--> RS232, схема и плата тривиальны, использован MAX3232, Фото, Основная плата, в разводке есть мелкие ошибки, и как оказалось одних лишь танталовых конденсаторов мало, супервизор питания делает RESET слишком рано, видимо из-за просадок питания, позже был добавлен алюминиевый конденсатор в навес, проблема ушла, Плата, at91_b.png Фото, Готовое устройство, Можно гра^W играться в NES игры, но быстро надоедает, для остального же дисплей слишком мелкий. | ||||||||||||||||||||||||||||||
|
# Сборка LFS не читая LFS (Продолжение) | ||
Теперь подробнее о содержимом /etc После монтирования корневой фс, ядро ищет на ней исполняемый файл init (/sbin/init), и запускает процесс init. То, что далее будет делать init определяется файлом /etc/inittab, для busybox там может быть следующее, tty1::sysinit:/etc/rc.d/rc.S tty1::respawn:/sbin/getty 38400 tty1 tty2::respawn:/sbin/getty 38400 tty2 tty3::respawn:/sbin/getty 38400 tty3 tty4::respawn:/sbin/getty 38400 tty4 ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 tty1::restart:/sbin/init tty1::shutdown:/etc/rc.d/rc.0 Первая строка означает, что при старте один раз будет запущен /etc/rc.d/rc.S на терминале tty1. Все следующие respawn строки указывают как запускать getty для терминалов. Здесь четыре виртуальных терминала и один терминал подключен через последовательный интерфейс. Последние строки задают действия производящиеся по выключению или перезагрузке. Заранее приведем /etc/fstab, /dev/mmcblk0p2 / ext2 defaults,noatime 1 1 /dev/mmcblk0p1 /boot ext2 defaults,noatime 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /dev tmpfs defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 tmpfs /var tmpfs defaults 0 0 mmcblk0 это SD/MMC карта, они имеют собственный механизм переаллокации блоков и распределения нагрузки, поэтому нет смысла использовать файловые системы предназначенные для флеш памяти, такие как jffs2. Журналирование не желательно, остается только ext2. Ну и чтобы зря не портить флеш, добавлен флаг noatime, запрещающий изменять время доступа файлов. /proc и /sys записаны как обычно, тут нечего сказать. /dev /tmp и /var монтируются как tmpfs. Надо заметить, что директория /dev корневой фс должна содержать хотя бы два файла, console и tty1, это необходимо для запуска /etc/rc.d/rc.S . Cкрипт инициализации /etc/rc.d/rc.S, #!/bin/sh echo "Mounting /proc /sys /dev" /bin/mount /proc /bin/mount /sys /bin/mount /dev echo "Devices scan: mdev -s" /bin/echo "/sbin/mdev" > /proc/sys/kernel/hotplug /sbin/mdev -s echo "Restoring real time" /usr/bin/kpctl -d /dev/ttyS1 -tr | /usr/bin/xargs /bin/date -D %s -s echo "Checking root filesystem" /sbin/fsck -a / RET=$? if test $RET -ge 2; then if test $RET -ge 4; then echo "An error occurred:" $RET /sbin/sulogin fi echo "System should be rebooted" /sbin/reboot fi echo "Remounting root filesystem" /bin/mount -w -o remount / echo "Mounting /tmp /var" /bin/mount /tmp /bin/mount /var echo "Running: rc.modules" /bin/sh /etc/rc.d/rc.modules echo "Running: rc.local" /bin/sh /etc/rc.d/rc.local kpctl используется для чтение реального времени с внешнего устройства. В rc.modules как можно догадаться, записана загрузка нужных модулей, а в rc.local что то особое для конкретной системы, если необходимо конечно. Ну и выключение /etc/rc.d/rc.0, #!/bin/sh echo "Storing real time" /bin/date +%s | /usr/bin/kpctl -d /dev/ttyS1 -tw echo "Unmounting all" /bin/umount -a -r /sbin/swapoff -a Тут все должно быть понятно. Ещё один важный файл, /etc/profile MANPATH=/usr/man:/usr/local/man:/usr/share/man PATH=/bin:/usr/bin:/usr/local/bin if test $(id -u) -eq 0; then PATH=/sbin:/usr/sbin:/usr/local/sbin:$PATH fi export MANPATH export PATH Здесь определяется общее окружение для всех входящих в систему пользователей. Можно делать локальные настройки для конкретных пользователей в ~/.profile . Для создания /etc/passwd /etc/group можно использовать adduser, addgroup. Текст приводить не будем. При использовании mdev из BusyBox понадобится ещё вот такой файл /etc/mdev.conf, null root:root 666 zero root:root 666 random root:root 664 urandom root:root 664 console root:tty 660 tty[0-9]* root:tty 660 ttyS[0-9] root:tty 660 fb[0-9] root:video 660 Здесь описан лишь минимум, остальное добавляется по необходимости. | ||
|
# GNU toolchain для ARM (Продолжение) | ||
Новая версия скрипта для сборки toolchain. target скорректирована, правильный вариант armv4tl-unknown-linux-uclibcgnueabi (Это для ARM920T). В остальном только небольшие изменения и переход на новые версии. На этот раз полученный компилятор испытывался на сборке Linux. Патч для gcc легко найти по ключевым словам. tcmakev3.gz | ||
|
# Драйвер LCD (Продолжение) | ||
Вторая версия все того же драйвера PCF8833, теперь работа ведется напрямую с контроллером SPI, это аппаратно зависимо (только для Atmel SPI), но позволяет получить приемлемый результат. Драйвер теперь работает стабильно, в отличии от предыдущего, который мог обрушить систему или просто перестать выводить картинку (хотя в логах все отлично, spi сообщения отправляются). Добавлены ещё некоторые мелочи, такие как возможность повторной инициализации дисплея с помощью ioctl, перенастройка глубины цвета и поворота, но это ещё не проверялось в действии. pcf8833v2.c.gz | ||
|
# Загрузчик Linux для AT91 | ||
Это можно назвать первой полностью работающей версией моего загрузчика, вот что он может, - Инициализация AT91 (пока только AT91RM9200) - Чтение и запись AT45xxx флеш памяти, там хранится сам код загрузчика - Чтение SD карт через MCI - Чтение файловой системы ext2 Алгоритм работы такой, 1. Инициализация, монтирование boot раздела с SD карты 2. Чтение файла zboot.seq и выполнение команд из него, команды такие, 2.1 Изменение частоты ядра и делителя 2.2 Задание строки параметров Linux 2.3 Загрузка образа Linux из файла и запуск 2.4 Самообновление из указанного файла Размер получился около 8кб, а это умещается во внутреннюю SRAM, нет необходимости в двухуровневой загрузке, at91-110709.tar.gz | ||
|
# Сборка LFS не читая LFS | ||
Не самое удачное название записи, здесь я распишу как собрал linux & busybox систему. Для начала надо сказать что ранее собранный toolchain (тот который arm-none-eabi) не подойдёт, название целевой платформы формируется вот так, arch-vendor-*-linux-* Что такое arch понятно, vendor насколько я понял не оказывает влияние на результат, и чисто декоративен, далее идёт список фич которые будет поддерживать toolchain как он формируется я сказать не могу, если знаете об этом больше пишите email :) Для ARM я выбрал такую цель arm-unknown-linux-uclibcgnueabi, в результате полученный кросс-компилятор будет правильно вписывать путь к /lib/ld-uClibc.so.0 в бинарники в отличии от старого. Сборку этого toolchain пришлось несколько изменить, симлинки теперь создавать нет необходимости, теперь надо устанавливать заголовки uClibc перед сборкой компилятора, а для самого GCC нужен softfloat патч (ну если ваш целевой CPU тоже не имеет FPU), все изменения можно увидеть в новом скрипте сборки tcmake-2.gz. Были ещё какие то ошибки при сборке GCC, они легко правятся вручную. Сборка ядра Это очень просто, открываем корневой Makefile, и приводим в порядок вот эти строки, ARCH ?= arm CROSS_COMPILE ?= arm-unknown-linux-uclibcgnueabi- Далее конфигурируем его как обычно, включаем EABI, нужные драйверы. Как добавить поддержку свой платы я писать не буду, это не сложно, можно скопировать с других и поправить. Загрузчик Можно использовать U-Boot, но интереснее написать свой загрузчик. Для ARM читаем сюда Documentation/arm/Booting . Тоже не сложно, заполняем tagged list и передаем управление в zImage. Сложнее будет с поддержкой протоколов и интерфейсов, если XModem можно реализовать очень быстро, то с чтением например USB Mass Storage не сильно хочется и связываться. По этому обычно выбирают U-Boot. Но для тех кто хочет писать свой загрузчик или ещё чего то хочет ;) предлагаю вот это at91-100609.tar.gz, исходники моего загрузчика для AT91RM9200. BusyBox Ещё проще чем ядро, надо только отконфигурировть как нужно, включить EABI, рекомендую отключить запись логов шелла. Корневая файловая система Сюда копируется BusyBox со всеми симлинками, uClibc собирается так же как для toolchain, можно взять ту же сборку, в поддиректории uClibc-*/utils есть полезные утилиты, их тоже можно положить в bin. Создаем etc dev proc sys home root tmp var. Для первого запуска надо правильно заполнить etc и dev. Первое это /etc/inittab, ::sysinit:/etc/rc.d/rc.S ::askfirst:-/bin/sh Скрипт инициализации /etc/rc.d/rc.S и запуск шелла, если надо как то иначе читайте документацию BusyBox. Для первого пуска должно хватить. Втрое, сам скрипт, #!/bin/sh PATH=/sbin:/usr/sbin:/bin:/usr/bin /bin/mount -v -n /proc /bin/mount -v -n /sys /bin/hostname lap /bin/mount -w -v -n -o remount / Ну и соответственно /etc/fstab /dev/sda2 / ext2 defaults,noatime 1 1 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 Там ещё где нибудь надо fsck делать, но пока и так неплохо. Третье, файлы устройств, mknod dev/tty c 5 0 mknod dev/console c 5 1 mknod dev/null c 1 3 mknod dev/sda2 b 8 2 Добравшись до шелла можно будет запустить mdev -s это полностью заполнит /dev . Пока у меня rootfs на usb-flash по этому /dev/sda2 . Консольшоты # ldd /bin/busybox libm.so.0 => /lib/libm.so.0 (0x4000e000) libc.so.0 => /lib/libc.so.0 (0x40029000) ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x40000000) # uname -a Linux lap 2.6.27.4 #81 Wed Jun 10 19:23:15 MSD 2009 armv4tl unknown # ifconfig lo 127.0.0.1 # ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: seq=0 ttl=64 time=0.671 ms 64 bytes from 127.0.0.1: seq=1 ttl=64 time=0.336 ms 64 bytes from 127.0.0.1: seq=2 ttl=64 time=0.336 ms | ||
|
# Очередной вариант сборки GNU toolchain для ARM. | ||
С помощью поисковых систем можно найти много скриптов для сборки GCC под разные платформы, это один из них. Я взял вот такие версии исходников, binutils-2.19.tar.bz2 gcc-4.3.3.tar.bz2 linux-2.6.27.4.tar.bz2 uClibc-0.9.30.1.tar.bz2 0. До того как, что либо делать, не помешало бы определить некоторый переменные и пути, TARGET='arm-none-eabi' PREFIX='/usr/local/arm/' CURRENT_DIR=$(pwd) SOURCE_DIR=$CURRENT_DIR'/src' BUILD_DIR=$CURRENT_DIR'/build' SYSROOT_DIR=$CURRENT_DIR'/sysroot' Думаю всё понятно, TARGET это название целевой платформы, PREFIX это префикс для установки кросс-компилятора. Можно ещё сделать симлинк из PREFIX в SYSROOT_DIR, и устанавливать все в SYSROOT_DIR, как и было сделано. 1. Первое что надо сделать, это собрать binutils, ../configure --prefix=$PREFIX --target=$TARGET --with-sysroot=$PREFIX --enable-interwork --enable-multilib --disable-nls make make DESTDIR=$SYSROOT_DIR install И не забываем добавить в PATH нужные пути. 2. Устанавливаем заголовки ядра, make mrproper make ARCH=arm headers_check make ARCH=arm INSTALL_HDR_PATH=$SYSROOT_DIR$PREFIX'/usr' headers_install find $SYSROOT_DIR$PREFIX'/usr' -name '\.*' | xargs rm Последняя строка может и не понадобится, просто мне не понравились эти файлы. 3. Теперь нужно собрать временную версию GCC, которая нужна для сборки libc, ../configure --prefix=$PREFIX --target=$TARGET --with-sysroot=$PREFIX --enable-interwork --enable-multilib --enable-languages=c --with-newlib --disable-shared --disable-nls --with-float=soft --with-arch=armv4t --with-tune=arm9tdmi --disable-libssp make make DESTDIR=$SYSROOT_DIR install 4. Полученным ранее GCC можно собрать uClibc, ln -s $SYSROOT_DIR$PREFIX'/lib/gcc/arm-none-eabi/4.3.3/crtbegin.o' $SYSROOT_DIR$PREFIX'/lib/gcc/arm-none-eabi/4.3.3/crtbeginS.o' ln -s $SYSROOT_DIR$PREFIX'/lib/gcc/arm-none-eabi/4.3.3/crtend.o' $SYSROOT_DIR$PREFIX'/lib/gcc/arm-none-eabi/4.3.3/crtendS.o' Это было сделано из-за того, что возникала ошибка во время линковки, может и не понадобится. make distclean if [ ! -e '.config' ]; then cp $SOURCE_DIR'/.uclibc.config' '.config' sed -i -e 's/arm-elf-/'$TARGET'-/' '.config' fi Конфиг должен быть настроен соответственно. make make PREFIX=$SYSROOT_DIR$PREFIX install Префикс здесь надо приклеить к пути самостоятельно. 5. Финальная версия GCC, ../configure --prefix=$PREFIX --target=$TARGET --with-sysroot=$PREFIX --enable-interwork --enable-multilib --enable-languages=c --disable-nls --with-float=soft --with-arch=armv4t --with-tune=arm9tdmi --disable-libssp make make DESTDIR=$SYSROOT_DIR install Параметры with-float=soft, with-arch и with-tune сами понимаете от чего зависят, и при первой сборке тоже. Вот сам скрипт польностью tcmake.gz. Тем что получилось можно успешно собирать busybox, с некоторыми опять же дополнительными симлинками (что то с crt0.o -> crt1.o) собирается busybox-1.13.4. Для разных версий исходников проблемы и костыли их исправляющие могут быть очень разными, в моем случае помогло отключение libssp. | ||
|
# Первая запись в этой ленте. | ||
HTML генерируется вот этим скриптом. (email amaora yandex ru) | ||
|