18 ноября, 2008
vi основные команды
Оригинал: .pdf .odt
Перевод: .pdf .odt
Условия распространения Creative Commons Attribution-ShareAlike 2.5 license
©Copyright 2006-2005, Free Electrons.
16 ноября, 2008
Как пропатчить Linux - Linux patch
Определите нужную версию ядра и патча с помощью браузера на kernel.org.
http://kernel.org/pub/linux/kernel/v2.6/patch2.6.27.bz2 (с 2.6.26 на 2.6.27)
http://kernel.org/pub/linux/kernel/v2.6/patch2.6.27.6.bz2 (с 2.6.27 на 2.6.27.6)
Далее скачиваем патч, сверяем подпись:
wget http://kernel.org/pub/linux/kernel/v2.6/patch-2.6.27.6.bz2
wget http://kernel.org/pub/linux/kernel/v2.6/patch-2.6.27.6.bz2.sign
gpg --verify patch-2.6.27.6.bz2.sign
Накладываем патч:
bzcat patch-2.6.27.6.bz2 | patch p1
Патч наложен.
Откатить патч можно с помощью patch с параметром -R.
Файл patch-2.6.27.6 - это вывод комманды diff. Вот так он выглядит:
diff --git a/Makefile b/Makefile
index 16e3fbb..1ea4453 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@ <-номера строк в файле
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 27
-EXTRAVERSION = <- удаленная строку
-NAME = Rotary Wombat <- удаленная строка
+EXTRAVERSION = .6 <- добавленная строка
+NAME = Trembling Tortoise <- добавленная строка
# *DOCUMENTATION*
Спасибо.
15 ноября, 2008
Crosstool - сборка и тестирование Toolchains
Сборка кросс-toolchain'а gcc/glibc для встраеваемых систем есть пэйнфул процесс. Программа (набор скриптов) Crosstool, написанная Dan Kegel, поможет найти рабочие комбинации различных версий gcc, glibc, binutils и заголовочных файлов ядра(см. рисунок выше).
- Домашняя страница проекта: http://kegel.com/crosstool/
- Также смотреть: uClibc chaintools http://free-electrons.com/community/tools/uclibc
- Have fun! http://www.aleph1.co.uk/armlinux/docs/toolchain/toolchHOWTO.pdf
Под ARM:
- http://www.codesourcery.com/gnu_toolchains/arm/
- ftp://ftp.handhelds.org/projects/toolchain/
- http://www.linux-mips.org/wiki/Toolchains
Tools list:
- Crosstool-ng
- Buildroot
- Scratchbox
- OpenEmbedded
- PTXdist
- LTIB
- Home made tools
- Firmware Linux
- Gentoo embedded
- ELDK
- другие? коммент.
Спасибо.
02 ноября, 2008
Архитектура ядра UNIX
На диаграмме ниже показаны различные модули ядра и их свзяи. Два главных компонента ядра: файловая подсистема (file subsystem) и подсистема управления процессами (process control subsystem). Также здесь видно три уровня: user, kernel и hardware levels. Интерфейс системных вызовов (system call interface) и библиотеки(libraries) разделяют пользовательский уровень и уровень ядра. Системные вызовы обычно представлены в виде вызовов функций в С программах, библиотеки собирают эти вызовы в примитивы, необходимые для работы ОС.
Блочная диаграмма ядра UNIX
Файловая подсистема управляет файлами, выделяет место под них, управляет свободным пространством, контролирует доступ к файлам, получает данные для пользователей. Процессы взаимодействуют с файловой подсистемой через специфический набор системных вызовов:
- open открывает файл для чтения и записи
- close
- read
- write
- stat запрашивает атрибуты файла
- chown изменяет запись о том, кто владеет файлом
- chmod управляет доступов к файлу
Файловая подсистема получает доступ к файлам, используя механизм буферизации (buffering mechanism), который устанавливает канал между ядром (kernel) и устройством хранения (storage device). Механизм буферизации взаимодействует с драйвером устройства блочного ввода/вывода (block I/O device) для того, чтобы инициировать перемещение данных в/из ядра. Драйвер устройства - это модуль ядра, который контролирует работу периферийных устройств.
Файловая подсистема также может напрямую взаимодействовать с "сырыми" ("raw") драйверами ввода/вывода без привлечения механизма буферизации. Raw устройства также называют символьными (character). Это все устройства, которые нельзя отнести к блочным.
Подсистема управления процессами
Подсистема управления процессами отвечает за синхронизацию процессов (process synchronization), межпроцессорное взаимодействие (interprocess communication), управление памятью (memory managment) и планировкой процессов (process sheduling). Файловая подсистема и подсистема управления процессами взаимодействуют при загрузке файла в память для его запуска (подсистема процессов прочитывает исполняемый файл в память перед его исполнения).
Некоторые системные вызовы для управления процессами:
- fork создает новый процесс
- exec накладывает образ программы на текущий процесс
- exit заканчивает запущенный процесс
- wait синхронизирует исполнение процесса с exit предыдущего fork-нутого процесса
- brk контролирует размер выделенной на процесс памяти
- signal управляет откликом процесса на экстраординарные события
Модуль управления памятью (memory managment module) управляет выделением памяти. Если системе не хватает физической памяти для всех процессов, ядро перемещает их между основной и вторичной памятью, и так все процессы имеют возможность быть запущенными.
Планировщик (sheduler) выделяет CPU под процессы. Он распределяет запуск процессов пока они добровольно (произвольно) не освободят CPU на/во время ожидания ресурса, либо пока ядро не выгрузит их по истечении кванта времени. После планировщик выбирает процесс с наибольщим приоритетов для его запуска; первичный процесс будет запущен опять тогда, когда он будет являться процессом с наивысшим приоритетом.
Существует несколько видов межпроцессорного взаимодействия, начиная с асинхронной передачи событий (asynchronous signaling of events), заканчивая синхронной передачей сообщений между процессами.
Управление аппаратным обеспечением
И наконец, управление аппаратным обеспечением (hardware control) ответственно за обработку прерываний (handling interrupts) и общения с машиной. Такие устройства как диски или терминалы могут прерывать CPU во время выполнения процесса. В таком случае ядро может продолжить исполнение прерванного процесса после обслуживания прерывания. Прерывания не обслуживаются специальными процессами, а специальными функциями ядра, вызываемыми в контексте текущего запущенного процесса.
Литература:
- The Design Of the Unix Operating System by Maurice J. Bach, 1986
04 августа, 2008
uClinux - инструменты сборки
Итак, Вы теперь имеете систему разработки uClinux. Вкратце об <установке>
- набор программ разработки uClinux должен быть установлен в /opt/uClinux
- m68k-coff использовался для компиляции ядра. Он не связан со стандартной С библиотекой uC-libc.
- ядро uClinux установленно в /opt/uClinux/linux
- m68k-pic-coff - это PIC компилятор, который использовался для сборки бинарников пользовательского пространства.
- стандартная С библиотека uC-libc должна быть скомпилирована как libc.a и crt0.o и скопирована в /opt/uClinux/m68k-pic-coff/lib, а их include файлы в /opt/uClinux/m68k-pic-coff/include
- стандартная математическая библиотека uC-libm дложна быть скомпилирована как libm.a и math.h, включенные в /opt/uClinux/m68k-pic-coff/lib и /opt/uClinux/m68k-pic-coff/include соответственно.
- m68k-pic-coffs’ LD заменен скриптом, который вызывает линковщик LD, затем COFF2FLT создает плоский бинарный модуль (Flat Binary Image) из coff файла
- утилита genromfs должна быть собрана и установлена, и добавлена в path
- Romdisk извлечен в /opt/uClinux/romdisk
- коды пользовательского пространства uClinux установлены в /opt/uClinux/src
- скрипт deftemplate.sh должен быть помещен в /opt/uClinux/
- скрипт buildenv.sh должен быть помещен в /opt/uClinux/bin/ и добавлен в path
Есть две области разработки: средства ядра uClinux и средства пользовательского пространства. Так как ядро представлено для множества платформ, основным местом разработки будет пользовательское пространство. Как бы там ни было, ядро uClinux должно быть установлено первым.
Сборка ядра uClinux
Ядро должно быть сконфигурировано перед сборкой. Для тех, кто конфигурировал ядро для настольных ПК, эта процедура будет знакома, кроме конечно того, что uClinux не поддерживает загружаемые модули. Для других это будет испытанием.
Для начала перейдите в /opt/uClinux/linux и запустите конфигурационную утилиту
cd /opt/uClinux/linux
make menuconfig
Время конфигурации ядра. Так как Вы будете ссылаться на различные архитектуры и платформы, здесь нет особо выбора. Выберите Ваш процессор и плату из Platform Dependent Setup, и пропустите конфигурацию дополнительных параметров.
Как только вы закончили с конфигурационными дилемами, пришло время сборки. Просто запустите следующие команды, откиньтесь на спинку кресла и следите. Это может занять некоторое время, в зависимости от скорости Вашей системы.
make dep
make clean
make linux.bin
Make dep говорит make об установке зависимостей. Clean очистит все старые компоненты предыдущих сборок, а linux.bin соберет образ linux.bin, что является ядром в чистом бинарном виде.
По завершении Вы должны иметь парочку файлов в директории linux (/opt/uClinux/linux). Это будут linux.text, linux.data, linux.bin и карта системы (system map).
Процедура сборки ядра
Сбоорка ядра начнется со сборки отдельных компонентов/подсистем ядра. Как только это будет сделано, все объектные файлы подсистемы будут связаны (linked) используя секцию компоновочного файла (.LD), который будет находится в arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/$(MODEL).ld, и запускать C asm код (crt0_rom.S) для создания файла linux.
LD -T (MODEL).ld crt0_$(MODEL).o [objs] -o linux
Компоновщик определяет секцию памяти, он сообщает компилятору сколько памяти доступно и где разместить разные куски кода. Загрузочный asm код - это код, который запускается прямо после reset vector или загрузчика (bootloader), который поднимает различные части микроконтроллера, такие как clock dividers, serial port, DRAM, SRAM, memory banks, watchdogs и т.д., которые должны быть установлены перед тем как микроконтроллер сможет запустить ядро linux. Также он поднимает стэк, обнуляет .bss сегмент, копирует .data сегмент в RAM и переходит к start_kernel() который является входной точкой в C Код.
Символьная/системная карта (symbol/system map) генерируется из файла linux. Это удобно для показа отладки, где каждая функция размещена в памяти.
NM $(LINUX) | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System.map
Linux.data, файл содержащий весь код сегмента данных, создан linux, удаляя все сегменты только-для-чтения и другие ненужные сегменты.
objcopy -O binary --remove-section=.romvec --remove-section=.text \
--remove-section=.ramvec --remove-section=.bss \
--remove-section=.eram linux linux.data
Файл Linux.text также содержит весь text segment код (fixed code и переменные/строки)
objcopy -O binary --remove-section=.ramvec --remove-section=.bss \
--remove-section=.data --remove-section=.eram \
--set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE linux linux.text
Сегменты .Text и .Data конкатенируются для синтеза linux.bin
cat linux.text linux.data > linux.bin
Мы закончили с linux.bin, что является бинарным кодом ядра. Теперь он может быть загружен в память и запущен. Однако будет сбой после попытки распаковки ROM filesystem и монтирования нодов устройства (device nodes), содержащихся внутри romfs.
Сборка ядра потребуется единожды до приминения каких-либо модификаций ядра. На каждой сборке системы romfs будет конкатенироваться с linux.bin.
ФС постоянной памяти (ROM filesystem)
Так как есть одна общая исходая директория для ядра linux, Вы можете сложить проекты ФСы rom и бинарников пространства пользователя. Вы можете иметь одно общее ядро на главном сервере, но иметь множество разработчиков, работающих над одной системой и использующих их собственные rom ФС.
Для установки рабочей среды всего лишь нужно создать директорию в подходящем месте, обычно /home/<username>/ для многопользовательской системы и запустить buildenv
cd /home/cpeacock/
mkdir ucsimm
buildenv
buildenv соберет среду разработки uClinux, создавая вначале Makefile в Вашей директории. Теперь если Вы наберете make, среда разработки будет скопирована из директории /opt/uClinux/, и создастся файл image.bin.
make
Теперь директория должна иметь такую структуру
Makefile deftemplate.sh image.bin linux romdisk romdisk.img romdisk.map src
Эта среда содержит бинарники пользовательского пространства в ФС ROM, которая монтирована ядром во время заргузки. Каждый исполняемый файл описанный в /src/makefile скомпилирован и его плоский бинарнкик помещен в /src/bin. Файл deftemplate.sh запущен для копирования конкретных бинарников в дерево виртуального диска постоянной памяти (romdisk), который будет представлять базу нашего romfs образа. Заметим, что скрипт deftemplate только копирует бинаркники в дерево romdisk. Он не удаляет их(бинарники), поэтому чтобы сделать это Вы должны раскамментировать соответствующую строку в скрипте deftemplate и вручную удалить файл из дерева rom диска.
Дерево rom диска также включает конфигурационные файлы и структуру директорий ФС rom
/bin /dev /etc /htdocs /lib /proc ramfs.img /sbin /tmp /usr /var
ФС romdisk.img автоматически генерируется из дерева используя
genromfs -v -V "ROM Disk" -f romdisk.img -d romdisk 2> romdisk.map
romdisk.img затем конкатенируется с /linux/linux.bin (бинарник ядра мы собирали ранее) для создания
cat linux/linux.bin romdisk.img > image.bin
image.bin - файл, который содержит ядро linux плюс ROM FS. Этот образ укомплектован и готов для закачки в Вашу uClinux Систему. Для лучшего представления процесса сборки, типичная карта памяти 2.0.38 uCsimm показана на рисунке ниже.
Память загрузчика (bootloader flash) уже присутствует в системе разработки, которую мы используем (в нашем случае uCsimm). Это модуль dragonball от Lineo. Сегменты ROM Vectors, .TEXT и .DATA созданы как часть компиляции ядра. Эти три секции составляют файл linux.bin, который может быть найдет в /opt/uClinux/linux.
Бинарники скомпилированы как плоские исполняемые и помещены в директорию rom диска. Затем Genromfs пакует это в romfs.img, который конкатенирован с linux.bin для предоставления файла image.bin. Это повысит или понизит размер, в зависимости от того какие файлы Вы включили в ФС ROM. Единственное ограничение накладывается на максимальное пространство вашей системы.
image.bin - это бинарный файл, который загружается в систему разработки через загрузчик (bootloader).
Настройка romfs
В настоящий момент мы собрали достаточно для загрузки image.bin и благополучно зарегистрировались в целевую систему uClinux. Однако мы используем стандартный IP адрес и другие параметры прямо из коробки.
Войдите в директорию с Вашим диском rom (romdisk). Вы должны иметь структуру, похожую на эту:
/bin /dev /etc /htdocs /lib /proc ramfs.img /sbin /tmp /usr /var
Как в любой системе linux, критические конфигурационные файлы могут быть найдены в /etc
inetd.conf inittab issue passwd rc resolv.conf services
Стандартный rc файл выглядит так:
#!/bin/sh
#
# system startup.
# set up the hostname
/bin/hostname uCsimm
# attach the interfaces
/sbin/ifattach
/sbin/ifattach \
--addr 192.168.1.200 \
--mask 255.255.255.0 \
--net 192.168.1.0 \
--gw 192.168.1.100 eth0
# expand the ramdisk
/sbin/expand /ramfs.img /dev/ram0
# mount ramdisk, proc and nfs
/bin/mount -t ext2 /dev/ram0 /var
/bin/mount -t proc proc /proc
/bin/mount -t nfs 192.168.1.11:/home/jeff/kit /usr
# start up the internet superserver
/sbin/inetd &
# that's it... success
exit 0
Вам нужно будет изменить имя хоста (hostname), IP адрес, маску, сетевые параметры и параметры шлюза. Также нужно изменить монтирование nfs, /bin/mount -t nfs 192.168.1.11:/home/jeff/kit /usr
Монтирование NFS тома для Разработки
NFS или Network File System - это путь экспортирования и монтирования директорий в UNIX системах. Это может быть очень удобно во время разработки, позволяя легко выводить Вашу рабочую директорию на uClinux платформу. Это дает возможность компилировать код в linux системе и запускать его на сетевом диске embedded системы без копирования flat бинарников или прошивки новой ROMFS. Можете представить себе какое огромное количество времени Вы экономите.
С утилитой флэш-загзузки/сетевой загрузки для целевой платформы Вы можете производить обновления флэша через кабель. Это также ускорит разработку. Пересылка 1MB image.bin файла через 115,200 serial link не так быстро.
Перед использованием NFS потребуется установить песочницу для разработки, чтобы извлечь нужные Вам директории. Рекомендуется провести некоторое время без внешнего подключения к интернет. NFS exports определены в файле /etc/exports. Надо редактировать от рута.
Типичная запись вывода имеет такой вид
/home (ro)
Это выведет домашнии директории (home) для всех с правами только чтение. Если Вы имеете чувствительную информацию в домашней директории, Вы можете явно указать на среду разработки или уточнить, какие машины имеют доступ к директории вывода, а именно:
/home/cpeacock/ucsimm uCSimm(ro)
где uCsimm - имя хоста uClinux системы. Оно должно быть включено в /etc/hosts, или же должен быть указан явный IP адрес.
После замены директории вывода нужно перезагрузить компьютер (windows way :) ) или перезапустить NFS демоны. Вот так:
/etc/rc.d/init.d/nfs stop
/etc/rc.d/init.d/nfs start
(на многих linux системах)
Как только это сделано, модифицирйуте файл rc и включите сюда данные о монтировании, в моем случае
mount -t nfs 192.168.0.1:/home/cpeacock/ucsimm /usr
Вы также можете зарегистрироваться в вашу uClinux систему и запустить это в коммандной строке. Это удобно после того, как uClinux система приведена в порядок, и теперь нужно быстро сделать некоторые вещи или reimage.
ФС оперативной памяти (RAM FileSystem)
uClinux имеет RAM ФС (ramdisk) для временных областей /tmp и /var в отсутствии жесткого диска (hard disk drive, HDD). romdisk текущиего дистрибутива uClinux идет с ramfs на 256кбайт. /tmp в корне - это символическая ссылка на /var/tmp. var - это точка монтирования RAM ФС.
ramfs распакована и монтирована через скрипт запуска rc,
# expand the ramdisk
/sbin/expand /ramfs.img /dev/ram0
# mount ramdisk, proc and nfs
/bin/mount -t ext2 /dev/ram0 /var
Она содержит ext2 ФС, которая сжата при помощи алгоритма Zero Run Length Encoding (ZRTE). Она распаковывается при помощи утилиты распаковки в блочное RAM устройство /dev/ram0. Как только этот процесс завершен, она монтирована как ext2 ФС с точкой монтирования /var.
Если нужно исправить ссылку на tmp, мы можем просто добавить команду в rc скрипте для создания директории tmp в var после монтирования ramfs. Как бы то ни было, увеличить размер ramdisk будет не так легко. Для этого нужно создать новый ramfs.img. Для некоторых приложений даже необходим больший размер ramdisk. Вы возможно захотите журналировать данные в файл, который затем будет скачан, используя анонимный FTP, HTTP, или другое.
Создаем новую ramfs
Создание новой ramfs - достаточно простая задача. Одна проблема, на которую следует обратить внимание - это порядок следования байт в вашей системы (endianness).
Начнем с обнуления блочного устройства ram. Позже мы будем использовать утилиту сжатия в целях получения более сжатого образа. Вам также нужно выбрать размер диска ramdisk. Большой ramdisk позволит Вам записывать большие журналы и временные файлы, но с затратами на системной RAM. Это зависит от того, какие приложения Вы используете на uClinux системе.
# dd if=/dev/zero of=/dev/ram0 bs=1k count=1024
1024+0 records in
1024+0 records out
Далее сделаем ext2fs. Флаг -v включает вербальный режим, так что мы сможем увидеть некоторую статистику. По умолчанию 5% блоков зарезервировано для суперпользователя. Мы это выключим, используя -m0. Мы также отключим любые другие дополнительные возможности ФС ext2, используя -Onone. На пост 2.2 ядерных системах, опции sparse_super и filetype автоматически включены при создании ext2fs. Однако обе эти возможности некорректно поддерживаются ядром pre 2.2, и как результат mount сообщает о проблеме при монтировании ФС на системе 2.0.38 uClinux.
# mke2fs -vm0 -Onone /dev/ram0 1024
mke2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
128 inodes, 1024 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
128 inodes per group
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
На следующем шаге мы добавим дополнительные папки и файлы к ramdisk. Это необязательная процедура, поэтому Вы можете ее пропустить. По умолчанию при создании ФС ext2 добавляется директория lost+found. Она появится в /var/lost+found. Также рекоммендуется создать папку tmp. Чтобы добавить файлы и папки, для начала монтируйте ФС как ext2.
# mount -t ext2 /dev/ram0 /mnt/ramdisk
# cd /mnt/ramdisk
# mkdir tmp
Как только Вы закончили, отмонтируйте ФС для обеспечения чистоты монтирования в будущем
# umount /mnt/ramdisk
Теперь время переместить ФС из блочного ram устройства в локальный файл. Копируем ФС байт-к-байту в ramfsraw.img. Для 1MB ramfs, этот файл будет размером в 1MB.
# dd if=/dev/ram of=ramfsraw.img bs=1k count=1024
1024+0 records in
1024+0 records out
Будет очень неэффективно добавлять файл размером 1Mb к romdisk в его текущей форме, и так как большая часть ФС свободна, мы можем очень эффективно сжать, используя ZRLE (Zero Run Length Encoding). Вы можете поискать документ, описывающий процесс “making a file with holes”.
ZRLE записывает блоки с ненулевыми данными, прибавляя к ним длину блока и ее позицию в файле. Так как в основном файл состоит из нулей, утилита обрезает их. Утилита распаковки просто обнулит всю длину распаковываемого файла, и затем скопирует блоки данных обратно в подходящие ячейки.
Сжатие может быть выполнено при помощи утилиты, называемой holes. Существует пара версий, в зависимости от порядка байт (endian) и/или размера блоков. Вы можете скачать исходные коды с ftp://ftp.beyondlogic.org/uClinux/ramfsutils.tar.gz и скомпилировать их. Эти бинарники запустятся на Linux платформе с обратным следованием байт (little endian platforms).
# /holes/holes ramfsraw.img >ramfs.img
Length of original file 1048576
Листинг двух файлов покажет длину сжатия. Теперь мы можем добавить его на наш romdisk, не затрачивая пространства.
# ls ram* -l
-rw-r--r-- 1 root root 2639 Mar 4 16:00 ramfs.img
-rw-r--r-- 1 root root 1048576 Mar 4 15:59 ramfsraw.img
Вы также можете заметить что сгенерированный ramfs.img меньше, чем uClinux ramfs.img (3340). Еще одна причина почему Вы должны обновлять и генерировать самостоятельно. (По некоторым причинам, размер блока run length на запасной ramfs не должна быть больше 200-300 байт даже если expand.c размещает буфер в 2048 байт при распаковке образа).
Тестируем RAM filesystem
Можно протестировать новую ramfs на Вашей uClinux платформе, сначала отмонтируя существующую ramfs, а затем распаковывая и монтируя новую ramfs.
/bin/umount /var
/sbin/expand /ramfs.img /dev/ram0
/bin/mount -t ext2 /dev/ram0 /var
Также Вы возможно захотите протестировать ее на Вашем настольном linux. Копирование файла expand.c из /src/init/ и перекомпиляция для x86 linux приведет к endianness проблеме. Исправьте define в ntohl(), или используйте прекомпилированный бинарник для x86 отсюда (ramfsutils.tar.gz).
Корневая ФС на NFS
Монтирование директории разработки uClinux в /usr поможет Вам ускорить процесс разработки. Это позволит разработчику компилировать бинарники m68k в linux системе и мгновенно иметь их через монтированный NFS том.
Может случится ситуация когда Вы захотите модифицировать другие файлы на FLASH, например, конфигурационные файлы /etc для инетрнет демонов, http web servers. One option is the flash and burn method - изменить файл, пересобрать образ, закачать образ в uClinux систему, задержать воздух и надеяться на то, что изменения верны.
Наиболее скоростной подход и, таким образом, лучший вариант решения проблемы заключается в монтировании корневой директории uClinux как NFS том, которая вытягивается с машины разработки. Это позволит модифицировать любой файл в ФС и иметь их быстродоступными на uClinux системе. Ясно, что это сохранит львинную долю времени.
Установка корневой ФС NFS заставляет немного подумать над ядром. Для начала редактируем файл setup.c в /arch/{arch}/kernel/ и добавляем следующие строки для установки деталей о NFS сервере и хосте в буффер командной строки ядра.
ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
+ #ifdef CONFIG_ROOT_NFS
+ strcpy(command_line,
+ "root=/dev/nfs "
+ "nfsroot=192.168.0.2:/ucsimm/romdisk "
+ "nfsaddrs=192.168.0.200:192.168.0.2:192.168.0.1:255.255.255.0:"
+ "ucsimm:eth0:none");
+ #endif
/* Keep a copy of command line */
*cmdline_p = &command_line[0];
memcpy(saved_command_line, command_line, sizeof(saved_command_line));
saved_command_line[sizeof(saved_command_line)-1] = 0;
Формат этих параметров
root=/dev/nfs
Используется для доступа к корню NFS. Это не настоящий том, а псевдо-NFS-том.
nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
server-ip - это IP адрес NFS сервера, от которого Вы хотите монтировать ФС. Диретория root конкретизирует имя директории на NFS сервере для монтирования корня. Дальше идет запятая и другие страндартные параметры NFS. Парамерты необязательны. Дополнительные параметры могут быть найдены в файле nfsroot.txt как часть документации, которую Вы получаете с ядром.
nfsaddrs=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>
client IP - это IP адрес, который вы хотите присвоить embedded системе uClinux. Обычно присваивается ifattach в rc файле, но это не будет больше доступно локально, Вы должны предоставить эти подробности здесь. server-ip опять конкретизирует IP адрес NFS сервера - шлюз и маска должны быть self explanatory, hostname - это имя Вашей локальной машины, device указывает какой интерфейс устанавливать, тогда как autoconf указывает должны ли BOOTP либо rarp быть использованы.
Эти три параметра связаны вместе. Отделите пробелами каждую команду.
Как только изменения сделаны, и сохранены, начните конфигурировать ядро uClinux для поддержки корневой NFS. Опции можно найти в меню Filesystems - выбрать "NFS filesystem support" и "Root file system on NFS" обе. Затем пересобрать ядро. Как только ФС rom будет монтирована с сервера NFS, уже не нужно генерировать ROM ФС и конкатенировать ее с файлом linux.bin. Просто заргузите файл linux.bin как есть.
Убедитесь что директория, которую Вы указали в exported корректна и сбросьте uClinux. Если все пройдет успешно, загрузка должна быть похожа на
eth0: Attempting TP
eth0: using 10Base-T (RJ-45)
Root-NFS: Got file handle for /ucsimm/romdisk via RPC
VFS: Mounted root (nfs filesystem).
и дать пользователю зарегистироваться в системе как обычно. Если NFS сервер отсутствует, последует следующее сообщение (uClinux будет пытаться соединиться бесконечное количество раз, пока NFS сервер не появится в сети)
eth0: Attempting TP
eth0: using 10Base-T (RJ-45)
NFS server 192.168.0.2 not responding, still trying.
Вы также можете получить сообщение ниже, если exports некорректен или Вы пытаетесь получить директории с другого сервера. В этом случае проверьте файл exports и перезапустите NFS демон. После kernel panic Вам потребуется перезапустить uClinux перед попыткой соединиться снова.
eth0: Attempting TP
eth0: using 10Base-T (RJ-45)
Root-NFS: Server returned error 13 while mounting /ucsimm/romdisk
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device 02:00
Kernel panic: VFS: Unable to mount root fs on 02:00
31 июля, 2008
uClinux - установка среды программирования
Почему встраивать Linux?
Linux быстро набирает популярность как ОС для встраиваемых устройств
Вот несколько преимуществ такой ОС:
- свободное от цены лицензирование
Для традиционных встраиваемых платформ сумма на лицензии будет внушительная. Включенные в поставку устройств, сторонние ОС способствуют повышению цены на устройства. Linux же свободна. - надежный IP стэк и TCP/IP приложения
Годами Linux может работать на серверах и рабочих станциях. Также Linux будет работать и на встаиваемых устройствах. - исходный код ОС открыт
Сколько раз Вы, разрабатывая ПО, которое опирается на сторонний код, натыкались на баги? При консультации с вендором он даже не заинтересован в этом, тем более не будет отлаживать код неделями или месяцами для того, чтобы выпустить патч. С Linux Вы имеете исходный код на руках. Вы можете отладить баг и отдать код обратно сообществу. Это придаст ядру больше стабильности, и от этого выиграют все участники Linux сообщества. - исходные коды средств разработки открыты
Средства разработки - это набор необходимых пакетов программ для компиляции и генерации выполняемого кода из исходных текстов программ. Они также открыты. - время, необходимое на рынке
В изобилии открытого исходного кода и приложений, нацеленных на Linux, вы заметите, что "время на рынок" сократилось. Возьмем в качестве примера продукты Memory Fax/Modem, которые появились на рынке несколько лет назад. Это факс/модемы со встроенной памятью, которые позволяют получать факсимильные сообщения, когда компьютер выключен. Для размещения такого продукта на рынок будет необходимой разумный объем работы. Вместе с uClinux, разработчик может основывать свои продукты на продуктах с открытым исходным кодом, таких как efax. Она также позволяет включать IP маскарад (с небольшими усилиями), тем самым добавив больше функциональности продукту. Linux также поддерживает широкий спектр периферийных устройств и файловых систем.
Вдобавок, имеется множество целевых платформ и со временем их количество возрастает. Сейчас uClinux поддерживает серию 68328 dragonball, Coldfire, ARM7TDMI, ETRAX, I960.
Дистрибутив uClinux
uClinux - самая распространенная форма встаиваемого linux. uClinux (MicroController Linux) впервые был портирован на серию процессоров Dragonball 68k в 1998. uClinux отличается от mainstream linux тем, что не имеет поддержки MMU (noMMU). Также uClinux имеет малую базовую основу, что важно для микроконтроллеров с малыми ресурсами и BFLT (Binary Flat) Executable Format.Linux 2.0.38
- linux-2.0.38.tar.gz (7.5MB)
- uClinux-2.0.38.1pre7.diff.gz (1.3MB)
Ядро uClinux - это то место, где будет производится вся возня. Оно основано на ядре Linux 2.0.38. Оригинальное ядро Вы должны использовать на вашем настольном ПК. Патч uClinux применяется для работы с микроконтроллерами. Обычно патч включает поддержку устройств и убирает опору на MMU. Скачайте тарболы и поместите их в /opt/uClinux. Распакуйте и пропатчите ядро. Делается это так:
mkdir /opt/uClinux
cd /opt/uClinux
tar –xzf linux-2.0.38.tar.gz
gzip –d uClinux-2.0.38.1pre7.diff.gz
cd linux
patch -p1 < ../uClinux-2.0.38.1pre7.diff
Как только Вы это сделаете, то получите основу ядра uClinux. Теперь Вам нужно собрать компилятор, который сможет компилировать код в M68k. Позже, в сборке uC-libc, попробуем включить файлы из linux/include/asm. "asm" - это символическая ссылка, указывающая на папку asm-, где arch - архитектура ядра. Например, если конфигурировать uClinux для m68k с noMMU, папка asm будет указывать на asm-m68knommu. Посему, это хорошее место для начала конфигурирования ядра, которое может быть сделано без компилятора m68k-coff.
По дефолту конфигурация для uCSimm, поэтому если Вы имеете другие платы необходимо их переконфигурировать ядро. Нет нужды собирать ядро, фактически Вы не можете собрать его из-за отсутствия средств разработки. make config установит ссылку на asm, которая будет необходима позже для сборки стандартной библиотеки с, uC-libc.
make menuconfig
Средства разработки (Toolchains)
Имеется два разных набора необходимых пакетов программ для компиляции и генерации исполняемого кода (Toolchains) для uClinux. Один используется для компиляции ядра и производит 32бит M68k фиксированный двоичный объектный код. Другой используется для компиляции кода пользовательского пространства и производит 32бит M68k PIC код (position independent code).Toolchains ядра - ничего больше как запуск фабрики gcc 2.7.2.3. diff ядра делает одну маленькую модификацию в файле /config/m68k/t-m68kbare, вставляя TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc для предотвращения нужды в libc.
Toolchains пользовательского пространства другой предмет обсуждения. Он имеет весьма обширные изменения. Эти изменения лежат в требовании иметь разрядо-независимый объектный код (PIC). Нет прямых переходов, но взамен они заменены родственными ветвями. Глобальные данные возвращаются родственно в регистр A5.
Есть два варианта для cборки tool chains. Можно скачать uClinuxgcc-kit-160899.tar.gz, который содержит все патчи и makefile для автоматической сборки binutils и gcc для среды ядра и пользвателя. Другой вариант: пропатчить и собрать средства самостоятельно и изучить, что происходит в процессе. Мы рассмотрим оба способы здесь.
Простая сборка Tool Chains
Скачиваем следующее:- binutils-2.9.1.tar.gz (5.6MB)
- gcc-2.7.2.3.tar.gz (6.9MB)
- uClinuxgcc-kit-160899.tar.gz (40KB)
Извлекаем uClinuxgcc-kit-160899.tar.gz. Можно собрать в любой директории, не зависимо от, /opt/uClinux
tar -xzf uClinuxgcc-kit-160899.tar.gz
cd uclinuxgcc-kit-160899
Правим Makefile (первая строка). Изменяем INSTALLDIR на подходящее место - лучше в /opt/uClinux. Соберем m68k-coff и m68k-pic-coff tool chains набрав make Комманда создаст исполняемые файлы в /opt/uClinux/bin. Можно добавить /opt/uClinux/bin в path, или связать новые бинарники с /usr/bin:
cd /opt/uClinux/bin
ln -f * /usr/bin
Это было не сложно. Теперь посмотрим что происходит при ручной сборке.
Ручная сборка Tool Chains - m68k-coff
Начнем со сборки инструментов m68k фиксированной разрядности, m68k-coff. Скачаиваем:Извлекаем binutils из тарболов в подходящую директорию и входим туда:
tar -xzf binutils-2.9.1.tar.gz
cd binutil-2.9.1
Конфигурируем binutils под свою аритектуру. Начнем сначала с m68k-coff так как этот подход не требует патчей.
./configure --prefix=/opt/uClinux --target=m68k-coff
Собираем m68k-coff bin устилиты:
make
make install
make создаст директорию /opt/uClinux/m68k-coff которая будет содержать 5 поддиректорий, включая bin, include, libs, m68k-coff и man. Они будут содержать хэдеры, которые нужны для создания gcc. Вернитесь обратно в директорию с gcc-2.7.2.3.tar.gz.
Извлеките gcc тарбол, пропатчите и войдите в директорию с исходниками gcc:
tar -xzf gcc-2.7.2.3.tar.g
gzip -d gcc-2.7.2.3.kernel.diff.gz
cd gcc-2.7.2.3 patch -p1 < ../gcc-2.7.2.3.kernel.diff
Сконфигурируйте gcc для своей архитектуры. Префикс должен быть таким же как для binutils, так gcc будет искать хэдеры предварительно созданные при установке binutils.
./configure --prefix=/opt/uClinux --target=m68k-coff
Теперь скомпилирйуте C кросс компилятор для m68k-coff. LANGUAGES=c говорит make файлу собрать только С компилятор, а не C++, что может повлечет за собой некоторые излишние проблемы.
make LANGUAGES=c
make LANGUAGES=c install
Сейчас вы должны иметь компилятор m68k-pic-gcc для сборки ядра. Исполняемый файлы должны лежать в /opt/uClinux/m68k-coff/bin. Чтобы продолжить и собрать инструментальные средства pic-coff мы должны удалить рабочие директории или переименовать их. Лучше переименовать их, потому как Вы собираете исходники с нуля, не скачивая RPM, поэтому Вы можете позже исправить ошибки и применить патчи. Переименуйте binutil-2.9.1 в binutil-2.9.1.kernel и gcc-2.7.2.3 в gcc-2.7.2.3.kernel
Ручная сборка Tool Chains - m68k-pic-coff (разрядно-независимый код, Position Independent Code)
- binutils-2.9.1.tar.gz (5.6MB)
- gcc-2.7.2.3.tar.gz (6.9MB)
- gcc-2.7.2.3.pic.diff.gz (32KB)
- binutils-2.9.1.pic.diff.gz (8KB)
Теперь повторим те же процедуры для компилятора m68k-pic-coff. В этот раз binutils должны быть пропатчены
tar -xzf binutils-2.9.1.tar.gz
gzip -d binutils-2.9.1.pic.diff.gz
cd binutils-2.9.1
patch -p1 < ../binutils-2.9.1.pic.diff
в этот раз конфигурируем средства разработки для m68k-pic-coff
./configure --prefix=/opt/uClinux --target=m68k-pic-coff
затем делаем бинарные утилиты m68k-coff.
make
make install
Теперь мы готовы собрать gcc компилятор. Извлекаем тарболы с исходными кодами, патчим и входим в директорию с gcc
tar -xzf gcc-2.7.2.3.tar.gz
gzip -d gcc-2.7.2.3.pic.diff.gz
cd gcc-2.7.2.3 patch -p1 < ../gcc-2.7.2.3.pic.diff
Конфигурируем gcc для своей архитектуры. Префикс должен быть таким же как и для binutils, так как gcc будет просматривать те хэдеры с которыми создавались binutils
./configure --prefix=/opt/uClinux --target=m68k-pic-coff
Делаем m68k-coff C кросс компилятор
make LANGUAGES=c
make LANGUAGES=c install
m68k-pic-coff и m68k-coff можно поместить в path, или создать жесткую ссылку в /usr/bin.
cd /opt/uClinux/bin
ln -f * /usr/bin
Жесткие ссылки созданы взамен мягким. Если была попытка создать мягкую ссылку, gcc/evecvp пожалуется на большое количество символических ссылок ("too many levels of symbolic links"). /opt/uClinux/bin содержит мягкие ссылки, которые указывают на директории bin отдельного компилятора.
На данной ступени мы имеем С компилятор, который делает разрядно-независимые COFF бинарники. Чего у нас пока что нет, это стандартной С и стандартных математических библиотек. uClinux также зависит от плоских бинарников (flat binaries), а не только coff (Common Object File Format). Поэтому мы должны добавть конвертер из coff во flat (coff2flt), который конвертирует модули coff, которые генерирует компилятор, во flat бинарники, которые мы сможем запускать на uClinux.
coff2flt (COFF - Common Object File Format to Flat Binary конвертер)
В порядке создавать плоские бинарники одной коммандой, линковщик (LD) заменен скриптом, который сначала запускает линковщик, который генерирует .coff файл, затем запускает утилиту coff2flt для генерации плоского бинарника.- coff2flt-0.5.tar.gz (6KB)
Скачиваем и распаковываем утилиту
tar -xzf coff2flt-0.5.tar.gz
cd coff2flt-0.5
make
make соберет coff2flt. В тарболе скрипт, линковщик. Мы должны заменить pic-coff-ld этим скриптом, в который возвращаются вызовы coff2flt для создания flat бинарника из coff бинарника. Однако перед тем как мы это сделаем, отредактируем строку в LD для установки %prefix% в /opt/uClinux/m68k-pic-coff
mv /opt/uClinux/m68k-pic-coff/bin/ld /opt/uClinux/m68k-pic-coff/bin/gld
install -m 755 coff2flt /opt/uClinux/m68k-pic-coff/bin
cp ld /opt/uClinux/m68k-pic-coff/bin
chmod 755 /opt/uClinux/m68k-pic-coff/bin/ld
Стандартная Библиотека C
- uC-libc-310899.tar.gz (233KB)
При компиляции бинарников пользовательского пространства используются две библиотеки. Это стандартная библитека С и стандартная математическая библиотека. Это статические библиотеки, которые линукются во время компиляции.
Стандартная С библиотека uC всегда имела беду с ошибками. В частности они имеют плохую манеру утечки памяти из-за их функций выделения памяти. Некоторые индивидуумы имеют патчи для malloc функций, которые можно вручную применить и собрать.
uC-libc испытавает очень радикальные изменения в данный момент. Эти экспериментальные изменения доступны через uClinux CVS хранилище. Стабильная библиотека должна быть доступна скоро, она заменит старые версии uC-libc и предоставит наиболее стабильную платформу. На позитивной ноте, должен сказать, что математическая библиотека имеет маленькие проблемы.
Извлекаем тарбол uC-libc в /opt/uClinux
tar -xzf uC-libc-310899.tar.gz
Библиотека uC-libc имеет две символические ссылки (include/linux и include/net), которые должны указывать на хэдеры ядра uClinux. Эти ссылки требуют, чтобы директория linux находилась в том же дереве, что и директория uC-libc. Если одной не существует из-за различных мест инсталляции, Вы можете создать ссылку.
Библиотека uC-libc в нынешнем состоянии не имеет функций setjmp и longjmp, которые позже потребуются sh. Простейший путь поправить это, переместить uC-libc/machine/setjmp.S в uC-libc/sysdeps/ и включить это (setjmp.o) в uC-libc/sysdeps/makefile.objs
cd uC-libc
make
Если Вы получите сообщения об ошибках о пропавших файлах(скорее всего в директориях asm, linux или net) такую как "/asm/types.h - No such file or directory," тогда проверьте сконфигурировали ли Вы ядро (/include/asm ссылки на месте) и что здесь находятся исходный код ядра linux и ссылка на linux в той же директории что и uC-libc оба.
make скомпилирует библиотеку uC-libc (libc.a) и оставит ее в директории uClibc. Теперь мы должны сделать ее доступной для средств m68k-pic-coff. Каждая ссылка может быть создана, а файлы скопированы
cp libc.a /opt/uClinux/m68k-pic-coff/lib/libc.a
cp crt0.o /opt/uClinux/m68k-pic-coff/lib/crt0.o
Хэдеры также должны быть доступны. Chaintool уже поместил assert.h в /opt/uClinux/m68k-pic-coff/include, поэтому можно переименовать текущую директорию
mv /opt/uClinux/m68k-pic-coff/include /opt/uClinux/m68k-pic-coff/include.old
ln -sf include /opt/uClinux/m68k-pic-coff/include
Стандартные математические библиотеки
- uC-libm-0.9.1.tar.gz (101KB)
Стандартные математические библиотеки не такие проблематичные как С библиотеки. Просто извлеките их в /opt/uClinux и соберите
tar -xzf uC-libm-0.9.1.tar.gz
cd uC-libm
make
затем создайте ссылки в m68k-pic-coff/lib для указания на библиотечные файлы и хэдеры. Эти хэдеры будут обычно находится по их пути в директорию uC-libc/include символической ссылкой.
ln -f libmf.a /opt/uClinux/m68k-pic-coff/lib/libmf.a
ln -f libmf.a /opt/uClinux/m68k-pic-coff/lib/libm.a
ln -f mathf.h /opt/uClinux/m68k-pic-coff/include/mathf.h
ln -f mathf.h /opt/uClinux/m68k-pic-coff/include/math.h
genromfs - ROM FileSystem Generation Utility
- genromfs-0.3.tar.gz (17KB)
- genromfs-0.3.diff.gz (1KB)
Genromfs генерирует ФС с постоянной памятью (ROM Filesystem). Извлеките, пропатчите и соберите так:
tar -xzf genromfs-0.3.tar.gz
gzip -d genromfs-0.3.diff.gz
cd genromfs-0.3
patch -p1 <../genromfs-0.3.diff
make
make install
make install инсталирует genromfs в /usr/bin + положит свою документацию в usr/man/man8 Genromfs теперь может быть вызвана из коммандной строки для генерации своей romfs.
genromfs -v -V "ROM Disk" -f romdisk.img -d romdisk 2> romdisk.map
Genromfs имеет несколько багов относительно нодов устройства (device nodes). Если Ваша romfs не корректна, ядро сообщит об этом (can't open the device node) и тогда запаникует (panics). Чаще всего полезней монтировать Вашу снова сгенерированную romfs чтобы посмотреть все ли корректно. Делается это так:
mount -r -o loop -t romfs romdisk.img /mnt/romfs
Диск с ROM ФС и бинарники пользовательского пространства
- romdisk-0.9.1.tar.gz (184KB)
- uC-src-0.9.1.tar.gz (526KB)
- deftemplate.sh (1KB)
- buildenv.sh (1KB)
Диск с постоянной памятью (romdisk-0.9.1.tar.gz) - сжатый тарбол, который содержит ноды устройства (device nodes). В итоге файл должен быть распакован (от root'а) в /opt/uClinux
tar -xzf romdisk-0.9.1.tar.gz
Диски romdisk образуют базис ФС встаиваемых (embedded) систем. Утслита genromfs создаст romfs.img из данного дерева, таким образом любые изменения в дереве будут отображены в ФС uClinux. Диск romdisk имеет следующие директории и файлы:
bin dev etc htdocs lib proc ramfs.img sbin tmp usr var
Вы заметите, что при входе в каталог bin предварительно скомпилированные бинарники будут видны. Их исходные коды устанавливаются так:
tar -xzf uC-src-0.9.2.tar.gz
cd src
make
Если Вы испытываете проблемы со сборкой из sh - неопределенный указатель на 'setjmp' или 'longjmp', проверьте включили ли Вы setjmp.S в сборку uC-libc.
Запуск make соберет все исходные коды перечисленные в SUBDIR определенные Makefile. Поэтому если вы добавляете экстра код сюда, то должны влкючить их в Makefile. По завершении процедуры сборки, бинарники будут в находится в директориях src/bin. Скрипт deftemplate.sh скопирует необходимые бинарники из /src в /romdisk/bin или sbin.
cp deftemplate.sh /opt/uClinux/
Нужен еще последний файл. buildenv.sh установит среду сборки из чистой директории, копируя необходимый код устанавливая Makefile. Скопируйте buildenv.sh в /opt/uClinux/bin и создайте ссылку на /usr/bin.
cp buildenv.sh /opt/uClinux/bin/
ln /opt/uClinux/bin/buildenv.sh /usr/bin/buildenv
и всё. Теперь если Вы создадите пустую директорию где-либо и введете buildenv, таинственно появится Makefile. Затем введите make, чтобы увидеть исходные коды пространства пользователя, romdisk etc копируется поверх и соберется.
PIC32 патч - 32-битный PIC патч для m68k-pic-coff 2.7.2.3
- gcc-2.7.2.3-pic-32bit.diff
- crt0.S
- или . . . gcc-2.7.2.3-pic-32bit.tar.gz (Gzip архив двух файлов выше)
С текущим компилятором m68k-pic-coff, будет ограничение на сборку исполняемого кода размером свыше 32k. Размер исходит из использования 16-битного знакового сдвига. Эрвин Отрайд (Erwin Authried) выпустил некоторые патчи для m68k-pic-coff-gcc для генерации 32-битных сдвигов, которые снимают эти ограничения. Код может ббыть собран нормально с 16-битными сдвигами без указания дополнительных специфик. Если Ваша программа превышает 32k, тогда можно вызвать компилятор с флагами -fPIC, которые генерируют 32-битные сдвиги.
Код скомпилированный с -fPIC больше размером. В дополнении к патчу компилятора, нужен новый файл запуска C (C startup file, crt0.S). Он дожен быть скомпилирован и добавлен в m68k-pic-coff/lib. Файл запуска не содержит функции _cleanup(), поэтому должен быть включЕн из другого места.
Отладка
- gdb-4.18.tar.gz (11.3MB)
- gdb-4.18-gdbserver.diff.gz (2KB)
Отладка является необязательным дополнением для "башковитых" uClinux программистов. Состоит она из двух компонентов: gdb-4.18, запускаемый на хост машине, сконфигурированной для m68k-coff, и gdbserver, запускаемый на uClinux платформе. Вместе они общаются через сеть (IP). Пока gdb клиент компилирует с небольшими усилиями, gdb сервер нуждается не только в пропатчивании, но также из библиотеки uClibc, библиотеке отладки uClibc и поддержку из ядра uClinux - но это еще не всё.
gdbserver требует прерывание в ядре uClinux для работы. Хорошие новости в том, что это было включено в поздние ядра, и поэтому не требует внимания. Ядро uClinux-2.0.38.1pre7, описанное здесь, уже имеет эту поддержку.
Скачайте и распакуйте gdb-4.18
tar -xzf gdb-4.18.tar.gz
gzip -d gdb-4.18-gdbserver.diff.gz
cd gdb-4.18
patch -p1 <../gdb-4.18-gdbserver.diff
Сконфигурируйте gdb клиент запустив на хосте для отладки m68k-coff кода и соберите
./configure --target=m68k-unknown-coff
make
Для сборки gdbserver потребуются некоторые дополнительные фкнкции, которых нет в стандартной библиотеке uC-Libc. Исходный код есть в библиотеке, но не задан для сборки по дефолту. Зайдем в /uC-libc/sysdeps/m68k и отредактируем ptrace.c так чтобы путь к ptrace.h был корректен. Заменим #include <sys/ptrace.h> на #include<linux/ptrace.h>.
Теперь добавим исходный код для сборки, редактируя /uC-libc/sysdeps/makefile.objs добавив m68k/ptrace.o в конец списка OBJS, чтобы это смотрелось так
waitpid.o \
write.o \
m68k/ptrace.o
Затем пересоберем библиотеку uC-libc и довавим новый libc.a в /m68k-pic-coff/lib
cd gdb-4.18/gdb/gdbserver
../../configure --target=m68k-linux-coff
Затем отредактируем Makefile, изменив CC = gcc на CC = m68k-pic-coff-gcc
make gdbserver
coff2flt -s 32768 -o gdbserver gdbserver.coff
Запуская make, Вы создаете плоский flat бинарный код gdbserver'а, размер стэка которого по умолчанию составляет около 4k. В результате gdbserver может рухнуть или отказать при соединении. Поэтому рекомендуется линковать с размером стэка в 32k
CVS – Concurrent Version System
Хранилище uClinux доступно на http://cvs.uclinux.org. Отсюда можно отслеживать обновления исходного кода и смотреть какие изменения были сделаны и зачем.Если вы хотите скачать полную версию исходных кодов, тогда это может быть сделано регистрацией в CVS используя CVS клиент. uClinux предоставляет анонимный доступ только для чтения к своему хранилищу.
Чтобы начать, Вы должны зарегистрироваться. Используйте следующую комманду:
echo anonymous > cvs –d:pserver:anonymous@cvs.uclinux.org:/var/cvs login
Тем сымым Вы войдете в CVS хранилище, используя имя anonymous и пароль anonymous.
cvs –z3 –d:pserver:anonymous@cvs.uclinux.org:/var/cvs co –P <dir>
где <dir> - одна из актуальных директорий,
uClibc The uClinux Userland C Library
uClinux-2.0.x 2.0.38 uClinux Kernel
uClinux-2.4.x 2.4.0 uClinux Kernel
userland uClinux Userland Binaries
Используется спецификатор -z3 для сжатия. Это максимальное сжатие. co необходимо для прекращения связи, -P конкретизирует отсеченные директории (убирает пустые директории).
Позже можно обновить исходные коды используя следующую комманду команду в соответствующей директории
cvs -z3 update -d -P
Ссылки:
GNU GCC
Linux
wiki: uClinux
wiki: binary file
30 июля, 2008
"Проблемы" Встраиваемых Систем GNU/Linux
Встраиваемые системы обычно:
- малые аппараты: сетевые устройства, карманные компьютеры, телефоны и т.д.
- не х86(arm, armel, ..), без MMU, без дисковые
"Проблемы":
- Малое финансирование во встаиваемые системы Linux, обычно со стороны вендоров аппаратного/программного обеспечения
- Нехватка разработчиков на kernel.org, опять же, обычно вовлечены разработчики вендоров аппаратных/программных средств(коммерческие)
- Во многих встраиваемых устройствах используется одна версия ядра в полном жизненном цикле продукта
(обычно производится только кастомизация ядра и поставка) - Своевременность и выпуски плотны
Технологии:
- Динамические тики, hr-таймеры
- DVB
- улучшение NoMMU
- Новые архитектуры: FRV, avr32, blackfin
Ядро:
- kevent: оперативная унифицированная доставка сообщений
- utrace: перепись кода трассировки процессов
- syslets/fibrils: асинхронные вызовы, AIO
Welcome to Linux Kernel Development http://www.linux.org/
01 июля, 2008
Стандарты и концепты системного програмирования в UNIX
Определение понятий - это начало ссылок.
Сократ
Ключевые моменты в современном UNIX программировании:
системные вызовы (syscalls), библиотека C (glibc), коллекция компиляторов (gcc), программные интерфейсы (APIs), бинарные интерфейсы (ABIs), ..[добавить нужное]
== стандарты: POSIX, SUS, C ==
UNIX стандарты.
Системное программирование в UNIX - древнее искусство. За 39 лет здесь не обошлось без хаоса и UNIX войн(расхождение линий AT&T и Berkley University в 1979, лишение прав компании Bell в 1984). Чтобы предотвратить хаос, группы выявления стандартов описали системные интерфейсы в официальных стандартах.
POSIX и SUS являются стандартами C API интерфейсов UNIX-подобных ОС.
В 1985 группа IEEE начала работать над стандартизацией интерфейсов системного уровня UNIX систем. Ричард Столлман (RMS) предложил название для даного стандарта: POSIX [произношение pahz-icks, как позитив]. Первый вариант POSIX появился в 1988: IEEE Std 1003.1-1998. (ISO, IEC приняли эти стандарты как ISO/IEC 9945). Версии стандартов описаны здесь.
The Open Group (объединение X/Open и OSF) также принимали участие в разработке стандартов для UNIX. Их главный труд Single UNIX Specification (SUS) (1994). Сегодня SUSv3(UNIX 03, 2002) включен в POSIX (IEEE Std 1003.1-2001).
C стандарты.
История раннего С описана в статье Д. М. Ритчи "The Development of the C Language, 1993".
== концепты: файлы, процессы, сигналы, IPC ==
Файлы
еще о файлах (начало здесь; ls([2,3]), stat.h)
..прежде чем получить доступ к файлу для чтения, записи, обработки или др. он должен быть открыт. Открытый файл указывается через уникальный дескриптор, соответствующий метаданным, ассоциированным с самим файлом. Этот дескриптор обрабатывается целым числом (тип int в C) называемым дескриптором файла(file descriptor, fd). fd разделены с пространством пользователя (user space), и используются пользовательскими программами напрямую для доступа к файлу.
Длина файлов ограничена (и только) размерами типов C (C types). Однако файловые системы(FS) могут накладывать свои ограничения, например, укрощать максимальную длину.
Один файл может быть открыт не один раз, причем даже тем же процессом. Каждому открытому экземпляру файла присваивается уникальный дескриптор (файловый дескриптор). Процессы могут совместно использовать fd, позволяя единственному дескриптору использоваться более чем одним процессом.
inode (information node) включает в себя метаданные ассоциированные с файлом, включая местоположение данных файла.
C точки зрения безопасности доступ к файлу через inode обременителен, поэтому файлы обычно открывают из пространства пользователя (user space) по имени (не по номеру inode!). Имя (в человеко-читаемой форме) и inode файла образуют пару, называемую ссылкой (link).
Когда ядро обращается к файлу оно проходит каждое вхождение директории (directory entry, dentry), начиная с /, то есть (для /home/va1e/unix.prog.01.st) сначала получает inode директории home, входит сюда, получает inode va1e, входит сюда, и, наконец, получает inode unix.prog.01.st. Эта операция называется развязкой пути (directory resolution). Для хранения результатов развязки (dir resolution) ядро использует кэш вхождений (dentry cache). Это позволяет быстро обращаться к файлам в будущем. Хотя и директории обрабатываются как обычные файлы, они должны управляться специальным набором системных вызовов.
Специальные файлы - это объекты ядра. И они являются файлами в соответствии парадигмы "всё - файл". Специальными файлами могут быть: файлы UNIX устройств (блочных устройств, символьных устройств [каждое устройство имеет свой файл]), именованные каналы (FIFO, механизм межпроцессорного взаимодействия [IPC]), UNIX сокеты (в отличие от IPC, сокеты позволяют взаимодействовать двум различным процессам не только на одной машине). Как и обычные файлы, специальные создаются путем системных вызовов.
Процессы
Следующим за файлами по значимости в UNIX идут процессы.
Процесс - это запущенный объектный код. Пример: запущенная в своем адресном пространстве программа. Процесс начинает свою жизнь с запуска объектного кода в исполняемом формате, который содержит метаданные, куски кода, загружаемые в память(например, инициализированные переменные С) и данные. Процесс также связан с системными ресурсами(аппаратное обеспечение, сетевые соединения, таймеры, сигналы, открытые файлы, механизмы межпроцессорного взаимодействия), которые управляются ядром; процесс работает с ресурсами только через системные вызовы. Ресурсы, их данные, записываются в дескриптор процесса внутри ядра.
Каждый процесс состоит из одной или нескольких нитей (threads), или единицы активности в процессе, которая отвечает за состояние процесса. Нить состоит из стэка (структуры данных), состояния процессора, и текущего размещения в объектном коде.
Каждый процесс обозначется уникальным целым числом - идентификатором процессы (process ID, PID) [ps(1)]. Дерево процессов(process tree) начинается с первого процесса init(8) [man 8 init]. Новый процесс создается системным вызовом fork(), который создает копию вызываемого процесса. Оригинальный процесс называется родительским (parent), новый - наследованным (child).
Сигналы
Сигналы (Signals) - это механизм односторонней передачи асинхронных сообщений. Сигнал может быть послан от ядра к процессу, от одного процесса другому. Обычно сигнал сообщает процессу о событии, например, аварийное завершение, или нажатие пользователем клавиш C-c. Число сигналов ограничено архитектурой. Каждый из них представлен числовой константой и именем. Например, SIGHUP (signal hangup) имеет значение 1 на x86 архитектуре.
IPC
Одной из важнейших работ ОС является возможность обмена информацией между процессами и предупреждение их о различных событиях(IPC). Многие механазмы IPC описаны в UNIX стандартах, указанных выше.
Список литературы:
1. SUSv3 [http://www.unix.org/version3/]
2. Стивен Прата. Язык программирования С. Лекции и упражнения. 2006, Вильямс
3. D. Lewine. POSIX Programmer's Guide: Writing Portable UNIX Programs. 1992, O'Reilly & Associates
4. R. Love. Linux System Pogramming. 2007, O'Reilly.
27 марта, 2008
Особенности файловой системы UNIX (BSD, Linux, Solaris, Mach, Hurd, Plan9)
- Что в файле?
- Каталоги и имена файлов
- Права доступа
- Команды
- Иерархия файловой системы
Что в файле?
Расширение имени файлов не имеет значения для типа файла.
Команда file делает предположение о типе файла.
~$ file /bin /bin/ed /usr/src/cmd/ed.c
/bin: directory
/bin/ed pure executable
/usr/src/cmd/ed.c c program text
file читает несколько сотен байт и ищет в них ключевые последовательности символов
например исполняемая программа начинается с "магического числа" в двоичном представлении. Команда od без параметров выводит дамп файла 16-битными порциями, позволяя увидеть это "магическое число"
~$ od /bin/ed
000000 000410 025000 000462 011444 000000 000000 000000 000001
000020 170011 016600 000002 005060 017776 010600 162706 000004
..
Восьмиричное значение 410 означает обычную исполняемыю программу. Заметим, что 410 не соответствует никакой ASCII-символ.
Каталоги и имена файлов
Все принадлежащие пользователю файлы имеют имена, начинающиеся с /usr/login, где login - имя вашей учетной записи, регистрационный каталог, чтобы просмотреть находящиеся здесь файлы введите cd(перенесет Вас в домашнюю директорию, если Вы еще не там); ls(1)
~$ сd; ls
команда pwd выведет имя текущего каталога
~$ pwd
/usr/login
В именнах файлов важен регистр букв, File и file - разные файлы
Права доступа
Команда ls запущенная с параметром -l, выводит, кроме основного содержания каталога, информацию о правах доступа.
~$ ls -l /etc/passwd
-rw-r--r-- 1 root 5115 Aug 30 10:40 /etc/passwd
~$ ls -lg /etc/passwd
-rw-r--r-- 1 adm 5115 Aug 30 10:40 /etc/passwd
В строке -rw-r--r-- представлены сведения о правах доступа к файлу, если бы это был каталог, то в первой позиции бы находился символ d.
~$ ls -l /
drwxr-xr-x 2 root root 4096 2008-03-25 11:42 bin
Следующие три символа показывают права владельца на чтение, запись и выполнение. rw-r--r-- означает, что пользователь root(владелец файла) из группы adm может читать и писать, но не может выполнять этот файл. У исполняемого файла должен стоять символ x вместо прочерка -. Следующие три симола rw-r--r-- показывают разрешения для группы adm, можно читать файл, но не более того. Последняя группа символов, также rw-r--r-- определяет права доступа для остальных - прочих пользователей системы. Таким образом только root может изменять регистрационную информацию, а всем остальным она доступна только для чтения.
Команда chmod изменяет права доступа к файлу
Восьмиричные значения образуются путем складывания 4 для чтения, 2 для записи, 1 для исполнения.
~$ chmod 666 file
дает право на чтение и запись файла file всем
~$ chmod 700 command
позволит читать, изменять, выполнять command только его владельцу
Отметим, что знак + (плюс) включает право доступа, а знак - (минус) - выключает.
~$ chmod +x command
позволит всем выполнять command
~$ chmod -w file
отменяет право на запись в файл file всех, включая владельца
~$ chmod -w .
запрещает право на запись в каталог, в котором мы находимся
Команды - это программы, которые вызывает пользователь. Основные команды расположены в директории /bin, но также могут быть расположены в
/usr/bin, чтобы не собирать мусор в /bin. Эти директории автоматически просматриваются командным интерпретатором (shell). UNIX имеет файловую систему компонованную в виде иерархии директорий.
При входе в систему вы попадаете в домашнюю директорию. Для того, чтобы обратиться к файлу в другой директорий, например /usr/share/bin/filex, указываем полный путь (начинается с '/', корневая директория всей файловой системы) с поддиректориями (usr, share, bin), то есть посылаем команду /usr/share/bin/filex
Важные команды, которые могут "играть" с файлами: cp(1), mv(1), rm(1), которые копируют, перемещают и удаляют файлы соответственно. Чтобы просмотреть содержание директорий используйте ls(1), создание директории - mkdir(1),
удаление директории - rmdir(1) или rm(1).
hier(7) - иерархия файловой системы
/ корневая директория
/dev/ devices(4)
console главная консоль, tty(4)
tty* терминалы, tty(4)
cat "наборщик снимков" cat(4)
rp* диски, rp, hp(4)
rrp* "сырые" диски, rp, hp(4)
/bin/ служебные программы, cf /usr/bin (1)
as ассемблер, cf /usr/lib/as2
cc исполнительный компилятор C, cf /usr/lib/c[012]
/lib/ объектные библиотеки и подобные вещи, cf /usr/lib/
libc.a системные вызовы, стандартные ввод/вывод I/O, и т.п.
libm.a математические программы
libplot.a программы рисования, plot(3)
libF77.a поддержка среды исполнения Фортрана
libI77.a ввод/вывод Фортрана
as2 второй "проход" ассемблера as(1)
c[012] проходы cc(1)
/etc/ важные данные и полезные средства сопровождения
passwd файл с паролями пользователей, passwd(5)
group файл с группами пользователей, group(5)
motd сообщение дня, login(1)
mtab таблица монтируемых устройств, mtab(5)
ddate сброс истории, dump(1)
ttys параметры терминала, ttys(5)
getty часть login, getty(8)
init отец всех процессов, init(8)
rc shell-программа для загрузки системы
cron часовой демон, cron(8)
mount mount(1)
wall wall(1)
/tmp/ временные файлы, обычно находятся на быстром устройстве, cf /usr/tmp/
e* испольуемые ed(1)
ctm* .. cc(1)
/usr/ универсальная директория, обычно монтируемая ФС
adm/ информация администратора
wtmp история входов в систему, utmp(5)
messages сообщения об ошибках устройств
tracct "наборщик снимков" счет , troff(1)
vpacct подсчет строк, lpr(1)
bin/ служебные программы, чтобы не засорять /bin/
tmp/ временные, чтобы не засорять /tmp/
stm* используется для sort(1)
raster .. plot(1)
dict/ список слов, словообразований и т.п.
words набор основных слов, используются look(1)
spellhist история для spell(1)
games/ игры
bj блэкджек
hangman виселица
quiz.k что знает quiz(6)
index оглавление категории
africa страны и столицы
..
..
include/стандартые #include файлы
a.out.h макет объектного файла, a.out(5)
stdio.h стандартные ввод/вывод, stdio(3)
math.h
..
sys/ системные макеты, cf /usr/sys/h
acct.h счет процессов, acct(5)
buf.h буфферы внутренней системы
..
lib/ объектные библиотеки и т.п., чтобы не засорять /lib/
lint[12] подпроцессы lint(1)
llib-lc холостое объявление для /lib/libc.a, используемое lint(1)
llib-lm .. /lib/libc.m
atrun планировщик at(1)
struct/ пути sruct(1)
..
tmac/ макросы для troff(1)
tmac.an макрос для man(7)
tmac.s .. ms(7)
..
font/ шрифты для troff(1)
R Times Roman
B Times Bold
..
uucp/ программы и данные uucp(1)
L.sys имена и числа, поступающие удаленно
uucico реальная копия программы
..
suftab таблица суффиксов для автоматического переноса слов, используемый troff(1)
units таблицы обмена для units(1)
eign лист английских слов, игнорируемых ptx(1)
man/ первый том руководства, man(1)
man0/ основное
intro вступление к тому1, ms(7) форматирование
xx шаблон для страниц руководства(manual pages)
man1/ раздел 1
as.1
mount,1m
..
cat1/ предварительные страницы man1/
as.1
mount.1m
..
spool/ замедленно исполняемые файлы
at/ at(1)
lpd/ lpr(1)
lock присутствует когда построчно-печатающее устройство активно
cf* копия распечатываемого файла, если нужно
df* файл управления демонами, lpd(8)
tf* файл контроля резидетной памяти, пока lpr работает
uucp/ рабочие фалйы и область обработки для uucp(1)
LOGFILE суммарный журнал
LOG.* журнал одной транзакции
mail/ почтовые ящики mail(1)
$uid почта пользователя $uid
$uid.lock блокировочный файл, пока $uid принимает почту
$wd рабочая директория пользователя, обычно по имени логина $wd
.profile окружение для sh(1), environ(5)
calendar календарь пользователя, calendar(1)
doc/ статьи, обычно второй раздел руководства, в формате ms(7)
as/ руководство ассемблера
c руководство C
..
sys/ системный код
dev/ драйверы устройств
bio.c общий код
cat.c cat(4)
dh.c DH11, tty(4)
tty tty(4)
..
conf/ железо-зависимый код
mch.s часть ассемблерного кода
conf генератор конфигураций
..
h/ заголовочные(include) файлы
acct.h acct(5)
stat.h stat(2)
..
sys/
main.c
pipe.c
sysent.c точки входа системы
..
/usr/ src/ исходные коды утилит и прочего
cmd/ коды команд
as/ ассемблер
makefile способ сборки ассемблера
as1?.s код pass1
ar.c код ar(1)
..
troff/ код nroff и troff(1)
nmake makefile для nroff
tmake makefile для troff
font/ код таблиц шрифтов, /usr/lib/font/
ftR.c Roman
..
term/ таблицы характеристик терминала, /usr/lib/term/
tab300.c DASI 300
..
..
libc/ код функций в /lib/libc.a
crt/ C runtime support
ldiv.s division into a long
lmul.s multiplication to produce long
..
csu/ запуск и "покрытие" программ нужных в каждой С программе
crt0.s обычный запуск
mcrt0.s модифицированный запуск для cc -p
sys/ системные вызовы
access.s
alarm.s
..
stdio/ функции стандартного ввода/вывода I/O
fgets.c
fopen.c
..
gen/
abs.c
atof.c
..
compall shell процедура для компиляции libc
mklib shell процедура для сборки /lib/libc.a
libI77/ коды /lib/libI77
libF77/
..
games/ исходные коды /usr/games/
Также смотрите
ls(1), ncheck(1), find(1), grep(1)
В Linux также можно изучить иерархию каталогов в руководстве hier
~$ man hier
Если Вы начинаете осваивать сисему UNIX возможно Вам понадобится руководство intro(2)
~$ man 2 intro
Литература:
1. UNIX TIME-SHARING SYSTEM, UNIX Programmer's Manual, V7Vol1, January, 1979, Bell Labs Inc., B.W. Kernigan, M.D.
McIlroy
2. UNIX Programming Environment, The First Edition, 1984, B.W. Kernigan
Также смотрите: Unix Toolbox (pdf буклет)