Последнее время все больше компаний проявляет интерес к микроядерным операционным системам. Эти системы из разряда академических начинают переходить в разряд ОС для применения в реальных продуктах. Например, представленная недавно платформа Samsung Knox построенна с использованием OKL4 Microvisor. Весьма вероятно, что таких решений гораздо больше, но не все производители афишируют используемые технологии, так как на данный момент микроядерные системы, в основном, применяются в сфере информационной безопасности.
Краткая история микроядерных ОС и описание наиболее известных проектов недавно были описаны моим коллегой sartakov в статье "Микроядра и FOSDEM'13". Я хочу рассказать более подробно о Genode OS Framework и процессе портирования его на новую аппаратную платформу на базе процессора архитектуры ARM. В качестве ядра для Genode использовал Fiasco.OC.

И так, что такое Genode OS Framework? Это фреймворк для построения операционной системы на базе мик��оядра. Genode предоставляет единый API, позволяющий использовать различные микроядра для построения ОС. На данный момент поддерживаются следующие микроядра: Codezero, Fiasco, Fiasco.OC, Nova, OKL4, Pistachio. Также поддерживается работа на ядре Linux. Кроме этого, возможен запуск без использования сторонних ядер (base-hw) на некоторых платформах на базе архитектуры ARM.
Эти ядра поддерживают разные архитектуры процессоров и могут использовать некоторые аппаратные возможности. Например, ядро Fiasco.OC может работать на большом количестве архитектур, таких как: x86, amd64, ARM (доступны и другие архитектуры, но их поддержка не используются в Genode на данный момент), а ядро Nova является микрогипервизором для архитектуры x86 и позволяет использовать аппаратную виртуализацию. Благодаря использованию фреймворка Genode мы можем без изменений исходного кода компилировать приложение для использования на любом из поддерживаемых ядер.
Более подробную информацию о Genode можно получить из документации, размещенной на сайте проекта, а также из материалов, прочитаных Norman Feske для "Летней школы системного программирования Ksys labs"
В настоящее время Genode+Fiasco.OC для архитектуры ARM поддерживает следующие платформы: Realview PBXA9, Versatile Express A9X4, Pandaboard (TI OMAP4), Freescale iMX53, Arndale (Samsung Exynos 5). Все эти отладочные платы имеют довольно большую стоимость, а некоторые, вообще, очень трудно приобрести. Сейчас имеется множество одноплатных ПК с ценой менее 100$, которые используются энтузиастами и как отладочные платы для изучения ОС, и как основа для прототипирования и изготовления своих устройств. На эти устройства обычно портирован Linux и на некоторые даже имеется документация в открытых источниках. Хорошая статья с обзором доступных устройств "Выбираем мини компьютер для домашнего творчества (DIY)". Некоторые платформы описаных плат уже поддерживаются ядром Fiasco.OC и не требуют портирования.
Как вы уже, наверно, догадались по фотографии в начале поста, в качестве платформы для портирования я использовал мини-ПК Cubieboard на базе SoC Allwinner A10.
Эта платформа интересна по ряду причин:
— не слишком устаревшая архитектура Cortex-A8;
— наличие исходного кода загрузчика U-Boot, ядра Linux и наличие «утекшей» в сеть документации в виде руководства пользователя;
— большой набор переферии (SATA, HDMI, и др.);
— наличие большого количества недорогих «hackable» устройств на этом чипе (Cubieboard, Mele A1000/A2000, и другие).
Рассмотрим этот SoC более подробно.

CPU: ARM Cortex-A8 с частотой до 1Ghz с поддержкой NEON, VFPv3, Trustzone
GPU: Mali 400 MP с поддержкой Open GL ES 2.0
VPU: CedarX с поддержкой FullHD видео.
Переферия: 4xUSB Host, USB OTG, 4xSD/MMC, 8xUART, 4xSPI, 3xI2C, GPIO, SATA, HDMI, LCD-интерфейс и другие
Ядро Fiasco.OC поддерживает архитектуру процессоров Cortex-A8. Это значит, что для портирования его на новую платформу нужно только добавить поддержку платформы, так называемый Board Support Package (BSP). Исходный код BSP расположен в директории kernel/fiasco/src/kern/arm/bsp.
В состав BSP для архитектуры ARM в Fiasco.OC входит:
— драйвер контроллера прерываний;
— драйвер таймера;
— драйвер UART;
— реализация сброса.
Кроме этого, в состав BSP входит конфигурация распределения памяти.
Память в A10, согласно руководству пользователя, распределяется следующим образом:

