QNX RTP Logo QNX Realtime Platform: Русский Портал QNX
Thursday, 20 Nov 2008 16:36
Меню

Проект OpenNET - все о Unix
Загрузочный образ: путеводитель Print E-mail
Akhilesh Mritunjai, перевод Владимир Чернышов

Предисловие

Когда QNX(R) Neutrino(R) RTP дебютировал, у многих волосы встали дыбом. Эта ОС оправдала все ожидания. Маленькая по объему, имеет возможность работы в широком диапазоне аппаратных средств, гибкая - в основном именно это захватило людей в самых различных странах. Эта ОС была фактически предназначена как специализированная настольная среда, продолжающая развитие встраиваемых систем. Все это захватило народное воображение, даже у начинающих, которые используют ее как высокоэффективный DeskTop на основе этой ОС. Однако много людей заметили, что QNX, вопреки другим операционным системам, предоставляет исключительную возможность того, что она может быть модулируема для разнообразных задач. Любой может создать образ системы, специально для конкретной задачи. Хотите запустить Web Server с дискеты? Никаких проблем! Ключом к этому является проектирование соответствующего образа и создания путеводителя - файла-строителя.

В этой статье, я предлагаю простой путеводитель, чтобы сформировать файл-строитель для различных приложений.

Предупрежедние

Я никоим образом не связан с QSSL. Информация, предоставленная мной - результат моего собственного усиленного изучения системы из различных источников. Я пробовал придерживаться точности выкладок насколько это возможно, но не утверждаю, что все сказанное здесь правильно. Информация, представленная здесь - это лучшее из моих знаний и исследований. Я не беру никакую ответственность за любой ущерб, нанесенный при помощи этой информации. Любой судебный иск, направленный против меня на основании информации, представленной здесь, не будет иметь силу.

Подтверждение

Я - пока еще студент и ученик. Изучая надлежащим образом эту ОС, я познакомился со множеством людей на телеконференциях и через электронную почту. Я многому научился от них. Я премного благодарен всем им, в особенности:

Chris McKillop, <cdm@qnx.com>
Mario Charest, <Mcharest@zinformatic.com>, http://www.zinformatic.com
Xiodan Tang, <xtang@qnx.com>
Приношу благодарности людям из qnxstart.com, в особенности:
Phearbear (aka. Johan)

Они всегда готовы идти на встречу людям и делиться опытом. Наконец я хотел бы благодарить людей, которые помогли при создании Abiword (www.abisource.com). Это позволило намного быстрее и проще создать этот путеводитель.

Читателям

Дорогие читатели, я хотел включить как можно больше подробностей, насколько это было возможно, в этом путеводителе. Хотелось бы услышать ваши предложения по улучшению данного путеводителя. Пожалуйста сообщите мне про все ошибки в этой статье и о темах, которые можно добавить. Я лично проверил большинство файлов-строителей, но они не везде могут работать и нуждаются в некоторых модификациях. В большинстве случаев, эти модификации - тривиальны (подобно выбору соответствующего драйвера). Я хотел бы включить и ваши файлы-строители, вышлите их мне.

В конце концов, держите всегда себя в руках - и все у вас будет хорошо!

И при плохой игре - улыбайтесь.

mritunjai
( Akhilesh mritunjai)
<Akhileshmritunjai@rediffmail.com>

Понимание файлов-строителей

