Skip to content

future_plans_ru

Serge Vakulenko edited this page Aug 26, 2015 · 1 revision

Проект uOS - версия 0.3

Некоторые размышления, как бы это могло выглядеть.

Поддержка пяти архитектур процессоров:

  • Intel 386 - Pentium, AMD и совместимые. Загрузка с USB-flash диска через GRUB. Поддержка файловых систем EXT2 и VFAT. Графическая оболочка на основе DirectFB.
  • ARM - Atmel AT91SAM7 и AT91SAM9, Samsung S3C4530A. Загрузка из flash-памяти. Консоль (UART), Ethernet, HDLC. Для встроенных систем.
  • MIPS32 - Элвис Мультикор MC-24. Загрузка из flash-памяти. Консоль (UART), внешний CAN. Для встроенных систем.
  • MSP430 - 16-битная архитектура. Загрузка из flash-памяти. Консоль (UART), внешний Ethernet CS8900. Для встроенных систем.
  • AVR - 8-битная архитектура. Загрузка из flash-памяти. Консоль (UART), внешний Ethernet CS8900. Для встроенных систем.

Архитектура i86-dos больше не поддерживается. Эти микроконтроллеры вышли из моды, да и компилятор GCC для i86, видимо, умер не родившись.

С версии 0.3 проект uOS ориентируется на GCC.

Сетевые возможности: реализация протоколов TCP и Telnet.

Отложено на будущее:

  • Встроенный язык Lua.
  • Удалённая консоль по протоколу VNC.
  • Файловая система с использованием FUSE.
  • Перенос на архитектуру TI MSP430.

Динамическая загрузка

Поддерживается загрузка и выполнение независимо скомпилированных бинарных модулей. Формат ELF, позиционно-независимый код. Предполагается иметь два формата бинарных модулей:

  • .EX --- программа, выполняемая как независимый процесс.
  • .DL --- динамическая библиотека, дополняющая сегмент кода вызывающего процесса.

Поскольку все процессы выполняются в общем адресном пространстве, бинарный код должен иметь позиционно-независимый формат (gcc -fpic).

Модули взаимодействуют через //интерфейсы// -- таблицы функций-методов.

Защита памяти

Каждый процесс имеет свой набор страниц: выполняемый код и данные, доступные на запись.

Каждый поток имеет свои персональные:

  • Стек данных - доступен на чтение/запись. Для простоты имеет ограниченный размер, скажем 16 кбайт.
  • Стек процессов - расположен в данных ядра и самому потоку недоступен. Хранит адреса возврата при вызове функций другого процесса.
  • Карта памяти (page table). При переключении потоков аппаратная карта памяти меняется.

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

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

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

Процессы

Процесс представляет собой хранилище ресурсов - страниц памяти, потоков, открытых файлов и так далее. Для управления процессами предназначен Process_Manager, который хранит:

  1. список всех процессов (запрашивающих ресурсы)
  2. список всех сервисов (предоставляющих ресурсы)

При завершении процесса Process_Manager сообщает всем сервисам о необходимости освободить ресурсы.

Память

Page_Allocator выделяет и освобождает страницы памяти. Страницы помечаются как принадлежащие конкретному процессу.

Потоки

Потоками управляет Thread_Manager. Поток управления имеет отдельный стек данных и таблицу страниц. При вызове функции другого процесса таблица дополняется страницами вызываемого процесса. При возврате выполняется обратное действие.

Ядро

Ядро --- одновременно и Process_Manager и Page_Allocator.

У каждого модуля есть глобальная переменная Kernel, которая дает доступ к ядру.

Process_Manager для каждого экспортируемого интерфейса создает прокси. Вызов Export_Interface(object) возвращает указатель на интерфейс-прокси.

Вызов Managed_By(object) возвращает процесс, который занимается объектами этого типа. Или 0, если такого процесса уже нет.

Развитие в сторону ARINC 653

  1. Защита памяти. Каждый раздел работает в своей области памяти. Системные структуры могут быть доступны для него на чтение.
  2. Жёсткое расписание процессорного времени между разделами. Системный таймер становится частью ядра. Могут существовать разделы, не имеющие выделенного участка в расписании и работающие только по прерываниям, например драйвер UART или Etherhet.
  3. Переключение защиты памяти при системном вызове. В памяти команд перед адресом входа в функцию находится структура, описывающая метод переключения.

Сценарии для проработки:

  • Системный вызов: создание задачи
  • Системный вызов: посылка сообщения в порт
  • Прерывание от таймера
  • Прерывание от UART
  • Отладочная печать
  • Приём пакета TCP

Например, процессор 1986ВЕ9x (архитектура ARM Cortex-M3) предоставляет 8 областей для режимя пользователя плюс одну системную область для ядра.

Вариант 1

Общее пространство.

  • для ядра RWX
  • для разделов R

Пространство раздела. Две области на раздел, всего 4 раздела.

  • код RX
  • данные и стек RW

Вариант 2

Общее пространство.

  • для ядра RWX
  • для разделов R

Пространство раздела RWX, и для кода, и для данных, и для стека. Всего 8 разделов.

You can’t perform that action at this time.