Для того, чтобы ОС могла использовать память, она должна знать физические адреса. Эти параметры задаются в классе Mem_layout, файл mem_layout-arm-sun4i.cpp:
Контроллер прерываний необходим для обработки событий от различных источников. Драйвер контроллера прерываний используется для управления контроллером, выполняя такие операции как: конфигурация контроллера, маскирование прерываний, функция обработки. Код драйвера в файле pic-arm-sun4i.cpp.
Таймер необходим для генерации событий, таких как: конец тайм-слота или таймаут IPC. В A10 имеется 6 таймеров. В качестве таймера для переодических прерываний используется таймер Timer0. Кроме таймеров общего назначения в состав SoC также входят Watchdog и RTC с будильником. Для использования таймера в режиме системного он должен генерировать прерывание каждую 1 мс. Инициализация таймера и необходимые функции реализованы в файле timer-arm-sun4i.cpp.
Драйвер UART используется ядром для вывода отладочных сообщений и доступа к отладчику ядра JDB. В Fiasco.OC инициализация модуля UART отсутсвует, считается, что его уже настроил загрузчик, в нашем случае — U-Boot. Код драйвера UART находится в файлах uart-arm-sun4i.cpp и kernel/fiasco/src/lib/uart/uart_sun4i.cc.
Для выполнения полного сброса процессора применяется Watchdog таймера, назначением которого является сброс системы при зацикливании кода. Реализация находится в файле reset-arm-sun4i.cpp.
После выполнения этих действий мы получаем BSP для выбраного процессора. Но ядро еще нужно загрузить. Рассмотрим процесс загрузки Genode+Fiasco.OC на архитектуре ARM:
1. При старте ROM-boot ищет загрузчик на SD-карте или загружается с NAND при отсутсвии SD-карты.
2. U-Boot, выполняя стартовые скрипты, загружает образ Genode в виде ELF или u-boot-image.
3. Загруженный модуль содержит в себе ядро Fiasco.OC и все остальные исполняемые файлы, такие как: sigma0, root task (в Genode это модуль core) и пользовательские программы.
4. Первым стартует bootstrap, который выполняет часть операций неоходимых для старта ядра, такие как:
— сканирование доступной памяти (выполняется не для всех архитектур, на ARM значение доступной памяти задается в конфигурации на платформу);
— перемещение модулей в памяти (sigma0 и root task должны быть расположены в определенных регионах, чтобы ядро при старте могло их запустить);
— и непосредственно запуск ядра.
7. Ядро выполняет необходимую инициализацию системы, запускает sigma0 и root task.
8. Начинает выполняться модуль core (являющийся root task), который инициализирует сервисы Genode и позволяет запускать необходимые нам приложения, используя конфигурационный файл.
Соответсвенно для запуска bootstrap на Cubieboard он должен знать об этой платформе, поэтому добавляем нужную конфигурацию l4/mk/platforms/cubieboard.conf и l4/pkg/bootstrap/server/src/platform/sun4i.cc. Кроме этого необходимо реализовать драйвер UART для вывода информации о загрузке в консоль.
Заключительный этап портирования — добавление необходимых файлов конфигурации в сборочную систему Genode. Процесс несложный, описывать не буду, изменения можно посмотреть в соответвующем коммите в репозитории. Хорошее описание системы сборки было рассмотрено в лекции "Genode OS Framework Programming Environment".
Исходные коды находятся на Github https://github.com/Ksys-labs/genode в ветке tutorials. Модифицированная версия Fiasco.OC в репозитории https://github.com/Ksys-labs/foc в ветке r47-sun4i, эти исходные коды уже содержат необходимые патчи и скачиваются с помощью системы сборки Genode.
Для сборки необходимо клонировать исходный код:
Собрать тулчейн для ARM:
И скачать ядро Fiasco.OC:
Теперь все готово для запуска.
1. Создаем директорию для сборки, используя команду:
2. Добавляем репозиторий hello_tutorial для сбоки простейшего сценария, которому не требуются отсутсвующие пока драйверы.
3. Включаем генерацию файла u-boot-image
4. Cобираем образ
После непродолжительной сборки получаем образ в виде: ELF (hello.elf) и u-boot-image (uImage) в директории var/run/hello.
После запуска на устройстве, в подключенной консоле, можно увидеть процесс загрузки и выполняющиеся приложения из hello tutorial:
Как видите, портировать микроядро на новую архитектуру совершенно не сложно. Конечно, как я писал выше, для использования микроядер в реальных проектах, все упирается в поддержку аппаратного обеспечения платформы. Например, при изготовлении прототипов устройств на базе Pandaboard и Gumstix Overo нам пришлось добавить множество драйверов, таких как: GPIO, UART, SPI, I2C. Эти интерфейсы требовались для работы с ЖКИ, тачскрином и считывателем смарткарт. Для использования Cubieboard, как мини-ПК с Genode, как минимум, необходимо написать (или портировать) драйверы: Framebuffer, USB, Ethernet.
Genode Labs планирует построить современную ОС на базе своего фреймворка и они уверенно двигаются в этом направлении. Это очень интересный открытый проект, связаный с альтернативными ОС. Genode не сильно требователен к ресурсам, и по моему мнению, одноплатные ПК на архитектуре ARM вполне могут использоваться, как одна из дешевых платформ для этой ОС.
Кроме этого, Genode отлично подходит для обучения в области Computer Science, и если вы студент и вам это интересно, вы можете присоединиться к нам. Для этого нужно посмотреть первые три лекции (1,2,3) и выполнить из них задания. Решение нужно выложить на Github и прислать ссылку на почту edu@ksyslabs.org.
Краткая история микроядерных ОС и описание наиболее известных проектов недавно были описаны моим коллегой sartakov в статье "Микроядра и FOSDEM'13". Я хочу рассказать более подробно о Genode OS Framework и процессе портирования его на новую аппаратную платформу на базе процессора архитектуры ARM. В качестве ядра для Genode использовал Fiasco.OC.