С файлами-строителями лучше всего ассоциировать набор правил, согласно которым будет генерироваться образ системы. Файл-строитель структурирован следующим образом:

  • загрузочный сценарий
  • сценарий запуска
  • список файлов
  • Проанализируем каждую из этих частей поподробнее:

    Сценарий Начальной загрузки:

    Типы начальной загрузки центрального процессора бывают оформлены различными способами. Таким образом, для них существуют различные программы запуска. Эта часть описывает программу запуска, которая будет использоваться, включая любые специальные флажки, необходимые для правильных операций, например, отключающая команду HLT для некоторых дефектных Pentium-процессоров, резервируя некоторый определенный диапазон адресного пространства для любого специфического драйвера, который будет загружен позже и т.д. Посмотрим на типичный случай, который реализует сказанное выше:

    [virtual=x86,bios +compress] .bootstrap = { startup-bios -s 64k -D 8250.3f8.9600 -A -vv PATH=/proc/boot procnto }

    В этом примере, первая строка определяет, что это - файл начальной загрузки, атрибуты файла предшествуют имени файла. "virtual" определяет, что этот файл-строитель формирует загрузочный образ, соответствующий виртуальному адресному пространству, которое будет определено во время загрузки. "х86, bios" - ключевые слова, после которых определяется процессор (x86) и тип загрузки (загрузка через BIOS) соответственно. "+compress" - ключевое слово, определяющее, что образ должен быть сжат. Это обеспечивает меньший объем образа.

    Обратите внимание: Размер образа большую роль, особенно при загрузке с Disk On Chip. При загрузке с жесткого диска на x86 совместимых системах, образ должен быть меньше чем 632 кБ.

    Анализируя содержание файла начальной загрузки, мы увидим, что он сходен со сценарием загрузки и запускает две программы:

    Startup-bios: Эта программа отвечает за извлечения образа, размещение его в соответствующем адресном пространстве ОЗУ, загрузка первоначальной конфигурации и наконец загрузка ядра. В этом примере опция "-s 64k" сообщает о том, чтобы было скопировано в первые 64 кБ ОЗУ Video BIOS, для ускорения работы (этот процесс известен как "ROM BIOS shadowing". ROM - гораздо более медленно работает по сравнению с ОЗУ). Вторая опция сообщает программе открыть канал отладки на первом последовательном порте со скоростью 9600 бод. Таким образом вывод отладки может быть зафиксирован на другом компьютере, связанных через нуль-модемный кабель. Третья опция сообщает программе немедленно перезагружать систему после аварийного завершения работы ядра. Эта опция весьма типична в реальной жизни, когда контроллер компьютера должен работать без остановки. Наконец четвертая опция сообщают программе перейти в режим двойной защиты.

    procnto: это ядро QNX Neutrino (интегрированное с менеджером процессов). Оно предоставляет основные функциональные возможности создания процессов и потоков, передачи сообщений, управление памятью и т.д.

    На этом этапе, завершается процесс начальной загрузки и ядро теперь готово породить процессы, которые переведут систему в рабочий режим.

    Сценарий Запуска:

    Этот сценарий выполняется после того, как будет закончен процесс начальной загрузки. Все пользовательские программы находятся здесь. Давайте посмотрим на типичный сценарий:

    [+script].script={ # определяются глобальные системные переменные PATH=/proc/boot:/usr/bin:/bin LD_LIBRARY_PATH=/proc/boot:/usr/lib:/lib TERM=qansi # для удобства определим здесь переменные для сети IP="192.168.4.100" GATEWAY="192.168.4.1" # менеджер ресурсов заполняет структуру данных ядра определенными # системными значениями (диапазоны IRQ, DMA и т.д.) # если ваша система имеет PCI-интерфейс (как у большинства компьютеров # Pentium > 100MHz) тогда запускается, PCI сервер # если у вас другой тип компьютеров не используют его pci-bios & # ожидание, пока PCI-BIOS исследует систему waitfor /dev/pci # запуск NIC драйвера с полным стеком TCP/IP io-net -dtulip chipset=21041 -p tcpip #ожидание, пока не запустится io-net waitfor /dev/socket # конфигурирование NIC ifconfig en0 $IP netmask 255.255.255.0 route add default $GATEWAY # запуск консольного драйвера с двумя виртуальными консолями # доступ по нажатию ctrl+alt+1 и ctrl+alt+2 devc-con -n2 & # запуск оболчки на консолях reopen /dev/con1 [+session] uesh & reopen /dev/con2 [+session] uesh & }

    Вы, должно быть, заметили, что этот сценарий сходен со сценарием оболочки. Блок с атрибутом, в начале имени файла ".script", показывает, что он является сценарием выполнения.

    Этот сценарий записан с комментариями, так что содержание должно быть ясно. Однако, есть некоторые пункты, которые надо отметить. Вы не должны запускать PCI-сервер "pci-bios", если у вас в системе нет шины PCI, но если у вас есть шина PCI и у вас есть некоторая плата (например, NIC), которую вы хотите использовать, вы должны запустить его. Для использования драйвера NIC, его необходимо определить, используя "nettrap". Если же у вас мало места, вы можете заменить полный стек TCP/IP малым (tiny). Это выгодно не только потому, что вы получаете дополнительное свободное место, поскольку размер "ttcpip.so" составляет 40% от "tcpip.so", но и потому что вам не нужен будет "ifconfig" и "route". В общем 90 кБ против 250 кБ, хотя ценой TCP/IP выдается сообщение типа "SO_KEEPALIVE", но большинство приложений работает без помех. Командная строка в таком случае переписывается (однопользовательская машина):

    io-net -dtulip chipset=21041 -p ttcpip \ if=en0:192.168.4.100:255.255.255.0 \ default=192.168.4.1

    Вы могли бы обратить внимание, что этот сценарий от души сыпет "waitfor" инструкциями. Большинство команд в Neutrino не блокируемые по своей природе. Это одновременно хорошо и плохо. Хорошо, потому что вы можете запустить параллельный процесс и воспользоваться преимуществом многопоточной обработки, если оба процесса взаимно независимы. Но это предполагает проблему, где запуск процесса зависит от работы предыдущего. Подобно вышеприведенному случаю, моя плата NIC - PCI одна и io-net не может запустить и выполнить ее драйвер, если PCI-сервер не загружен, подобный случай - с "ifconfig" и "route", которые не можгут работать, если "io-net" не завершился, конфигурируя NIC. Чтобы обойти эту ситуацию, мы должны ждать, пока узел того устройства-драйвера не определится, который сообщит, что устройство-драйвер загружено и выполняется.

    Третья и последняя часть - та, которая сообщает, какие файлы являются необходимыми при запуске.

    Список файлов:

    Теперь идет список файлов, которые приведут к созданию этого материала. Выборка, которая идет с вышеупомянутыми двумя частями:

    libc.so.1 /lib/dll/devn-tulip.so /lib/dll/npm-tcpip.so libsocket.so.1 /etc/termcap=/etc/termcap /etc/hosts=/etc/hosts [type=link] /usr/lib/ldqnx.so.1=/proc/boot/libc.so.1 [type=link] /usr/lib/libc.so.1=/proc/boot/libc.so.1 [type=link] /usr/lib/libsocket.so.1=/proc/boot/libsocket.so.1 [data=copy] [perms=+r,+x] /sbin/io-net /usr/bin/ifconfig /usr/bin/route /usr/bin/telnet /usr/bin/ftp devc-con uesh pci-bios

    Начальные строки определяют общедоступные библиотеки. Первый "libc.so" почти всегда требуется, так как большинство приложений C - динамические, в отличие от "libc.so". Другие библиотеки содержат драйвер NIC, TCP/IP стек и BSD разъем для работы с сетями. Указанные файлы заканчиваются в /proc/boot на целевой системе после загрузки. А что же делать, если мы хотим разместить наши файлы в каком-то определенном местоположении? Сразу после этого есть пример, где мы явно определяем местоположение файлов. Обратите внимание, что директивное структура создается автоматически, так что вам не прийдется волноваться об этом. Но даже это не решает обычную проблему с общедоступными библиотеками. Фактически, некоторые программы ожидают библиотеки по одному пути, в то время как другие могли бы ожидать их где-нибудь еще. Плохо, что много приложений ожидают специфическую версию файла, к которому привязываются в определенном месте в то время как другие в другом. Создание копий файла будет тратой свободного места. Преодоление этой символической поддержки связи решено. Таким образом мы можем создавать символические связи к специфическому файлу многими способами, как может делать приложение. После этого существует секция, отмеченная атрибутами "[data=copy]", которая определяет, что следующая секция имеет двойственные выполняемые программы то есть те файлы, которые могут совместно использовать их долю кода, но не их сегменты данных. Эта секция также отмечена в соответствии с разрешениями, данными файлам "[perms=+r,+x]", которая устанавливает атрибуты чтения и выполнения. Файлы определяются после этого.

    Проповедую людям! Теперь надо показать все это. Давайте всю информацию, которую мы получили в теории переведем на практику. Я приведу примеры файлов строителей, необходимых для типичных приложений с полным описанием их создания, формирования и реализации.

    Использование файлов-строителей

    Вопрос: Итак, у меня есть файл-строитель, что теперь?
    Ответ: Если у вас есть файл-строитель, вам остается только создать образ файловой системы используя утилиту "mkifs". Выглядит это примерно так:
    mkifs -v my.build my.ifs

    Она берет файл-строитель с именем "my.build" и создает загрузочный модуль "my.ifs".

    Вопрос: Хорошо! Я получил "my.ifs", что дальше?
    Ответ: Ничего себе! Вы получили его. Сходите на перерыв, вы работали над этим глупым материалом слишком долго... поправлюсь, не вы, а я ;)

    Хм... Давайте вернемся к работе. Вы хотите так или иначе загрузить и использовать ваш образ. Теперь мы должны понять, как эти вещи работают, чтобы приспособить их для своей работы! Позволю себе кратко описать загрузочный процесс ОС. Когда мы включаем компьютер, он запустит BIOS, который сначала выполнит POST (Power On Self Test). Затем будут инициализированы присутствующие системные компоненты. Если будут обнаружены некоторые специальные компоненты, тогда BIOS вызовет соответствующие им расширенные подпрограммы, чтобы их тоже инициализировать. Наконец, когда все проинициализировано, BIOS посмотрит, есть ли кто-то, чтобы перехватить управление. Он проверит загрузочную запись и решит, где ее искать и в какой последовательности загружать. Предположим, что BIOS просматривает жесткий диск с самого начала. Жесткий диск разделен на несколько разделов, каждая из которых действует как независимый диск. Track0/Sector0/Head0 активного раздела жесткого диска (а также Flash Disk-а), как предполагается, содержит MBR (Master Boot Record). BIOS, обнаружив MBR-подпись в этом секторе, загружает его в память и передает ему управление. MBR - очень маленькая универсальная программа, которую фактически не знает как загружать ОС, но знает, какие разделы содержит ОС. Нулевой сектор раздела содержит "Boot Records" (загрузочную запись). Этот блок начальной загрузки - определяет специфику раздела ОС и знает, как ее грузить. Если мы загружаемся с дискеты MBR отсутствует, и загрузчик находится в Track0/Sector0/Head0 диска.

    В QNX загрузчик (это характерно для любого мультисистемного загрузчика) находится в MBR. После выбора загрузочного раздела, он загружает boot records этого раздела и передает управление ему непосредственно. В том случае, если это QNX раздел, тогда управление берет на себя QNX и выводит знакомое сообщение "Press ESC for .altboot.". После этого он начинает загружать содержимое ".boot" или ".altboot", в зависимости от выбора пользователя. ".boot" (или ".altboot") - это образ neutrino. Он связывается с заголовком ".boot" или ".altboot" и копирует загрузочный код в память, загружает критические структуры данных с информацией, которая у него есть и обрабатывает ее по управлению загрузочного кода. Обратите внимание, что код запуска - "startup-bios" для ".bootstrap" файла строителя (эти данные никогда не сжимаются). Сейчас все это - еще не QNX. Но все это уже знает, как проводить исследование различных аппаратных средств. Он получает информацию про определенные параметры ЦП машины, формирует связь между ядром и машиной, распаковывает образ, затем загружает ядро и наконец запускает сценарий запуска. Ура-а-а-а!!! Так много всего происходит, чтобы запустить эту глупую коробку...

    Итак, чему же мы научились от всего этого рассказа? Если вы не уверены в себе, я рекомендовал бы просмотреть вышесказанное снова. Так или иначе серьезные люди выяснили бы все что им нужно, мы однозначно крюком или хуком должны получить наш образ neutrino в виде ".boot" (или ".altboot", поскольку вам это нравится!). Создание образа относительно просто и требует самых минимальных знаний программы..... (жаль, что не дают призы за мою работу)... "dinit". Ниже приведено его типичное использование:

    dinit -f my.ifs /dev/fd0

    Эта программа форматирует гибкий диск, записывает boot records и заполняет ".boot" содержимым my.ifs. Если у вас уже есть созданные разделы, вы только заменяете /.altboot my.ifs, используя:

    cp -f my.ifs/.altboot

    Предупреждение. Вы должны быть твердо уверены, что по крайней мере один из /.boot и /.altboot является нормальным и позволит вам загрузиться в вашу систему, иначе вы будете жалеть об этом позже.

    Все сказали и сделали... сейчас можно перегружаться.


    ФАЙЛ-СТРОИТЕЛЬ #1:

    Цель

    Создать образ системы, который выведет сообщение "Hello World!" после своей загрузки. Ресурсы: x86/bios

    Подход

    Мы уже знаем, что нам доступно печать сообщения "display_msg". Таким образом мы не нуждаемся в какой-либо внешней программе, чтобы это сделать.

    Файл-строитель

    [virtual=x86,bios +compress] .bootstrap={ startup-bios -s 64k procnto } [+script] .script={ display_msg "Hello World..." }

    ФАЙЛ-СТРОИТЕЛЬ #2:

    Цель

    Создать образ системы, после загрузки которого я могу исследовать среду.Ресурсы: x86/bios

    Подход

    Чтобы исследовать среду, нам нужна оболочка и некоторые команды, чтобы посмотреть окружение ls и less. ksh должен выполняться в этом случае, таким образом, мы уменьшаем объем свободного места.

    Файл-строитель

    [virtual=x86,bios +compress] .bootstrap={ startup-bios -s 64k procnto } [+script] .script={ seedres PATH=/proc/boot LD_LIBRARY_PATH=/proc/boot:/usr/lib display_msg "Explorer Image..." devc-con -n2 & reopen /dev/con2 [+session] ksh & reopen /dev/con1 [+session] ksh & } libc.so.1 [type=link] /usr/lib/ldqnx.so.1=/proc/boot/libc.so.1 [data=copy] [perms=+r,+x] seedres ls ksh devc-con less ps sin pidin

    ФАЙЛ-СТРОИТЕЛЬ #3:

    Цель

    Создать сеть, позволяющую системное использование образа, в котором я могу выполнить telnet/ftp на других машинах. Ресурсы: x86, bios

    Подход

    Чтобы создать такой тип образа, нам нужен NIC драйвер со стеком TCP/IP. Telnet/ftp может легко работать с урезанным стеком. Я предположу, что у нас есть NE2000 совместимая PCI NIC. Если компьютер не имеет PCI шины, и плата - ISA одна, мы просто должны исключить pci-bios.

    Файл-строитель

    [virtual=x86,bios +compress] .bootstrap={ startup-bios -s 64k procnto } [+script] .script={ PATH=/proc/boot LD_LIBRARY_PATH=/proc/boot:/usr/lib HOME=/ TERM=qansi-m display_msg "Network image" seedres pipe & pci-bios & waitfor /dev/pci #\ обозначает продолжение линии # если у вас одна линия io-net -dne2000 -pttcpip \ if=en0:YOURIP:YOURNETMASK \ default=GATEWAY devc-con -n2 & reopen /dev/con2 [+session] ksh & reopen /dev/con1 [+session] ksh & } # нижеприведенное является примером встроенного файла # который нам необходимо создать, поскольку свои машины # не признают наш qansi-m терминал [ p e r m s = + r , + x ] / . k s h r c = { alias telnet="TERM=ansi /proc/boot/telnet" } libc.so.1 libsocket.so.1 npm-ttcpip.so devn-ne200.so /etc/hosts=/etc/hosts /etc/termcap=/etc/termcap [type=link] /usr/lib/ldqnx.so.1=/proc/boot/libc.so.1 [data=copy] [perms=+r,+x] seedres pipe ksh devc-con io-net /usr/bin/ftp /usr/bin/telnet /usr/bin/ping

    ФАЙЛ-СТРОИТЕЛЬ #4:

    Цель

    Создать (почти) полностью записанный в ППЗУ системный образ с сетью, который должен загрузиться с гибкого диска и по удаленному доступу смонтировать свою файловую систему через NFS/CIFS. Таким образом это подобно пульту базирования настольной системы. Ресурсы: x86, bios

    Подход

    Чтобы создать такой тип образа, нам необходима установка, подобная предыдущей. Кроме того, мы должны подготовить сервер. Если мы сможем создать QNX машину как сервер, все будет просто, поскольку / должна экспортироваться только для чтения через SAMBA или NFS. Или мы можем cкопировать полностью /lib, /usr, /sbin и /bin к любой другой *nix или windows машине и экспортировать корневой каталог (например, /home/mine/QNX) через NFS/CIFS (Samba). Со стороны клиентов, нам необходима мощная установка, для обеспечения оптимальной работы, также необходим полный стек TCP/IP. Так что будет лучше, если мы сможем урезать все это и разместить на другом носителе, на который мы в итоге будем попадать после установки файловой системы.

    Файл-строитель

    [search=/bin:/usr/bin:/lib:/usr/lib:/sbin:/lib/dll] [virtual=x86,bios +compress] .bootstrap={ startup-bios -s 64k PATH=/proc/boot procnto } [+script] .script={ PATH=/proc/boot LD_LIBRARY_PATH=/proc/boot:/usr/lib HOME=/ TERM=qansi-m display_msg "Full Network image" seedres pipe & pci-bios & waitfor /dev/pci io-net -dne2000 -p tcpip ifconfig en0 192.168.4.100 netmask 255.255.255.0 route add default 192.168.4.1 fs-nfs2 192.168.4.19:/home/mine/qnx / # или # fs-cifs //W2kPC:192.168.4.19:/qnxdir / "u" "p" devc-con -n2 & reopen /dev/con2 [+session] uesh & reopen /dev/con1 [+session] uesh & } libc.so.1 libsocket.so.1 npm-tcpip.so devn-ne200.so /etc/hosts=/etc/hosts /etc/termcap=/etc/termcap /etc/passwd=/etc/passwd /etc/group=/etc/group [type=link] /usr/lib/ldqnx.so.1=/proc/boot/libc.so.1 [data=copy] [perms=+r,+x] seedres pipe # используем минимальную конфигурацию uesh devc-con io-net ifconfig route fs-nfs2 # or fs-cifs

    ФАЙЛ-СТРОИТЕЛЬ #5:

    Цель

    Я хочу загрузиться с дискеты и хочу загрузить мой любимый проект содержащий "tomatageddon" (игра). Ресурсы: x86, bios

    Подход

    Проблема с такими требованиями состоит в том, что, размер игры, проекта и общедоступных библиотек C++ намного превышают максимальный размер файла-строителя, который не может быть больше 1 МБ после подключения всего этого обычным образом. Значит мы должны найти альтернативу. Нам не нужно использовать сеть, так что предыдущий файл-строитель не пригоден для этого. Но заметьте, что... Подумайте, сколько свободного места на дискете? 1.44 MБ, а мы используем только 600 кБ из него... Черт возьми, куда делось остальное место? Ответ: вы можете найти его, смонтировав дискету, "dinit" сделает это за вас. Используйте:

    mount -t qnx4/dev/fd0/fs/fd0

    Что же вы обнаружили в /fs/fd0? Большое количество свободного места... - не так ли! Теперь вы должны задаться вопросом, можете ли его использовать или нет! Да! Можно. Следующее, что необходимо сделать - скопировать наши файлы на диск и создать условия для их запуска. Поскольку мы хотим сохранить побольше свободного места, нам придется выполнить сжатие файлов. Мы сожмем файлы, а затем распакуем их в RAM-диск, что обеспечиваетcя мастером Neutrino /Dev/shmem. Это мжно сделать лишь в том случае, если вы имеете, по крайней мере, 4МБ ОЗУ в вашей системе. Это выглядит следующим образом:

    mkdir transfer cd transfer copy /usr/lib/libncurses.a . copy /usr/lib/libstdc++.so.2.10.0 . copy /anywhere/tomatageddon . # фактически вы уже создали загрузочный диск # с файлом-строителем mount -tqnx4 /dev/fd0 /fs/fd0 # если у вас достаточно места на диске, чтобы просто разместить файлы, # пропустите этот шаг gzip * # теперь скопируем файлы cp * /fs/fd0 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # после загрузки cd /dev/shmem # если вы не сжимали файлы, пропустите следующие 4 шага gunzip < /libncurses.a.gz > libncurses.a gunzip < /libstdc++.so.2.10.gz > libstdc++.so.2.10 gunzip < /tomatageddon.gz > tomatageddon chmod 755 tomatageddon # наслаждайтесь ./tomatageddon

    Файл-строитель

    [virtual=x86,bios +compress] .bootstrap={ startup-bios -s 64k PATH=/proc/boot:/dev/shmem \ LD_LIBRARY_PATH=/proc/boot:/lib:/usr/lib:/:\ /dev/shmem procnto } [+script] script={ LD_LIBRARY_PATH=/proc/boot:\ /lib:/usr/lib:/:/dev/shmem display_msg "Game image" seedres pipe & pci-bios & waitfor /dev/pci devb-fdc cam quite disk name=fd blk\ automount=fd0:/:qnx4,cache=100k devc-con -n2 & reopen /dev/con2 [+session] esh & reopen /dev/con1 [+session] esh & } libc.so.1 fs-qnx4.so cam-disk.so libcam.so io-blk.so [type=link] /usr/lib/ldqnx.so.1=/proc/boot/libc.so.1 [type=link] /proc/boot/cam-disk.so.1=/proc/boot/cam-disk.so /etc/termcap=/etc/termcap /usr/lib/terminfo=/usr/lib/terminfo [data=copy] [perms=+r,+x] seedres pci-bios esh devc-con devb-fdc pipe chmod ls /proc/boot/gunzip=/usr/bin/gzip

    ФАЙЛ-СТРОИТЕЛЬ #6:

    Цель

    Я не хочу ждать 30 секунд, пока загрузится мой компьютер. Мне надо быстро загрузиться.

    Подход

    Проектирование образа такого вида - хитрая задача. Сначала нам надо знать, как загружается QNX RTP, только после этого мы сможем выполнить эту задачу. Мы начнем, смотреть в /boot/build, где располагается файл-строитель, по умолчанию /.boot. Мы увидим, что они содержат драйвера файловой системы и утилиту "diskboot". Больше ничего нет кроме "diskboot". Мы пойдем другим путем. Мы должны быть уверены относительно одной вещи, что нам необходимо смонтировать жесткий диск и устанавливать точку монтирования "/". Таким образом, мы создаем файл-строитель, который запускает "devb-eide" и устанавливает точку монтирования на /.

    devb-eide cam quite blk automount=hd0t79:/:qnx4

    Так, что же мы видим... после загрузки установки каталогов отсутствуют! Что же пошло не так как надо? Подождите... в RTP существует так называемая "package filesystem" (пакетная файловая система). Значит нам надо продвигаться дальше, наберем "fs-pkg"... ой! Система отвечает "No such command or file". Что дальше? Исследовав систему, мы увидим, что "fs-pkg" постоянно находится в /sbin, но этого каталога там не было, когда мы смонтировали жесткий диск, это означает только одно - /sbin был создан "fs-pkg". Но если сам fs-pkg находится в /sbin, как чертовая система его выполняет? Смешно, не так ли? Ответ лежит просто в обзоре... Пробуйте "mount", он выдаст сообщение о том, что вы уже смонтировали файловую систему. На моем разделе установлен hd0t79, смонтированный на ....... и пишет, что это "/boot/fs/qnxbase.qfs on /pkgs/base qnx". Кто его смонтировал? Команда "find /pkgs/base -name fs-pkg" показывает, что fs-pkg фактически постоянно находится в "/pkgs/base/qnx/os/core-2.1.1/x86/sbin/fs-pkg". Мы уже отметили, что /boot была доступна после монтирования. Так что мы добавляем mount в файл-строитель и также добавляем команду, устанавливающую "/boot/fs/qnxbase.qfs" в /pkgs/base, и затем выполняем fs-pkg. Вуаля! После загрузки все каталоги находятся там. Вся работа заключалась в создании скрипта запуска, который система запустит после загрузки. После этого сценария, проходит инициализация аппаратных устройств типа графических плат, звуковых карт, сетевых устройств; система запускает соответствующие драйверы, и наконец загружает фотон. Очевидное, что этот сценарий должен находиться в /etc, так что мы начнем шариться там... Ничего себе! Мы увидим, что сценарии отрабатывают много чего... /еtc/system/sysinit имеет все команды, которые запускают enum-* семейство программ, которые исследуют аппаратные средства. Таким образом, мы должны в конечной строке файла-строителя написать соответствующую команду для выполнения этого файла. Теперь мы можем работать! Подождите, после выполнения всего этого, наш файл-строитель все еще медленный... Так что же теперь? Посмотрим на параметры devb-eide и времени, которое требуется для выполнения, мы увидим, что если мы укажем параметры для нашего EIDE контроллера, система могла бы загружаться быстрее. Обратим внимание на следующие параметры - nopci, slave, ioport и irq. Если у нас нет второго жесткого диска на slave, мы должны сообщить об этом системе. Для этого необходимо установить соответствующий флажок на параметр slave. Если у нас нет PCI-контроллера жесткого диска, флажок nopci - правильное решение. Теперь для оценки irq и ioport, мы загружаемся в windows, заходим в панель управления->система-> аппаратные устройства, выбираем контроллер жесткого диска и вызываем его свойства. Тут мы увидим, что там перечислены два IRQ, первое значение для primary IDE controller, а второе - для secondary... Мир! Мы быстро записываем эти значения. Теперь вернемся к ioport, Аллилуйя!!

    Что же это такое... Так много значений и так много данных. Спокойствие и еще раз спокойствие! devb-eide драйвер требует только начальный IO адрес. Самые нижние значения портов очевидны, но их не следует выбирать. Выбирать надо те значения, которые расположены в расширенном диапазоне. На моей системе они были F000 и F008 для Primary и Secondary контроллеров соответственно. Мы устанавливаем эти значения и перезагружаемся. Да! На сей раз система загрузилось быстрее чем когда-либо, время загрузки сократилось в два раза! Так что окончательный файл-строитель выглядит следующим образом:

    Файл-строитель

    [search=/sbin:/usr/sbin:/bin:/usr/bin:/lib:/lib/dll:/boot/sys:.] [virtual=x86,bios +compress] boot = { startup-bios -s 64k PATH=/proc/boot:/bin:/usr/bin\ LD_LIBRARY_PATH=/proc/boot:/lib:/usr/lib:/lib/dll\ procnto } [+script] startup-script = { display_msg "" display_msg "Welcome to QNX Neutrino 6" display_msg "Neutrino image built by Mritunjai" seedres pci-bios & waitfor /dev/pci slogger -l /var/log/slog devc-con -n 4 display_msg "Starting devb-eide..." # строка ниже \ обозначает продолжение devb-eide blk \ automount=hd0t79:/:qnx4,\ automount=hd0t12:/fs/hd0-dos:dos,\ automount=cd0:/fs/cd0:cd dos exec=all,fsi=updat\ cam quite eide \ nopci,slave,irq=14/15,ioport=f000,f008 waitfor /pkgs 30 display_msg "" display_msg "Done." display_msg "Mounted /dev/hd0t79 on /" # Используйте это если хотите... будьте уверены, что это замедлит загрузку # но обеспечение безопасности данных должно стоять на первом месте #display_msg "Checking / for inconsistencies..." #chkfsys -qPr / #display_msg "Done." display_msg "Mounting base packages" mount -t qnx4 /boot/fs/qnxbase.qfs /pkgs/base display_msg "Starting fs-pkg" /pkgs/base/qnx/os/core-2.1.1/x86/sbin/fs-pkg display_msg "Starting sysinit..." /bin/sh -c /etc/system/sysinit } /var/log/slog = { } [type=link] /dev/console=/dev/con1 libc.so [type=link] /usr/lib/ldqnx.so.1=/proc/boot/libc.so libcam.so io-blk.so cam-disk.so fs-qnx4.so fs-dos.so cam-cdrom.so fs-cd.so [data=copy] [perms=+r,+x] seedres pci-bios devb-eide slogger devc-con sh mount chkfsys

    Расширение ожидания

    Когда все идет хорошо, почему бы не добавить улучшение обзора ко всему этому! Нам ничего не мешает записать нашу собственную программу, которая не только не загружает систему, но и сообщает нам про время, которое занимает загрузка системы. Вот - исходный код моей программы, написанной на языке C:

    #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv) { int secs = -1, nsec = 0; if(argc<2) { printf("Use: %s <path> [time_in_seconds]\n", argv[0]) ; return -1; } if(argc==3) { secs=atoi(argv[2]); } while(secs == -1 || secs-- > 0) { if(access(argv[1], F_OK) == 0) { break; } if(secs>=0) { printf("\r%d", nsec++); fflush(stdout); } else { printf("\r"); } delay(200); printf("."); fflush(stdout); delay(200); printf("."); fflush(stdout); delay(200); printf("."); fflush(stdout); delay(200); printf("."); fflush(stdout); delay(200); printf("\r"); fflush(stdout); if(secs<0) { secs = -1; } } if(access(argv[1], F_OK) == -1) { /* следующая строка обозначает продолжение */ printf("\rTIMEOUT: Could not access \'%s\' \ in \%s seconds.\n", argv[1], argv[2]); fflush(stdout); return 1; } printf("\r\n"); return 0; }

    Эпилог

    В конце концов, я не могу все это делать без ваших предложений. Придумайте их. Я буду добавлять их время от времени.

    [Вернуться к списку]
    ©   2000-2003 Команда проекта QNX.ORG.RU // QNX.ORG.RU Team
    Авторы проекта: Дмитрий Алексеев [dmi] и Дмитрий Васильев. Техническое сопровождение проекта: Игорь Сорокин [isorokin]. Информационное сопровождение: Дмитрий Алексеев [dmi]
    QNX - зарегистрированная торговая марка QNX Software Systems, Ltd., Canada. Остальные упоминаемые на сайте торговые марки и логотипы являются исключительно собственностью их уважаемых владельцев. Ничьи права не затронуты. Материалы сайта не могут быть скопированы и где-либо использованы в той или иной форме без письменного разрешения разработчиков сайта.
    Powered by Mambo Open Source