|
Выбор ОССобственно, на самом деле выбор этот для меня был очень прост. Начнем от простейшего варианта: систему можно написать самому. Задача, стоящая перед аппаратно- програмным комплексом не сильно сложная, процессор мощный (Да, мощный ! ~166*10^6 тактов в секунду. Тетрис просто летает), памяти много (а вы пробовали писать программы на ассемблере ? Сколько времени вы будете писать осмысленный код, который займет хотя бы половину имеющейся в наличии памяти - 16 Мб ?), аппаратура почти вся хорошо и на много раз документирована. Здесь есть две проблемы: 1) документировано все таки не все. Например, звук у меня был на чипе Vortex. К нему доки закрыты. 2) пожалуй, код для декодирования mp3 я напишу, но осваивать для этого доки или чужие исходники - это очень тонкое развлечение. Попытаться адаптировать тот же исходник mpg321 к собственной системе.... В общем: как нибудь в другой раз. Чуть усложним: ms-dos (ну и прочие: ps-dos, dr-dos, .... freedos ... кто больше ?). Да, под нее есть даже готовые dosamp, mp3-486 - но это продукты без исходных кодов и не склонные к взаимодействию с другими программами - у них только обычный экранный интерфейс. А нам нужна координация, управление с ИК и прочие вкусности. Да и проги эти излишнией универсальностью и корректностью не страдают - не все субформаты mp3 им понятны, не со всеми звуковухами они дружат. QNX. Ну до кучи приплетем сюда Minuet, v2os, ... э-э-э... где у меня компашка с музеем операционок - я без нее и всех названий -то не упомню. Вот, например, была там *NIX-подобная операционка, но с форматом исполняемых файлов - ms-dos-exe. Да, под ней даже Volcov Commander пытался работать. С переключением виртуальных консолей по Alt-F :). В общем, наверное, среди таких ОС можно найти подходящую, но вот нет по ним соответствующего обзора. Винда. Под ней подобную конструкцию делали - я встречал упоминание в инете, но без подробностей (winamp + плагины). Но у меня к ней личная неприязнь. Потому что если большинство описаний к другим ОС можно в среднем озаглавить словом "Почему (как устроено) ?", то документация к винде будет начинаться со слова "Как (добиться конкретного результата) ?". Причем темы "Как сделать из винды безмониторный "MP3-плейер"" там не наблюдается, впрочем как и 95% других, интересующих меня тем. FreeBSD, ну пусть заодно и другие *BSD. Эту систему я использую как десктоп, но вот ранее упомянутый Vortex она не поддерживает. Возможно, помогла бы установка драйверов от 4Front Technologies (по крайней мере именно так я заставил под FreeBSD 4.11 работать Audigy 2), но ... ... есть ведь еще Linux. Т.е. та куча систем, которая использует ядро (ну и всю кучу сопутствутющих драйверов, а заодно и прикладной софт) от компании Линус Торвальдс & единомышленники. Я давно хотел с ней поиграться, но просто поставить и ... что дальше ? Фря работает, все что надо делает. Ну появится еще одна система... Придётся выбирать с чем работать после каждого включения машины :). А тут повод. И Vortex поддерживается. Почему Zenwalk ? Потому что это ветка широко известной в узких кругах Slackware - версии/дистрибутива Linux, предназначенной для тех, кто еще не докурился до нирваны сборки Linux From Scratch (т.е. буквально - сборки дистрибутива по... ну почти по отдельным файлам), но в то же время считает любые подсказки и помощь от системы и ее инсталятора излишними. Чем, разумеется, экономит дисковое пространство, время... ну и, конечно, наслажается красотой технической простоты. Примерно как математик, сокращающий длинное уравнение. Конечно, не последнюю роль в выборе сыграло включение Zenwalk в один из недавно пришедших DVD к журналу LinuxFormat. Thank's. Ядро системы я пересобирал сам, хотя это, в зависимости от мощности машины, может быть необязательно. Список установленных пакетов:
aaa_base-10.1.0-noarch-2 aaa_elflibs-10.1.0-i486-1 alsa-lib-1.0.9-i486-1 alsa-utils-1.0.9a-i486-2 audiofile-0.2.6-i486-1 bash-3.0-i486-2 bin-9.2.0-i486-2 binutils-2.15.92.0.2-i486-3 bzip2-1.0.3-i486-1 ccache-2.4-i486-1 coreutils-5.2.1-i486-1 cxxlibs-5.0.6-i486-1 devs-2.3.1-noarch-22 diffutils-2.8.1-i386-1 e2fsprogs-1.38-i486-2 esound-0.2.36-i486-1m7 etc-5.1-noarch-2m7 findutils-4.1.7-i386-1 gawk-3.1.4-i486-1 gcc-3.3.6-i486-1 gcc-g++-3.3.6-i486-1 gdb-6.3-i486-1 glibc-2.3.5-i486-4 glibc-solibs-2.3.5-i486-4 gmp-4.1.4-i486-2 grep-2.5-i386-2 groff-1.19.1-i486-1 gzip-1.3.3-i386-2 hdparm-6.1-i486-1 kbd-1.12-i486-1m7 kernel-2.6.12.2-i486-2m7 kernel-headers-2.4.31-i386-1 less-382-i486-1 libao-0.8.6-i486-1 libid3tag-0.15.1b-i486-1 libmad-0.15.1b-i486-1 libogg-1.1.2-i486-1 libtool-1.5.14-i486-1 libvorbis-1.1.0-i486-1 lilo-22.7-i486-1m7 man-1.5p-i486-1 man-pages-1.64-noarch-1 mc-4.6.0-i486-msam mpg321-0.2.10-i486-2 ncurses-5.4-i486-2 openssh-4.1p1-i486-1 openssl-solibs-0.9.7g-i486-1 pkgconfig-0.15.0-i486-1 pkgtools-10.2.0-i486-4m7 procps-3.2.3-i486-1 proftpd-1.2.10-i486-1z21 sed-4.0.9-i486-2 shadow-4.0.3-i486-1m7 sysvinit-2.84-i486-56m7 tar-1.15.1-i486-1m7 tcpip-0.17-i486-34m7 util-linux-2.12p-i486-1 Файловые системыСразу объясню фишку на первой странице про два винта: системный и винт с данными. Причина примитивна: инженеры и программисты BIOS'a имевшейся в наличии материнки по указанию сверху вдруг перестали предполагать о грядущем появлении винтов более чем 32 Гб объёма. Т.е. при подключении, например, 40 Гб винта и объявлению его наличия в BIOS setup, BIOS при загрузке просто зависал. Если же наличие не объявлять - винт не сможет быть загрузочным. Поэтому пришлось использовать два винта: с одного стартует ОС (ядро Linux не использует BIOS для работы с винтами, оно находит их само и в дальнейшем общается без посторонней помощи), на другом лежат данные. Как верно сообщают с мест, BIOS можно и перешить. Если есть исправленный вариант. Первый винт объёмом 200 Мб. Да, такого объема винты тоже были. Были и еще меньше. 5 Мб, например. Но у меня была только двухсотка. Битых блоков нет, работает безотказно, греться умеет плохо, один недостаток - шумит. Поэтому пришлось сделать так, чтобы после загрузки он отключался. На нем стоит Zenwalk.... и больше ничего. Единственный раздел с файловой системой ext2. Она не сильно надежная (в смысле - не журналируемая), но позже поясню, почему это не важно. Второй винт - 40 Гб, ноутбучный. AAM у него настроен на максимум (Automatic Acoustic Management Tool, я использовал утилиту от Mishail Mavritsin (2:5020/3637.55@fidonet), есть также, например, Victoria), т.е. производительность в жертву тишины. Впрочем он и так шустрый. Греться не умеет, слышно его в работе только если приложить ухо; т.к. используется в качестве флешки, одет в защитный жестяной корпус со всех сторон. Имеется несколько разделов: 1) hda1 или ad0s1 - FreeBSD. Флешка должна быть загружаемой. Заодно это и бекап домашней системы. Для плейера роли не играет, но т.к. сдвигает номера других разделов, здесь упомянуто. Объём - ~2 Гб, тип 165. 2) hda2 или ad0s2 - ext2. Объём - ~7 Мб, тип 131. Этот раздел каждый раз при загрузке плейера переформатируется и затем используется как /tmp. 3) hda3 или ad0s3 - расширенный раздел в терминологии MS, содержит в себе hda5 или ad0s5 - FAT32 с музыкой или еще чем нибудь. Пользовательские данные, в общем. Этот раздел намеренно создан как extended ("логический диск"), т.к. в этом случае win9x ставит его после букв других дисков (при использовании винта на чужих машинах). В плейере он монтируется как /Data и одновременно является домашним каталогом непривелегированного пользователя deka. Объём - ~36 Гб, тип 15. /etc/rc.d/Разобравшись с винтами и осями, кратко пробежим по процессу загрузки linux и обозначим важные для плейера действия, а от прочих избавимся. Итак: после включения машины процессор начинает выпонять код из ROM, который называется BIOS материнской платы. BIOS тестирует процессор, память и прочие компоненты материнской платы, а заодно пытается разыскать другие BIOSы, находящиеся на картах расширения. Для видеокарты это будет видео-BIOS, для сетевой - менеджер удаленной загрузки и т.д. После всех этих действий, если все опрошенные BIOSы вернули управление (т.е. например, не началась удаленная загрузка) BIOS материнской платы начинает изучать нулевые сектора накопителей, которые указаны в BIOS SETUP как загрузочные. Например, нулевой сектор НЖМД. Если там обнаруживается характерная сигнатура, содержимое сектора падает на адрес 0:7C00 и на него передается управление. Этот сектор содержит таблицу разделов винта и начальный загрузчик. Все это вместе в терминологии IBM называется Master Boot Record (MBR). Начальный загрузчик переносит сам себя куда нибудь подальше от адресов 0:7C00, изучает таблицу разделов, находит раздел, обозначенный как загрузочный, вычитывает с него нулевой сектор (это не нулевой сектор винчестера, а нулевой сектор относительно начала раздела !) опять же в адрес 0:7C00 и, проверив сигнатуру, передает управление туда. До этого места последовательность загрузки одинакова для всех ОС. Дальше все зависит от операционки. Если речь идет о линуксе, то еще и от загрузчика, который окажется в нулевом секторе раздела. Я использовал lilo. Он действует очень просто: дочитывает кусок себя, затем находит ядро системы и считывает его в память. Ядро изучает аппаратуру (3-7 секунд), затем монтирует корневую файловую систему (какую именно - ему подсказывает lilo), затем запускает процесс /sbin/init. Теперь внимательнее. Всё, что было до этого регулированию поддается мало, да и смысла что либо менять нет. Ну можно разрешить быстрый тест памяти в BIOS (если BIOS SETUP это умеет), можно запретить "Floppy boot seek", а в качестве устройства загрузки указать "C only" - несколько секунд еще выиграете. А вот то, что делает /sbin/init настраивать можно и нужно. Во первых, на слабой машине это может ускорить запуск плейера, во вторых, машина будет отзывчивее при настройке и подстройке. Кстати, если вы внимательно читали предыдущий раздел, должны были обратить внимание, что я не стал использовать swap-раздел. Да, 32 Мб RAM системе вполне хватает. Если настроить хорошо. Т.е. просто выкинуть все лишнее. Дальше я могу слегка соврать, а могу соврать и сильно, т.к. тут больше моих предположений, чем чтения мануалов. У /sbin/init есть несколько очень важных задач. Одна из них - запуск и убийство разнообразных процессов. Запуск происходит при загрузке init и при смене т.н. уровня исполнения, убийство - перед сменой этого уровня. Т.е. пошла команда на смену уровня - опа, всё что можно было кроме себя убил, затем то, что указано в конфигурации - запустил. Конфигурация храниться в файле /etc/inittab. Читаем ее внимательно, ибо там много комментариев. Существует несколько уровней. 0 - остановка, 1 - однопользовательский режим, 2 - аналог 3, 3 - многопользовательский режим, 4 - режим с запущенным X-сервером, 5 - аналог 3, 6 - перезагрузка. /etc/inittab описывает, что (имена программ, аргументы) и как (ну, например: нужно ли заного запускать программу если она завершила работу) нужно запустить на очередном уровне исполнения. Сразу после загрузки init переходит в уровень si, при этом выполняется скрипт /etc/rc.d/rc.S. Затем уровень меняется на 1 и выполняется скрипт /etc/rc.d/rc.K, затем уровень 2 - /etc/rc.d/rc.M (кроме того он будет выполнен и на уровнях 3, 4, 5 если произойдет переход в них). Эти строчки в /etc/inittab мы трогать не будем, но запомним. Обратите внимание - initdefault установлен в 3 - т.е. после попадания в этот уровень автоматические переходы по уровням прекращаются. Теперь найдите строчку вроде c1:1235:respawn:/sbin/agetty 38400 tty1 linux. Она говорит о том, что на 1, 2, 3 и 5 уровнях следует запустить agetty. Эта программа после запуска системы захватывает виртуальные консоли (те, что переключаются комбинацией Alt-Fx) и запрашивает на них логин. В нормальной ситуации введенный пользователем логин передается программе login, которая, в свою очередь, запрашивает пароль пользователя и в случае верного ответа запускает shell пользователя с нужным уровнем привелегий (сама login исполняется еще с правами суперпользователя, но shell уже будет понижен в уровне, если, конечно, зашел не root). Но нам-то нужен плейер, поэтому запрос логина-пароля ни к чему. Мы пойдем другим путем: c1:1235:respawn:/sbin/agetty -n -l /sbin/mywrap 38400 tty1 linuxТеперь на первом виртуальном терминале agetty выполнит всю подготовительную работу, но не запросит логин, а просто передаст управление указанной нами программе, которая будет называться /sbin/mywrap. Это небольшой скрипт, к содержимому которого мы вернемся в следующих главах этого детектива. Обратите внимание: если этот скрипт погибнет, /sbin/init будет пытаться перезапустить его, пока не будет изменен уровень выполнения (т.е., например, пока система не уйдет в подготовку к перезагрузке). Теперь обратимся к директории /etc/rc.d/. Как вы помните, здесь лежат файлы инициализации системы, которые init последовательно выполняет перед тем, как запустить нашу программу. В этих скриптах перечислено много увлекательных действий, но нам нужно их предельно сократить и слегка подправить логику. Сократить - потому что скрипты делают попытки запустить разнообразные сервисы, вроде апача, mysql'я и прочего. Сервисы, естественно, не запускаются, просто потому что я их не ставил, но время на проверку этого факта уходит. Как и память. Это касается как процесса загрузки, так и подготовки к shut down'у. Подправить - потому что мы делаем плейер, а не рабочую станцию. А одим из требований было - возможность безболезнено выключить машину в любой момент. Вот тут начинается самое интересное. Что значит "в любой момент" ? Это значит, что ОС и программы не должны делать таких операций, неожиданное прерывание которых может привести к дальнейшим проблемам с машиной. Где может храниться информация о том, что какая-то операция не была завершена ? Только в памяти. Т.е. на винте. Т.е. в файловой системе. Т.е. мы должны запретить модификацию файловых систем. Если вы раньше работали только с Windows - крепко наморщите лоб. Юниксоидам понятно и так: нужно, чтобы ключевые файловые системы всегда работали в режиме "только чтение". Вот здесь я столкнулся с некоторыми проблемами. Попробую вспомнить все: Файлик /etc/mtab - очень любит перезаписываться командой mount. В т.ч. при работе скриптов инициализации. Эта проблема решается просто, хотя и не очевидно: убираем его, а вместо него делаем ссылку: ln -s /proc/mounts /etc/mtab. После этого командам mount и umount нужно запрещать модификацию /etc/mtab (есть для этого ключик -n). Файлик ld.so.cache создается при инициализации системы командой ldconfig. В нем описаны местоположения различных библиотек. Если вы изменяете что либо в конфигурации софта, нужно просто руками запустить ldconfig при разрешенной записи на /etc, а вот из скриптов инициализации ldconfig выкинуть. Даже если указать в /etc/fstab монтирование корневой файловой системы в Read Only, это указание, как ни странно, игнорируется. Поэтому в скриптах инициализации мы самым наглым образом добавим явное указание /sbin/mount -n -o remount,ro /. Вообще, запомните эту команду, она пригодится при отладке. Обратная ей команда /sbin/mount -n -o remount,rw / разрешает запись в файловую систему. proftpd и кое кто еще любит хранить файлы unix-сокетов где нибудь в районе /tmp. /tmp должна быть открыта для записи. Но если она будет открыта, не факт, что после выключения питания, в следующий раз система вообще сможет смонтировать этот раздел. С другой стороны - данные из этого раздела после выключения питания не нужны. Сделаем все быстро и просто: добавим перед mount /tmp изящное mkfs -q /dev/hdc2. Т.е. форматирование раздела при каждой загрузке. В отличие от винды, где то, что называется "форматирование", фактически является заодно и проверкой физики диска, в *nix'ах форматирование - это только запись в раздел пустого корневого каталога, пустой таблицы инодов и прочих системных областей. Поэтому mkfs на 7-и мегабайтном разделе займет доли секунды. Согласно ТЗ требуется, чтобы плейер мог сохранять номер или имя текущего трека, мог индексировать коллекцию (а индексы надо куда -то записывать, правда ?). Перебираем мозги и под слоем пыли вспоминаем, что вообще говоря, кнопки "закончить работу" в ms-dos не было, а на диски она писала. Просто ее нельзя было выключать не выйдя из програм, которые держали файлы открытыми, и внимательно относиться к индикатору HDD, а также к настройкам программ кеширования записи. Попробуем заставить линуксовое ядро симулировать стиль ms-dos в отношении раздела с данными: для этого строчка монтирования этого раздела будет выглядеть так: mount -tvfat -n -o noatime,sync,dirsync,uid=deka,gid=users,iocharset=koi8-r -v /dev/hdc5 /DataСкорость обмена с разделом, конечно, упадет... ну да ладно (deka - это логин непривелегированного пользователя, от имени которого выполняются некоторые операции. Надо бы его создать. users - его группа). Ну вот, сложные моменты объяснил, простые посмотрите в архиве, где приведены результирующие конфиги - tar /etc/*. Напрямую копировать в свою систему не рекомендую - несовпадение версий, аппаратуры, ... мало ли что вылезет ? Но как образец и отправная точка - в самый раз. |