И так, что такое Genode OS Framework? Это фреймворк для построения операционной системы на базе мик��оядра. Genode предоставляет единый API, позволяющий использовать различные микроядра для построения ОС. На данный момент поддерживаются следующие микроядра: Codezero, Fiasco, Fiasco.OC, Nova, OKL4, Pistachio. Также поддерживается работа на ядре Linux. Кроме этого, возможен запуск без использования сторонних ядер (base-hw) на некоторых платформах на базе архитектуры ARM.
Эти ядра поддерживают разные архитектуры процессоров и могут использовать некоторые аппаратные возможности. Например, ядро Fiasco.OC может работать на большом количестве архитектур, таких как: x86, amd64, ARM (доступны и другие архитектуры, но их поддержка не используются в Genode на данный момент), а ядро Nova является микрогипервизором для архитектуры x86 и позволяет использовать аппаратную виртуализацию. Благодаря использованию фреймворка Genode мы можем без изменений исходного кода компилировать приложение для использования на любом из поддерживаемых ядер.
Более подробную информацию о Genode можно получить из документации, размещенной на сайте проекта, а также из материалов, прочитаных Norman Feske для "Летней школы системного программирования Ksys labs"
В настоящее время Genode+Fiasco.OC для архитектуры ARM поддерживает следующие платформы: Realview PBXA9, Versatile Express A9X4, Pandaboard (TI OMAP4), Freescale iMX53, Arndale (Samsung Exynos 5). Все эти отладочные платы имеют довольно большую стоимость, а некоторые, вообще, очень трудно приобрести. Сейчас имеется множество одноплатных ПК с ценой менее 100$, которые используются энтузиастами и как отладочные платы для изучения ОС, и как основа для прототипирования и изготовления своих устройств. На эти устройства обычно портирован Linux и на некоторые даже имеется документация в открытых источниках. Хорошая статья с обзором доступных устройств "Выбираем мини компьютер для домашнего творчества (DIY)". Некоторые платформы описаных плат уже поддерживаются ядром Fiasco.OC и не требуют портирования.
Как вы уже, наверно, догадались по фотографии в начале поста, в качестве платформы для портирования я использовал мини-ПК Cubieboard на базе SoC Allwinner A10.
Эта платформа интересна по ряду причин:
— не слишком устаревшая архитектура Cortex-A8;
— наличие исходного кода загрузчика U-Boot, ядра Linux и наличие «утекшей» в сеть документации в виде руководства пользователя;
— большой набор переферии (SATA, HDMI, и др.);
— наличие большого количества недорогих «hackable» устройств на этом чипе (Cubieboard, Mele A1000/A2000, и другие).
Рассмотрим этот SoC более подробно.

CPU: ARM Cortex-A8 с частотой до 1Ghz с поддержкой NEON, VFPv3, Trustzone
GPU: Mali 400 MP с поддержкой Open GL ES 2.0
VPU: CedarX с поддержкой FullHD видео.
Переферия: 4xUSB Host, USB OTG, 4xSD/MMC, 8xUART, 4xSPI, 3xI2C, GPIO, SATA, HDMI, LCD-интерфейс и другие
Ядро Fiasco.OC поддерживает архитектуру процессоров Cortex-A8. Это значит, что для портирования его на новую платформу нужно только добавить поддержку платформы, так называемый Board Support Package (BSP). Исходный код BSP расположен в директории kernel/fiasco/src/kern/arm/bsp.
В состав BSP для архитектуры ARM в Fiasco.OC входит:
— драйвер контроллера прерываний;
— драйвер таймера;
— драйвер UART;
— реализация сброса.
Кроме этого, в состав BSP входит конфигурация распределения памяти.
Память в A10, согласно руководству пользователя, распределяется следующим образом:

