Контроллер КАМАК CM5307 Часть 2. Операционная система Linux. В.Р.Мамкин (т. 394284) V.R.Mamkin@inp.nsk.su Новосибирск, 2001 ОГЛАВЛЕНИЕ 1. Ядро................................................................................................................................................. 3 1.1. Особенности архитектурной реализации ............................................................................. 3 1.2. Командная строка. .................................................................................................................. 4 1.3. Модули..................................................................................................................................... 5 2. Корневая файловая система.......................................................................................................... 6 3. Файлы конфигурации.................................................................................................................... 8 4. RAM-диск ....................................................................................................................................... 9 5. Драйвер шины КАМАК .............................................................................................................. 10 5.1. API уровня ядра .................................................................................................................... 10 5.2. API прикладного уровня ...................................................................................................... 12 6. Средства разработки приложений ............................................................................................. 15 6.1. Платформа LINUX................................................................................................................ 15 6.2. Платформа Windows............................................................................................................. 15 8. Средства отладки приложений............................................................................................... 16 1. Ядро 1.1. Особенности архитектурной реализации Для контроллера КАМАК использовано ядро ОС Linux версии 2.0.38, адаптированное для микропроцессора MC5307. Так как процессор не имеет менеджера виртуальной памяти, для него применена специальная версия Linux, использующая так называемую Flat Model памяти. С точки зрения программиста имеются следующие отличия от “стандартной” версии Linux: • Формат исполняемого файла • Вместо вызова fork() необходимо использовать vfork(). Процесс-родитель при этом блокируется до тех пор, пока дочерний процесс не выполнит exec() или exit() • Изменен смысл вызова brk(). • Особенности механизма защиты памяти • Особенности управления памятью Ядро содержит в своем составе следующие программные компоненты, специфичные для данного процессора: • Код инициализации • Поддержка таймера MC5307 • Драйвер последовательного порта MC5307 • Драйвер Ethernet контроллера MX98726 • Драйвер флэш-диска • Управление контроллером памяти MMU Кроме того, в виде загружаемого модуля разработан драйвер шины КАМАК, позволяющий работать с шиной как прикладному программному обеспечению, так и другим модулям. 1.2. Особенности управления памятью. Память для пользовательских процессов выделяется блоками с размером, кратным 128 kb. Каждый прикладной процесс занимает монолитный блок памяти. Память процессу выделяется на этапе загрузки исполняемого файла и далее не может быть увеличена либо уменьшена. В отличие от стандартной версии linux, где выделение памяти процессу возможно на этапе исполнения (с помощью системного вызова mmap), во flat-linux память выделяется в пользовательском пространстве из пула фиксированного размера. Выделением памяти занимается не ядро, а библиотека приложения, реализующая программный интерфейс к куче. Память прикладного процесса Code segment Data segment Bss segment Heap 1.3. Формат исполняемого файла Исполняемые файлы программ имеют специальный flat-формат. Файлы данного формата получаются из elf файлов, выдаваемых компилятором, с помощью конверсии утилитой elf2flt. Основная особенность данного формата в том, что заголовок flat файла содержит поля размеров стека и кучи, необходимых для работы приложения. Размер стека указывается при конверсии в командной строке утилиты elf2flt. Размер кучи может задаваться с помощью утилиты heapsize. Так как память в системе выдается блоками по 128 kb, реальный размер кучи может быть больше указанного утилитой heapsize. 1.4. Системный вызов fork Прикладной процесс, который сделал системный вызов fork, порождает еще одну нить исполнения. При этом сам процесс блокируется до тех пор, пока дочерний процесс не завершится или не выполнит системный вызов exec. Два получившихся процесса существуют на одном адресном пространстве (т.е. имеют общие сегменты кода, данных и bss), но имеют разный стек и контекст исполнения. Отдельное адресное пространство процесс получает только после вызова exec. 1.5. Системный вызов brk Системный вызов brk с аргументом 0 возвращает физический адрес начала кучи, с аргументом 1 возвращает физический адрес конца кучи. 1.6. Особенности механизма защиты памяти Механизм защиты памяти обеспечивает: 1. Защиту кода и данных ядра от прикладных процессов 2. Защиту кода и данных прикладных процессов друг от друга Для реализации защиты памяти использовано свойство процессора находиться в двух режимах – супервизора и пользователя. В режиме супервизора процессор может обрабатывать прерывания, производить операции со статусным регистром (разрешать/запрещать прерывания). В режим супервизора процессор автоматически переходит при обработке прерывания или системного вызова. Режиму супервизора соответствует исполнение кода ядра. Режиму пользователя соответствует исполнение прикладного процесса. Мониторинг состояния процессора и текущего исполняемого адреса в памяти осуществляет аппаратное устройство – контроллер MMU. Если процессор находится в режиме супервизора, ему разрешается доступ по любому адресу. Если процессор находится в режиме пользователя, доступ разрешен в пределах, заданных регистрами EDGE_LOW и EDGE_HIGH (см. описание аппаратной части). Если процесс обращается к неразрешенной области памяти, контроллер MMU блокирует этот доступ и вырабатывает прерывание с наивысшим приоритетом (7). Обработчик прерывания от MMU, который находится в ядре linux, при получении прерывания завершает процесс, вызвавший прерывание, сигналом SIGSEGV. 1.7. Командная строка. В командной строке ядру сообщается устройство, на котором содержится корневая файловая система, а также консольное устройство, через которое будут выводиться сообщения уровня ядра (printk функция). Командная строка состоит из: • Обязательного префикса Arg! • Строки с указанием устройства с корневой файловой системой: root=/dev/vfdisk [rw] Необязательный параметр rw указывает, что разрешена запись на диск • Строки с указанием консольного устройства: CONSOLE=/dev/ttyS0 Если консоль не указана, вывод сообщений ядра будет осуществляться только в буфер памяти ядра, содержимое которого можно посмотреть в файле /proc/kmsg. Пример командной строки: Arg!root=/dev/vfdisk rw CONSOLE=/dev/ttyS0 1.8. Модули Для использования аппаратных возможностей процессора при разработке модуля необходимо подключить к исходному тексту файл-заголовок, определяющий регистры: #include <asm/m5307.h> Базовому адресу окна регистров соответствует символ imm, экспортируемый ядром. Для управления модулями используются стандартные утилиты insmod, rmmod, ksyms. Файл /proc/ksyms содержит список символов, экспортируемых ядром. 2. Корневая файловая система Устройство /dev/vfdisk представляет собой блочное устройство ввода-вывода, на верхнем уровне отформатированное как стандартная файловая система ext2. Структура устройства показана на рисунке. Flash Translation Level (FTL) software Block device М/сх Flash памяти 8192 сектора * 512 байт hardware SPI контроллер Между функциями обращения к аппаратному устройству и блочным устройством Linux существует программная прослойка – FTL, которая осуществляет равномерный по количеству обращений доступ к секторам флэш-диска. Наличие уровня FTL приводит к необходимости осуществлять дополнительно низкоуровневое форматирование диска. Процесс подготовки диска к работе происходит следующим образом – низкоуровневое форматирование утилитой vfdisk, затем форматирование ext2 стандартной утилитой mke2fs. Для проверки целостности файловой системы ext2 может использоваться утилита e2fsck. В силу специфических условий эксплуатации рекомендуется в рабочем режиме подключать устройство /dev/vfdisk только для чтения, используя его для записи при необходимости конфигурации программного обеспечения. Файловая система диска содержит утилиты: /bin/ae текстовый редактор /bin/cat вывод файла на консоль /bin/chmod изменение атрибутов файла /bin/cp копирование файлов /bin/date вывод даты и времени /bin/e2fsck проверка файловой системы /bin/echo вывод сообщения на консоль /bin/kill посылка сигнала процессу /bin/ln установка символического линка /bin/login проверка имени пользователя и пароля /bin/ls вывод содержимого директории /bin/mkdir создание директории /bin/mke2fs создание файловой системы /bin/mknod создание файла устройства /bin/more вывод файла на консоль, постранично /bin/mount подключение файловой системы /bin/mv /bin/passwd /bin/printenv /bin/ps /bin/reboot /bin/rm /bin/rmdir /bin/sh /bin/sync /bin/umount /bin/vfdisk перемещение файлов изменение пароля вывод окружения на консоль вывод информации о процессе перезапуск ОС удаление файла удаление директории оболочка shell сброс содержимого буферов на диск отключение файловой системы утилита форматирования низкого уровня /sbin/dhcpcd /sbin/gdbserver /sbin/ifconfig /sbin/insmod /sbin/ksyms /sbin/lsmod /sbin/ping /sbin/rmmod /sbin/route /sbin/smbmout /sbin/smbumount /sbin/telnetd клиент протокола DHCP сервер пошаговой отладки утилита конфигурации сетевых устройств загрузить модуль вывод на консоль символов, экспортируемых модулями вывод на консоль список загруженных модулей ICMP эхо выгрузить модуль управление маршрутами подключить удаленную файловую систему Win отключить удаленную файловую систему Win сервер протокола telnet /lib/modules/camac.o модуль драйвера КАМАК шины 3. Файлы конфигурации Процесс загрузки операционной системы выглядит следующим образом: 1. После сброса резидентный ROM монитор получает управление и открывает файловую систему флэш-диска. 2. Образ ядра копируется монитором из флэш диска в оперативную память контроллера 3. Управление передается ядру Linux 4. Ядро проводит инициализацию и монтирует корневую файловую систему 5. Ядро запускает первый прикладной процесс /etc/init 6. Процесс init запускает shell (/bin/sh), которому в качестве параметра передается командный файл /etc/start. 7. В файле /etc/start может быть вызваны на исполнение другие командные файлы /etc/rc/rc0, /etc/rc/rc1 и т.д. Таким образом, при старте системы используются конфигурационные файлы: /etc/start – первым получает управление /etc/rc0 – настройка сетевых параметров до получения IP адреса по DHCP /etc/rc1 – настройка сетевых параметров после получения IP адреса Другие конфигурационные файлы: /etc/issue.net – вид приглашения при подключении по протоколу telnet /etc/rc/ae.rc – конфигурационный файл редактора ae /etc/rc/fstab – список монтируемых файловых систем /etc/rc/passwd – имена пользователей и пароли /etc/rc/resolv.conf – конфигурация DNS 4. RAM-диск По умолчанию, система подключает RAM диск на устройстве /dev/ram0. Диск монтируется к директории /var. Пользователь может подключать свои диски, используя устройства /dev/ram1, /dev/ram2 и т.д. Например: mke2fs -q /dev/ram1 mount -t ext2 /dev/ram1 /mnt 5. Драйвер шины КАМАК Драйвер шины КАМАК разработан в виде модуля и обеспечивает программный интерфейс для доступа к шине КАМАК как на уровне прикладных процессов, так и на уровне ядра. Для прикладных процессов интерфейс к шине представляет собой символьное устройство вводавывода. Для модулей, работающих с КАМАК шиной, разработан API. Архитектура драйвера показана на рисунке. Прикладная задача /dev/camac API модулей Char-устройство Функции ввода-вывода Kernel Level контроллер Hardware level КАМАК шина 5.1. API уровня ядра КАМАК модуль экспортирует функции: int cam_bus_read (char *buf, int len); int cam_bus_write (const char *buf, int len); void cam_execute_C (void); void cam_execute_Z (void); int cam_get_I(void); void cam_set_I(int i); int cam_bus_lamenable(int lam, LAMHANDLER handler); int cam_bus_lamdisable(int lam); int cam_bus_lampending(void); Операции чтения/записи Для чтения или записи на шину используются функции: int cam_bus_read (char *buf, int len); int cam_bus_write (const char *buf, int len); Первый параметр, buf, представляет собой указатель на заголовок вида: typdef struct { unsigned short n; unsigned short a; unsigned short f; unsigned short status; unsigned *buf; } cam_header_t; Через этот заголовок пользователь сообщает драйверу: n – номер блока КАМАК, от 0 до 23 a – адрес, от 0 до 15 f – функция, от 0 до 31 buf – указатель на буфер с данными После завершения цикла драйвер в поле status заголовка сообщает результат Q блока (бит 0) X блока (бит 1) Второй параметр, len, содержит количество операций чтения/записи, <=256 Буфер, который указывается в заголовке, представляет собой массив 32-разрядных слов (int или unsigned), длиной не менее len. Возвращаемое значение – количество выполненных циклов чтения/записи (равно len). Выполнение циклов C и Z Вызов функций void cam_execute_C(void) void cam_execute_Z(void) приводит к появлению на шине циклов C и Z Управление сигналом Inhibit int cam_get_I(void) – возвращает состояние сигнала I на шине void cam_set_I(int i) – устанавливает сигнал I на шине Управление LAM запросами int cam_bus_lamenable(int lam, LAMHANDLER handler); Функция устанавливает обработчик LAM запроса и размаскирует запрос. Первый параметр – номер lam запроса, от 0 до 23 Второй параметр - указатель на функцию – обработчик запроса: typedef void (*LAMHANDLER) (int); Обработчик запроса получает от драйвера КАМАК в качестве параметра номер LAM запроса, от 0 до 23. Таким образом, один обработчик может быть использован для нескольких запросов. Возвращаемое значение : 0 в случае успеха, -1 если LAM уже занят обработчиком прикладного уровня. int cam_bus_lamdisable(int lam) Маскирует LAM запрос. Возвращаемое значение: 0 в случае успеха, -1 если LAM занят обработчиком прикладного уровня. int cam_bus_lampending(void); Функция возвращает маску LAM запросов, активных в настоящий момент. Возвращаемое значение не зависит от установленной маски разрешения/запрета и отображает текущее состояние на шине. Примечания. 1. После однократной обработки запроса, LAM маскируется драйвером, поэтому функция cam_bus_lamenable должна вызываться вновь для каждого запроса. 2. Обработчик LAM запроса исполняется на закрытых аппаратных прерываниях, поэтому функция должна возвращать управление как можно быстрее. 5.2. API прикладного уровня Прикладные процессы могут обращаться к шине КАМАК через символьный драйвер /dev/camac. Число процессов, одновременно совершающих операции ввода-вывода не ограничено. Появление активного LAM запроса приводит к посылке сигнала SIGUSR1, если процесс предварительно разрешил обработку данного LAM. Перед началом работы с шиной процесс открывает специальный файл: fd = open(“/dev/camac”, O_RDWR) Работа с шиной должна завершаться закрытием специального файла: close(fd) Операции чтения/записи int read(int fd, char *buf, int len) int write(int fd, char *buf, int len) Где Первый параметр – файловый дескриптор. Второй параметр – указатель на заголовок cam_header_t (см. предыдущий пункт) Третий параметр – число операций чтения/записи, <= 256 Возвращаемое значение – число операций чтения/записи Выполнение циклов C и Z ioctl вызовы: ioctl(fd, CAM_IOCTL_EXC, 0) ioctl(fd, CAM_IOCTL_EXZ, 0) приводят к появлению на шине C и Z циклов соответственно. Первый параметр – файловый дескриптор. Второй параметр – код операции (константа, определенная в файле camac.h) Третий параметр игнорируется. Возвращаемое значение – 0. Управление сигналом Inhibit Для чтения сигнала I на шине КАМАК выполняется ioctl вызов: unsigned x; … ioctl(fd, CAM_IOCTL_GETI, &x); Первый параметр – файловый дескриптор. Второй параметр – код операции Третий параметр – указатель на unsigned Возвращаемое значение – ioctl вызов возвращает 0, состояние сигнала Inhibit находится в переменной x. Для установки сигнала I выполняется ioctl вызов: unsigned x; … ioctl(fd, CAM_IOCTL_SETI, &x); Первый параметр – файловый дескриптор. Второй параметр – код операции Третий параметр – указатель на unsigned Возвращаемое значение – ioctl вызов возвращает 0 Сигнал Inhibit будет установлен в соответствии с содержимым переменной x. Управление LAM запросами unsigned x; … ioctl(fd, CAM_IOCTL_LAMENABLE, &x); Данный вызов “приписывает” указанный LAM процессу и размаскирует его. В случае активизации данного LAM запроса, процесс получит сигнал SIGUSR1. Первый параметр – файловый дескриптор. Второй параметр – код операции Третий параметр – указатель на unsigned Возвращаемое значение – ioctl вызов возвращает 0 в случае успешного выполнения и -1 если LAM занят другим процессом или модулем. Переменная x содержит номер LAM запроса 0..23 unsigned x; … ioctl(fd, CAM_IOCTL_LAMDISABLE, &x); Данный вызов маскирует LAM запрос и освобождает его для захвата другими процессами. Первый параметр – файловый дескриптор. Второй параметр – код операции Третий параметр – указатель на unsigned Возвращаемое значение – ioctl вызов возвращает 0 в случае успешного выполнения и -1 если LAM занят другим процессом или модулем. Переменная x содержит номер LAM запроса 0..23 unsigned x; … ioctl(fd, CAM_IOCTL_LAMPENDING, &x); Вызов возвращает маску LAM запросов, активных в настоящий момент. Возвращаемое значение не зависит от установленной маски разрешения/запрета и отображает текущее состояние на шине. Первый параметр – файловый дескриптор. Второй параметр – код операции Третий параметр – указатель на unsigned Возвращаемое значение – ioctl вызов возвращает 0, маска находится в переменной x. 6. Средства разработки приложений Средства разработки приложений для контроллера CM5307 являются кросс-средствами. Исполняемых платформ возможно две – Windows и Linux. 6.1. Платформа LINUX По умолчанию корневой директорией для программного обеспечения является /usr/cm5307. Путь к корневой директории используется в make файлах и должен экспортироваться как переменная окружения: export CM5307_BASE=/usr/cm5307 В корневой директории находятся файлы: linux68k/work/makeconfig - определения путей к библиотекам и h-файлам, флагов компилятора и т.д. Этот файл должен подключаться директивой include в пользовательских make-файлах. linux68k/work/user.ld – скрипт-файл компоновщика, используемый для определения адресного пространства прикладного процесса. linux68k/include-* – h файлы, используемые при компиляции linux68k/lib/ctr0.o – объектный файл, содержащий код, который получает управление при старте процесса. linux68k/lib/libc.a – C библиотека linux68k/lib/libmf.a – математическая библиотека (с соответствующим файлом include/mathf.h) linux68k/tools – директория с исполняемыми файлами кросс-компилятора linux68k/work – директория с примерами прикладных программ linux68k/work/test_cam – тест работы КАМАК. Программа работает на прикладном уровне и обращается к шине через драйвер. В качестве тестового устройства используется блок АЦПИ-20. linux68k/work/test_fp – программа, демонстрирующая работу с плавающей арифметикой. linux68k/work/test_net – программа, демонстрирующая работу с TCP/IP. linux68k/work/modules/cam_test – пример разработки модуля для обращения к КАМАК-шине. Модуль работает с блоком АЦПИ-20. 6.2. Платформа Windows По умолчанию корневой директорией является //d/work/cm5307. Путь к корневой директории используется в make файлах и должен экспортироваться как переменная окружения: SET CM5307_BASE=/cygdrive/d/work/cm5307 Также, должен быть установлен путь к исполняемым файлам: path=d:\work\cm5307\linux68k\tools;%path% Файловая структура средств разработки выглядит так же, как для платформы Linux (предыдущий пункт). 8. Средства отладки приложений Для отладки приложений могут использоваться средства удаленной отладки через сеть TCP/IP. В качестве отладчика используется запускаемый на платформе разработки gdb. На целевом контроллере запускается отладочный сервер и отлаживаемая программа (см. рис). Имя приложения, используемого в качестве примера - test. TCP/IP host CM5307 gdb gdbserver ptrace Symbol table test.gdb test Первое, что необходимо сделать для отладки приложения test – запустить gdbserver и указать ему в качестве отлаживаемого приложения исполняемый файл test. После этого gdbserver загрузит приложение в память контроллера и остановит его. Управление исполнением приложения, а также контроль содержимого регистров и памяти будет осуществляться через механизм ptrace. Далее gdbserver будет ожидать соединения от gdb отладчика и перейдет в режим исполнения удаленных команд. В отладчик gdb при старте должна быть загружена таблица символов, содержащаяся в объектном файле test.gdb, после чего необходимо установить соединение с удаленным контроллером. После этих процедур отладчик готов к пошаговому выполнению приложения. Для отладки приложения test средствами разработки должны быть получены следующие файлы: test.gdb – файл с таблицей символов и отладочной информацией. Используется для загрузки в отладчик gdb. test – исполняемый файл. Запускается на целевом контроллере. Для получения файлов с отладочной информацией (*.gdb) необходимо выполнить следующее: • Компилировать исходные тексты с дополнительным ключом –g. • Компоновать файлы без ключа –r. В качестве примера отладки приложения см. $(CM5307_BASE)/work/test_gdb/. Для пошаговой отладки этого приложения необходимо выполнить следующие команды. На целевом контроллере # gdbserver host:4000 test [args] Данная команда запустит приложение test и будет ожидать соединения по UDP сокету 4000. Имя удаленного компьютера host игнорируется и может быть любым. Необязательный список параметров [args] передается отлаживаемой программе. На компьютере разработки # gdb GNU gdb 4.18 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. (gdb) file test.gdb Reading symbols from test.gdb...done. (gdb) target remote 192.168.1.2:4000 Выделенные курсивом команды вводит пользователь. Здесь команда file указывает отладчику, из какого файла необходимо считывать отладочную информацию. Команда target указывает IP адрес целевого контроллера, номер UDP сокета и инициирует соединение.