Для того, чтобы ОС могла использовать память, она должна знать физические адреса. Эти параметры задаются в классе Mem_layout, файл mem_layout-arm-sun4i.cpp:
EXTENSION class Mem_layout
{
public:
enum Virt_layout_sun4i : Address {
Timer_map_base = Devices1_map_base + 0x020C00,
Intc_map_base = Devices1_map_base + 0x020400,
Uart_base = Devices1_map_base + 0x028000,
Watchdog_map_base = Timer_map_base + 0x90,
};
enum Phys_layout_sun4i : Address {
Devices1_phys_base = 0x01c00000,
Sdram_phys_base = 0x40000000,
Flush_area_phys_base = 0xe0000000,
};
};
Контроллер прерываний необходим для обработки событий от различных источников. Драйвер контроллера прерываний используется для управления контроллером, выполняя такие операции как: конфигурация контроллера, маскирование прерываний, функция обработки. Код драйвера в файле pic-arm-sun4i.cpp.
Таймер необходим для генерации событий, таких как: конец тайм-слота или таймаут IPC. В A10 имеется 6 таймеров. В качестве таймера для переодических прерываний используется таймер Timer0. Кроме таймеров общего назначения в состав SoC также входят Watchdog и RTC с будильником. Для использования таймера в режиме системного он должен генерировать прерывание каждую 1 мс. Инициализация таймера и необходимые функции реализованы в файле timer-arm-sun4i.cpp.
Драйвер UART используется ядром для вывода отладочных сообщений и доступа к отладчику ядра JDB. В Fiasco.OC инициализация модуля UART отсутсвует, считается, что его уже настроил загрузчик, в нашем случае — U-Boot. Код драйвера UART находится в файлах uart-arm-sun4i.cpp и kernel/fiasco/src/lib/uart/uart_sun4i.cc.
Для выполнения полного сброса процессора применяется Watchdog таймера, назначением которого является сброс системы при зацикливании кода. Реализация находится в файле reset-arm-sun4i.cpp.
После выполнения этих действий мы получаем BSP для выбраного процессора. Но ядро еще нужно загрузить. Рассмотрим процесс загрузки Genode+Fiasco.OC на архитектуре ARM:
1. При старте ROM-boot ищет загрузчик на SD-карте или загружается с NAND при отсутсвии SD-карты.
2. U-Boot, выполняя стартовые скрипты, загружает образ Genode в виде ELF или u-boot-image.
3. Загруженный модуль содержит в себе ядро Fiasco.OC и все остальные исполняемые файлы, такие как: sigma0, root task (в Genode это модуль core) и пользовательские программы.
4. Первым стартует bootstrap, который выполняет часть операций неоходимых для старта ядра, такие как:
— сканирование доступной памяти (выполняется не для всех архитектур, на ARM значение доступной памяти задается в конфигурации на платформу);
— перемещение модулей в памяти (sigma0 и root task должны быть расположены в определенных регионах, чтобы ядро при старте могло их запустить);
— и непосредственно запуск ядра.
7. Ядро выполняет необходимую инициализацию системы, запускает sigma0 и root task.
8. Начинает выполняться модуль core (являющийся root task), который инициализирует сервисы Genode и позволяет запускать необходимые нам приложения, используя конфигурационный файл.
Соответсвенно для запуска bootstrap на Cubieboard он должен знать об этой платформе, поэтому добавляем нужную конфигурацию l4/mk/platforms/cubieboard.conf и l4/pkg/bootstrap/server/src/platform/sun4i.cc. Кроме этого необходимо реализовать драйвер UART для вывода информации о загрузке в консоль.
Заключительный этап портирования — добавление необходимых файлов конфигурации в сборочную систему Genode. Процесс несложный, описывать не буду, изменения можно посмотреть в соответвующем коммите в репозитории. Хорошее описание системы сборки было рассмотрено в лекции "Genode OS Framework Programming Environment".
Исходные коды находятся на Github https://github.com/Ksys-labs/genode в ветке tutorials. Модифицированная версия Fiasco.OC в репозитории https://github.com/Ksys-labs/foc в ветке r47-sun4i, эти исходные коды уже содержат необходимые патчи и скачиваются с помощью системы сборки Genode.
Для сборки необходимо клонировать исходный код:
git clone git://github.com/Ksys-labs/genode.git
git checkout tutorials
cd genode
Собрать тулчейн для ARM:
./tools/tool_chain arm
И скачать ядро Fiasco.OC:
make prepare -C base-foc
Теперь все готово для запуска.
1. Создаем директорию для сборки, используя команду:
./tools/create_builddir foc_cubieboard BUILD_DIR=_build.foc_cubieboard
cd _build.foc_cubieboard
2. Добавляем репозиторий hello_tutorial для сбоки простейшего сценария, которому не требуются отсутсвующие пока драйверы.
echo 'REPOSITORIES += $(GENODE_DIR)/hello_tutorial' >> etc/build.conf
3. Включаем генерацию файла u-boot-image
echo 'SPECS += uboot' >> etc/spec.conf
4. Cобираем образ
make run/hello
После непродолжительной сборки получаем образ в виде: ELF (hello.elf) и u-boot-image (uImage) в директории var/run/hello.
После запуска на устройстве, в подключенной консоле, можно увидеть процесс загрузки и выполняющиеся приложения из hello tutorial:
Лог
L4 Bootstrapper
Build: #4 Чт. апр. 18 22:48:37 MSK 2013, 4.7.2
Scanning up to 1024 MB RAM
Memory size is 1024MB (40000000 — 80000000)
RAM: 0000000040000000 — 000000007fffffff: 1048576kB
Total RAM: 1024MB
mod07: 4117e000-411b8e3c: genode/timer
mod06: 41148000-4117ddc0: genode/hello_server
mod05: 4111c000-41147c28: genode/hello_client
mod04: 410d6000-4111b738: genode/init
mod03: 410d5000-410d51a4: genode/config
mod02: 4106e000-410d431c: genode/core
mod01: 41064000-4106d374: sigma0
mod00: 41015000-41063d20: /home/vanner/projects/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
Moving up to 8 modules behind 41100000
moving module 00 { 41015000-41063d1f } -> { 412a4000-412f2d1f } [322848]
moving module 01 { 41064000-4106d373 } -> { 412f3000-412fc373 } [37748]
moving module 02 { 4106e000-410d431b } -> { 412fd000-4136331b } [418588]
moving module 03 { 410d5000-410d51a3 } -> { 411b9000-411b91a3 } [420]
moving module 04 { 410d6000-4111b737 } -> { 411ba000-411ff737 } [284472]
moving module 05 { 4111c000-41147c27 } -> { 41100000-4112bc27 } [179240]
moving module 06 { 41148000-4117ddbf } -> { 4112c000-41161dbf } [220608]
moving module 07 { 4117e000-411b8e3b } -> { 41162000-4119ce3b } [241212]
moving module 03 { 411b9000-411b91a3 } -> { 4119d000-4119d1a3 } [420]
moving module 04 { 411ba000-411ff737 } -> { 4119e000-411e3737 } [284472]
Scanning /home/vanner/projects/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco -serial_esc
Scanning sigma0
Scanning genode/core
Relocated mbi to [0x4100e000-0x4100e19c]
Loading cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
Loading sigma0
Loading genode/core
find kernel info page…
found kernel info page at 0x40002000
Regions of list 'regions'
[ 40001000, 400019ff] { a00} Kern cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
[ 40002000, 40060fff] { 5f000} Kern cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
[ 40090000, 4009673b] { 673c} Sigma0 sigma0
[ 40098000, 4009e17b] { 617c} Sigma0 sigma0
[ 40100000, 4024743f] { 147440} Root genode/core
[ 41000000, 410143f3] { 143f4} Boot bootstrap
[ 4100e000, 4100e299] { 29a} Root Multiboot info
[ 41100000, 411e3737] { e3738} Root Module
API Version: (87) experimental
Sigma0 config ip:40090100 sp:41013d24
Roottask config ip:4014af84 sp:00000000
Starting kernel cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco at 40001198
Hello from Startup::stage2
Boot_alloc: size=0x180
Boot_alloc: allocated extra memory block @0xf13e1000 (size=400)
Boot_alloc: @ 0xf13e1000
Boot_alloc: remaining free block @ 0xf13e1180 (size=280)
Cache config: ON
ID_PFR[01]: 00001131 00000011 ID_[DA]FR0: 00000400 00000000
ID_MMFR[04]: 01100003 20000000 01202000 00000211
FPU0: Arch: VFPv3(3), Part: VFPv3(30), r: 3, v: c, i: 41, t: hard, p: dbl/sngl
Startup::stage2 finished
SERIAL ESC: allocated IRQ 1 for serial uart
Not using serial hack in slow timer handler.
Welcome to Fiasco.OC (arm)!
L4/Fiasco.OC arm microkernel 1998-2013 TU Dresden
Rev: 8991035 compiled with gcc 4.7.2 for sun4i []
Build: #3 Чт. апр. 18 22:48:33 MSK 2013
Calibrating timer loop… done.
SIGMA0: Hello!
KIP @ 40002000
allocated 4KB for maintenance structures
SIGMA0: Dump of all resource maps
RAM:------------------------
[0:40000000;40000fff]
[0:40061000;4008ffff]
[0:40097000;40097fff]
[0:4009f000;400fffff]
[4:40100000;40247fff]
[0:40248000;4100dfff]
[4:4100e000;4100efff]
[0:4100f000;410fffff]
[4:41100000;411e3fff]
[0:411e4000;7effffff]
IOMEM:----------------------
[0:0;3fffffff]
[0:80000000;ffffffff]
KIP @ 40002000
magic: 4be6344c
version: 87014444
sigma0 esp: 41013d24 eip: 40090100
sigma1 esp: 00000000 eip: 00000000
root esp: 00000000 eip: 4014af84
MBI @ 4100e000
mod[3] [4119d000,4119d1a4) config
mod[4] [4119e000,411e3738) init
mod[5] [41100000,4112bc28) hello_client
mod[6] [4112c000,41161dc0) hello_server
mod[7] [41162000,4119ce3c) timer
:ram_alloc: Allocator 40230784 dump:
Block: [50000000,5000001c) size=0000001c avail=00000000 max_avail=00000000
Block: [5000001c,50000038) size=0000001c avail=00000000 max_avail=00000000
Block: [50000038,50000054) size=0000001c avail=00000000 max_avail=00000000
Block: [50000054,50000070) size=0000001c avail=00000000 max_avail=2effff58
Block: [50000070,5000008c) size=0000001c avail=00000000 max_avail=00000000
Block: [5000008c,500000a8) size=0000001c avail=00000000 max_avail=2effff58
Block: [500000a8,7f000000) size=2effff58 avail=2effff58 max_avail=2effff58
=> mem_size=788529152 (752 MB) / mem_avail=788528984 (751 MB)
:region_alloc: Allocator 402318f4 dump:
Block: [00001000,40000000) size=3ffff000 avail=3ffff000 max_avail=3ffff000
Block: [7f000000,bfff0000) size=40ff0000 avail=40ff0000 max_avail=40ff0000
Block: [bfff1000,c0000000) size=0000f000 avail=0000f000 max_avail=0000f000
=> mem_size=2164252672 (2063 MB) / mem_avail=2164252672 (2063 MB)
:io_mem: Allocator 40230be0 dump:
Block: [00000000,40000000) size=40000000 avail=40000000 max_avail=40000000
Block: [40001000,40002000) size=00001000 avail=00001000 max_avail=40000000
Block: [40003000,40061000) size=0005e000 avail=0005e000 max_avail=0005e000
Block: [40090000,40097000) size=00007000 avail=00007000 max_avail=0005e000
Block: [40098000,4009f000) size=00007000 avail=00007000 max_avail=80ffffff
Block: [7f000000,ffffffff) size=80ffffff avail=80ffffff max_avail=80ffffff
=> mem_size=3238449151 (3088 MB) / mem_avail=3238449151 (3088 MB)
:io_port: Allocator 4023103c dump:
:irq: Allocator 40231498 dump:
Block: [00000000,00000100) size=00000100 avail=00000100 max_avail=00000100
=> mem_size=256 (0 MB) / mem_avail=256 (0 MB)
:rom_fs: Rom_fs 402321a8 dump:
Rom: [4119e000,411e3738) init
Rom: [41100000,4112bc28) hello_client
Rom: [4119d000,4119d1a4) config
Rom: [4112c000,41161dc0) hello_server
Rom: [40002000,40003000) l4v2_kip
Rom: [40002000,40003000) kip
Rom: [41162000,4119ce3c) timer
:core ranges: Allocator 40233f08 dump:
Block: [40100000,40248000) size=00148000 avail=00148000 max_avail=00148000
Block: [41100000,411e4000) size=000e4000 avail=000e4000 max_avail=2f000000
Block: [50000000,7f000000) size=2f000000 avail=2f000000 max_avail=2f000000
=> mem_size=790806528 (754 MB) / mem_avail=790806528 (754 MB)
int main(): — create local services — int main(): — start init — int main(): transferred 751 MB to init
int main(): — init created, waiting for exit condition — [init] Could not open file «ld.lib.so»
[init -> hello_server] Hello::Root_component::Root_component(Genode::Rpc_entrypoint*, Genode::Allocator*): Creating root component.
[init -> hello_server] virtual Hello::Session_component* Hello::Root_component::_create_session(const char*): creating hello session.
[init -> hello_client] virtual void Hello::Session_client::say_hello(): Saying Hello.
[init -> hello_server] virtual void Hello::Session_component::say_hello(): I am here… Hello.
[init -> hello_client] int main(): Added 2 + 5 = 7
[init -> hello_client] virtual void Hello::Session_client::say_hello(): Saying Hello.
[init -> hello_server] virtual void Hello::Session_component::say_hello(): I am here… Hello.
[init -> hello_client] int main(): Added 2 + 5 = 7
…
Build: #4 Чт. апр. 18 22:48:37 MSK 2013, 4.7.2
Scanning up to 1024 MB RAM
Memory size is 1024MB (40000000 — 80000000)
RAM: 0000000040000000 — 000000007fffffff: 1048576kB
Total RAM: 1024MB
mod07: 4117e000-411b8e3c: genode/timer
mod06: 41148000-4117ddc0: genode/hello_server
mod05: 4111c000-41147c28: genode/hello_client
mod04: 410d6000-4111b738: genode/init
mod03: 410d5000-410d51a4: genode/config
mod02: 4106e000-410d431c: genode/core
mod01: 41064000-4106d374: sigma0
mod00: 41015000-41063d20: /home/vanner/projects/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
Moving up to 8 modules behind 41100000
moving module 00 { 41015000-41063d1f } -> { 412a4000-412f2d1f } [322848]
moving module 01 { 41064000-4106d373 } -> { 412f3000-412fc373 } [37748]
moving module 02 { 4106e000-410d431b } -> { 412fd000-4136331b } [418588]
moving module 03 { 410d5000-410d51a3 } -> { 411b9000-411b91a3 } [420]
moving module 04 { 410d6000-4111b737 } -> { 411ba000-411ff737 } [284472]
moving module 05 { 4111c000-41147c27 } -> { 41100000-4112bc27 } [179240]
moving module 06 { 41148000-4117ddbf } -> { 4112c000-41161dbf } [220608]
moving module 07 { 4117e000-411b8e3b } -> { 41162000-4119ce3b } [241212]
moving module 03 { 411b9000-411b91a3 } -> { 4119d000-4119d1a3 } [420]
moving module 04 { 411ba000-411ff737 } -> { 4119e000-411e3737 } [284472]
Scanning /home/vanner/projects/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco -serial_esc
Scanning sigma0
Scanning genode/core
Relocated mbi to [0x4100e000-0x4100e19c]
Loading cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
Loading sigma0
Loading genode/core
find kernel info page…
found kernel info page at 0x40002000
Regions of list 'regions'
[ 40001000, 400019ff] { a00} Kern cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
[ 40002000, 40060fff] { 5f000} Kern cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco
[ 40090000, 4009673b] { 673c} Sigma0 sigma0
[ 40098000, 4009e17b] { 617c} Sigma0 sigma0
[ 40100000, 4024743f] { 147440} Root genode/core
[ 41000000, 410143f3] { 143f4} Boot bootstrap
[ 4100e000, 4100e299] { 29a} Root Multiboot info
[ 41100000, 411e3737] { e3738} Root Module
API Version: (87) experimental
Sigma0 config ip:40090100 sp:41013d24
Roottask config ip:4014af84 sp:00000000
Starting kernel cts/genode/_build.foc_cubieboard/kernel/fiasco.oc/fiasco at 40001198
Hello from Startup::stage2
Boot_alloc: size=0x180
Boot_alloc: allocated extra memory block @0xf13e1000 (size=400)
Boot_alloc: @ 0xf13e1000
Boot_alloc: remaining free block @ 0xf13e1180 (size=280)
Cache config: ON
ID_PFR[01]: 00001131 00000011 ID_[DA]FR0: 00000400 00000000
ID_MMFR[04]: 01100003 20000000 01202000 00000211
FPU0: Arch: VFPv3(3), Part: VFPv3(30), r: 3, v: c, i: 41, t: hard, p: dbl/sngl
Startup::stage2 finished
SERIAL ESC: allocated IRQ 1 for serial uart
Not using serial hack in slow timer handler.
Welcome to Fiasco.OC (arm)!
L4/Fiasco.OC arm microkernel 1998-2013 TU Dresden
Rev: 8991035 compiled with gcc 4.7.2 for sun4i []
Build: #3 Чт. апр. 18 22:48:33 MSK 2013
Calibrating timer loop… done.
SIGMA0: Hello!
KIP @ 40002000
allocated 4KB for maintenance structures
SIGMA0: Dump of all resource maps
RAM:------------------------
[0:40000000;40000fff]
[0:40061000;4008ffff]
[0:40097000;40097fff]
[0:4009f000;400fffff]
[4:40100000;40247fff]
[0:40248000;4100dfff]
[4:4100e000;4100efff]
[0:4100f000;410fffff]
[4:41100000;411e3fff]
[0:411e4000;7effffff]
IOMEM:----------------------
[0:0;3fffffff]
[0:80000000;ffffffff]
KIP @ 40002000
magic: 4be6344c
version: 87014444
sigma0 esp: 41013d24 eip: 40090100
sigma1 esp: 00000000 eip: 00000000
root esp: 00000000 eip: 4014af84
MBI @ 4100e000
mod[3] [4119d000,4119d1a4) config
mod[4] [4119e000,411e3738) init
mod[5] [41100000,4112bc28) hello_client
mod[6] [4112c000,41161dc0) hello_server
mod[7] [41162000,4119ce3c) timer
:ram_alloc: Allocator 40230784 dump:
Block: [50000000,5000001c) size=0000001c avail=00000000 max_avail=00000000
Block: [5000001c,50000038) size=0000001c avail=00000000 max_avail=00000000
Block: [50000038,50000054) size=0000001c avail=00000000 max_avail=00000000
Block: [50000054,50000070) size=0000001c avail=00000000 max_avail=2effff58
Block: [50000070,5000008c) size=0000001c avail=00000000 max_avail=00000000
Block: [5000008c,500000a8) size=0000001c avail=00000000 max_avail=2effff58
Block: [500000a8,7f000000) size=2effff58 avail=2effff58 max_avail=2effff58
=> mem_size=788529152 (752 MB) / mem_avail=788528984 (751 MB)
:region_alloc: Allocator 402318f4 dump:
Block: [00001000,40000000) size=3ffff000 avail=3ffff000 max_avail=3ffff000
Block: [7f000000,bfff0000) size=40ff0000 avail=40ff0000 max_avail=40ff0000
Block: [bfff1000,c0000000) size=0000f000 avail=0000f000 max_avail=0000f000
=> mem_size=2164252672 (2063 MB) / mem_avail=2164252672 (2063 MB)
:io_mem: Allocator 40230be0 dump:
Block: [00000000,40000000) size=40000000 avail=40000000 max_avail=40000000
Block: [40001000,40002000) size=00001000 avail=00001000 max_avail=40000000
Block: [40003000,40061000) size=0005e000 avail=0005e000 max_avail=0005e000
Block: [40090000,40097000) size=00007000 avail=00007000 max_avail=0005e000
Block: [40098000,4009f000) size=00007000 avail=00007000 max_avail=80ffffff
Block: [7f000000,ffffffff) size=80ffffff avail=80ffffff max_avail=80ffffff
=> mem_size=3238449151 (3088 MB) / mem_avail=3238449151 (3088 MB)
:io_port: Allocator 4023103c dump:
:irq: Allocator 40231498 dump:
Block: [00000000,00000100) size=00000100 avail=00000100 max_avail=00000100
=> mem_size=256 (0 MB) / mem_avail=256 (0 MB)
:rom_fs: Rom_fs 402321a8 dump:
Rom: [4119e000,411e3738) init
Rom: [41100000,4112bc28) hello_client
Rom: [4119d000,4119d1a4) config
Rom: [4112c000,41161dc0) hello_server
Rom: [40002000,40003000) l4v2_kip
Rom: [40002000,40003000) kip
Rom: [41162000,4119ce3c) timer
:core ranges: Allocator 40233f08 dump:
Block: [40100000,40248000) size=00148000 avail=00148000 max_avail=00148000
Block: [41100000,411e4000) size=000e4000 avail=000e4000 max_avail=2f000000
Block: [50000000,7f000000) size=2f000000 avail=2f000000 max_avail=2f000000
=> mem_size=790806528 (754 MB) / mem_avail=790806528 (754 MB)
int main(): — create local services — int main(): — start init — int main(): transferred 751 MB to init
int main(): — init created, waiting for exit condition — [init] Could not open file «ld.lib.so»
[init -> hello_server] Hello::Root_component::Root_component(Genode::Rpc_entrypoint*, Genode::Allocator*): Creating root component.
[init -> hello_server] virtual Hello::Session_component* Hello::Root_component::_create_session(const char*): creating hello session.
[init -> hello_client] virtual void Hello::Session_client::say_hello(): Saying Hello.
[init -> hello_server] virtual void Hello::Session_component::say_hello(): I am here… Hello.
[init -> hello_client] int main(): Added 2 + 5 = 7
[init -> hello_client] virtual void Hello::Session_client::say_hello(): Saying Hello.
[init -> hello_server] virtual void Hello::Session_component::say_hello(): I am here… Hello.
[init -> hello_client] int main(): Added 2 + 5 = 7
…
Как видите, портировать микроядро на новую архитектуру совершенно не сложно. Конечно, как я писал выше, для использования микроядер в реальных проектах, все упирается в поддержку аппаратного обеспечения платформы. Например, при изготовлении прототипов устройств на базе Pandaboard и Gumstix Overo нам пришлось добавить множество драйверов, таких как: GPIO, UART, SPI, I2C. Эти интерфейсы требовались для работы с ЖКИ, тачскрином и считывателем смарткарт. Для использования Cubieboard, как мини-ПК с Genode, как минимум, необходимо написать (или портировать) драйверы: Framebuffer, USB, Ethernet.
Genode Labs планирует построить современную ОС на базе своего фреймворка и они уверенно двигаются в этом направлении. Это очень интересный открытый проект, связаный с альтернативными ОС. Genode не сильно требователен к ресурсам, и по моему мнению, одноплатные ПК на архитектуре ARM вполне могут использоваться, как одна из дешевых платформ для этой ОС.
Кроме этого, Genode отлично подходит для обучения в области Computer Science, и если вы студент и вам это интересно, вы можете присоединиться к нам. Для этого нужно посмотреть первые три лекции (1,2,3) и выполнить из них задания. Решение нужно выложить на Github и прислать ссылку на почту edu@ksyslabs.org.
