Разработка прикладных приложений для KolibriOS. Обзор вариантов

от автора

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

Что нужно для начала разработки для Колибри ОС (КОС)?

Источниками информации для вас будут (начало тут):

  • Форум, чтобы знать в каком направлении двигаться;
  • Вики, хотя к сожалению достаточно фрагментирована, но даст необходимый минимум обзорной информации;
  • Исходные тексты программ в хранилище Subversion (SVN);
  • Справочник по системным функциям на русском и английском языке SVN:/kernel/trunk/docs/sysfunc*.txt, или на Вики;

Чем пользоваться для разработки и что для этого нужно:

  1. Подготовить рабочую среду или машину для запуска системы. Можно работать и на живом железе (возможно с проблемами поддержки оборудования). Лично я запускаю ОС в бесплатном для некоммерческого использования VMware Player, но Колибри работает и в QEMU и в VirtualBox, и в Bochs эмуляторе.

    Установить SVN-клиент по выбору – например для командной строки есть SlikSVN, визуальные RapidSVN, SubTile (нужен Firefox runtime), а есть в виде расширения Windows Exporer TortoiseSVN.
    Полный учебник по работе с SVN ищем в сети, приведу здесь примеры типовых команд для SlikSVN, находясь в нужном каталоге:

    >svn co svn://kolibrios.org/contrib/sdk sdk — получить себе актуальную копию;
    >svn status --show-updates — просмотреть измененные по сравнению с сервером файлы;
    >svn up — обновить свою копию с сервера;
    >svn add *.c — добавить все новые c-файлы под контроль;
    >svn commit --username XXXX --password YYYY -m "метка билда" — загрузить на сервер свои изменения (сначала не забыв проанализировать status);

    Для загрузки исходных текстов с SVN пароль не требуется. Можно для просмотра кода Колибри и приложений пользоваться Web-возможностями сервера SVN, но в нем не видно русскоязычных комментариев в кодировке CP1251 (CP866 поддерживается).

  2. Ассемблер FASM, и редактор Tinypad идут в комплекте установленной системы, что естественно для системы, написанной на Ассемблере. Прямо из редактора можно открыть справочник по системным функциям, доску отладочных сообщений Board, оттранслировать программу и запустить ее независимо либо в системном отладчике Mtdbg. Пример программы тоже есть в ISO-образе, еще можно смотреть программы на SVN по пути SVN:/programs/demos.
  3. C—. Второй родной язык для этой системы, на котором написаны многие системные утилиты. Похож на С, но вместо стандартной С-библиотеки использует прямые системные вызовы и позволяет работать с регистрами процессора напрямую, за счет чего программа получается компактнее. Лежит тут, примеры программ, весьма кстати приятно написанных – SVN:/programs/cmm. Библиотека SVN:/programs/cmm/lib. Имеется работающий в Колибри и кросс компилятор для Windows. О нем есть более подробная статья на Хабре от Punk_Joker
  4. Кросс компилятор C/C++ GCC. Хостом может служить Linux или Windows. Лежит тут, нужно скачать msys-kos32 либо linux-kos32 и SDK с готовыми С-библиотеками для КОС. Кое-какие требуемые для запуска GCC dll под Windows, возможно придется подгрузить отдельно со страницы mingw, если у вас на машине еще его нет. Использует модифицированную для КОС библиотеку newlib, которую нужно скачать с SVN:/contrib/sdk/sources/newlib (рядом лежит и libstdc++-v3). В SDK имеется предсобранная libc.dll для динамической загрузки, а для статической компоновки библиотеку придется собрать самому.

    Единственное неудобство кросс-компиляции – нужно каждый раз копировать полученную программу в систему. Варианты – или через FTP если сервер заработает с вашей сетевой картой, или через USB-флэшку, или модифицируя ISO-образ системы (например с помощью Magic ISO Maker) и перезапуская ее. По этому компилятору есть статья на Хабре от pascualle, из которой можно взять makefile. В ближайшей перспективе (уже в тесте) выпуск порта версии gcc 5.4 от ion2

  5. Простой компилятор TinyC в виде родного и кросс-компилятора для Windows (можно собрать и для Linux). Взять полный комплект с примерами тут, проще всего его копировать вместе с программой в Колибри и там использовать. Поддерживает только чистый С, с поддержкой некоторых расширений языка от GCC, например атрибутов и ассемблерных вставок.

Чем пользоваться в качестве редактора при кросс-компиляции? Ваше личное дело, я прописал отдельный toolchain в CodeBlocks.

Компиляция и отладка

Для С отсутствует отладчик исходного кода, потому приходится использовать системный Mtdbg.

Для некоторого удобства можно компилироваться с .map файлом для gcc и с отладочным файлом для tcc – это даст в отладчике подсказку в виде имен функций и частично строк исходника для tcc.

Для GCC поддерживается статическая и динамическая линковка – потому два варианта makefile. Не забудьте при динамической линковке в образ системы в /lib сложить libc.dll и stdlibc++.dll (в ISO версии системы сразу присутствуют)

Примеры строк компиляции для отладки:

  • gcc (статическая libc) — строки сложные, потому лучше использовать готовые makefile

    >kos32-gcc -c -g -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 -I $(SDK_DIR)/sources/newlib/libc/include -o hello hello.cpp — обычная компиляция

    >kos32-ld -static -nostdlib -T $(SDK_DIR)/sources/newlib/static.lds -Map=hello.map -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib -o hello hello.o -lstdc++ -lsupc++ -lgcc_eh -lc -lapp -lgcc -lc — линковка с нужным для Колибри форматом файла и созданием .map -файла для отладчика

    >kos32-objdump -d -M intel -S hello.o > hello.asm — создание ассемблерного файла со строками исходного cpp файла для удобства
    >kos32-objcopy hello -O binary — обрезание лишнего и генерация исполняемого файла Колибри

    Немного сложно, но в итоге по map файлу мы можем смотреть физические адреса данных и функций и видеть соответствие ассемблерного и С-кода.

  • GCC (libc в виде .dll) — отличие от статической сборки только в строке линковки:

    >kos32-ld -static -S -nostdlib -T $(SDK_DIR)/sources/newlib/app.lds --image-base 0 -Map=hello.map -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib -o hello hello.o -lstdc++ -lsupc++ -lgcc_eh -lc.dll -lapp -lgcc -lc.dll

  • TinyC

    > tcc hello.c -o hello -lck -g

    Здесь все проще, поскольку компилятор модифицирован специально для Колибри.

Более экзотичные варианты, но которые могут показаться вам удобными:

  1. Использовать другие С-компиляторы или языки согласно этой статье.
    При рассмотрении примеров программ на С прошу особо обратить внимание, что в системе в разных программах используются разные варианты libс, разработанные в разные исторические эпохи, отличающиеся вызовами системного API:
    • старая menuetlibc, унаследованная от прародительницы menuetOS, <menuet/os.h>, выделяется префиксом функций __menuet, является портом DJGPP. Достаточно часто используется с GCC, хотя я бы счел ее устаревшей и советовал использовать новую newlibc <kos32sys.h>.
    • У tcc своя упрощенная libck, но вызовы API <kos32sys1.h> унифицированы с GCC. Хотя есть еще старая tcc-версия <kolibrisys.h>, ее я лично не тестировал.
    • минимальный набор функций для MSVC. Определяется по файлам «kosSyst.h», «KosFile.h». Устарел
    • минимальный набор функций для для BCC “menuet.h”
    • довольно полная библиотека для WatcomC “kolibri.h”

  2. Использовать Oberon. Это как стандартный Pascal, только лучше, а по синтаксису проще чем Object Pascal (Delphi). Описание языка занимает всего 13 страниц. Компилятор и документация тут, примером использования является fbreader. Кстати, пока эта статья готовилась, автор компилятора уже сделал статью про использование Оберона. Ожидайте скоро.
  3. Имеются также порты PascalPro, возможность использования FreePascal, TinyPy, Lua, Forth, Basic разной степени готовности. Возможно, эти темы будут раскрыты отдельными статьями.

Подробнее по созданию прикладных программ

Разработка консольных приложений:

В системе отсутствует поддержка консольных приложений через системное API, это как ни странно система с графическим интерфейсом, если вы заметили. Создание таких приложений возможно с использованием системной же библиотеки console.obj, с документацией SVN:/programs/develop/libraries/console. Пример использования на ассемблере – там же examples.

Небольшое отступление – в Колибри формат .obj это не обычный объектный файл для линкера, а динамически загружаемая библиотека формата COFF, с сформированной специальным образом таблицей экспорта. В каждой программе необходимо выполнить ее загрузку через системное API и связывание явным образом. GCC также поддерживает загрузку .dll формата PE.

Для GCC использование консоли для стандартных функций встроено в С-библиотеку libc.

Для TinyC тоже возможно использование libck, но также имеется уменьшенные по размеру кода функции tiny_printf и прямая обертка над console.obj в виде conio.h

Нюансом для КолибриОС является отсутствие потоков ввода-вывода и их перенаправления, потому написать что то типа cat a.txt > aaa.txt | more не получится.

Для взаимодействия консольных программ есть 4 способа:

  • использовать функции shell.c
  • использовать API для IPC (interprocess communication), SysFn 60
  • использовать API для Shared Memory, SysFn 68.22
  • использовать API для буфера обмена Clipboard, SysFn 54.1

Также при использовании console.obj ваше приложение будет состоять из двух одноименных процессов, не пугайтесь.

Разработка графических приложений:

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

В настоящий момент для разработки графических приложений можно использовать системные вызовы, библиотеку виджетов box_lib и gui.h для C—. Для C тоже выполнена обвязка box_lib, частично в рамках GSoC 2016, расширение GUI-библиотеки запланировано на осень 2016.

Поскольку оконное GUI встроено в ядро, то стандартная заготовка оконной программы очень простая.

SVN:/programs/develop/examples/example/trunk/rus/example.asm

; Простой пример программы для KolibriOS
; озвучивает код нажатой клавиши
;
; Компилировать FASM'ом
; Можно открыть example.asm через программу FASM (её ярлык есть
; на рабочем столе)
; А можно просто нажать F9 в Tinypad'е. Лог компиляции
; отображается на доске отладки (программа BOARD)
;
; Что важно знать при программировании под Колибри:
; Номер функции помещается в регистр eax.
; Вызов системной функции осуществляется командой "int 0x40".
; Все регистры, кроме явно указанных в возвращаемом значении,
; включая регистр флагов eflags, сохраняются.
;
; Пример:
; mov eax, 1 ;Функция 1 - поставить точку в окне
; ;список сисфункций см. в DOCPACK - sysfuncr.txt
; mov ebx, 10 ; координата x=10
; mov ecx, 20 ; координата y=10
; mov edx, 0xFFFfff ;цвет точки
; int 0x40 ;вызвать функцию
;
; Тоже самое с использованием макроса:
; mcall 1, 10, 20, 0xFFFfff
;---------------------------------------------------------------------

use32 ; включить 32-битный режим ассемблера
org 0x0 ; адресация с нуля

db 'MENUET01' ; 8-байтный идентификатор MenuetOS
dd 0x01 ; версия заголовка (всегда 1)
dd START ; адрес первой команды
dd I_END ; размер программы
dd 0x1000 ; количество памяти
dd 0x1000 ; адрес вершины стэка
dd 0x0 ; адрес буфера для параметров
dd 0x0 ; зарезервировано

include "macros.inc" ; макросы облегчают жизнь ассемблерщиков!

;---------------------------------------------------------------------
;--- НАЧАЛО ПРОГРАММЫ ----------------------------------------------
;---------------------------------------------------------------------

START:

red: ; перерисовать окно

call draw_window ; вызываем процедуру отрисовки окна

;---------------------------------------------------------------------
;--- ЦИКЛ ОБРАБОТКИ СОБЫТИЙ ----------------------------------------
;---------------------------------------------------------------------

still:
mcall 10 ; функция 10 - ждать события

cmp eax,1 ; перерисовать окно ?
je red ; если да - на метку red
cmp eax,2 ; нажата клавиша ?
je key ; если да - на key
cmp eax,3 ; нажата кнопка ?
je button ; если да - на button

jmp still ; если другое событие - в начало цикла

;---------------------------------------------------------------------

key: ; нажата клавиша на клавиатуре
mcall 2 ; функция 2 - считать код символа (в ah)

mov [Music+1], ah ; записать код символа как код ноты

; функция 55-55: системный динамик ("PlayNote")
; esi - адрес мелодии

; mov eax,55
; mov ebx,eax
; mov esi,Music
; int 0x40

; или коротко:
mcall 55, eax, , , Music

jmp still ; вернуться к началу цикла

;---------------------------------------------------------------------

button:
mcall 17 ; 17 - получить идентификатор нажатой кнопки

cmp ah, 1 ; если НЕ нажата кнопка с номером 1,
jne still ; вернуться

.exit:
mcall -1 ; иначе конец программы

;---------------------------------------------------------------------
;--- ОПРЕДЕЛЕНИЕ И ОТРИСОВКА ОКНА ----------------------------------
;---------------------------------------------------------------------

draw_window:

mcall 12, 1 ; функция 12: сообщить ОС о начале отрисовки

mcall 48, 3, sc,sizeof.system_colors

; далее: сначала длинный вариант (закомментированный)
; затем короткий аналог с использованием макросов

; mov eax,0 ; функция 0: определить окно
; mov ebx,200*65536+300 ; [x старт] *65536 + [x размер]
; mov ecx,200*65536+150 ; [y старт] *65536 + [y размер]
; mov edx, [sc.work] ; цвет фона
; or edx, 0x33000000 ; и тип окна 3
; mov edi,header ; ЗАГОЛОВОК ОКНА
; int 0x40

mov edx, [sc.work] ; цвет фона
or edx, 0x33000000 ; и тип окна 3
mcall 0, <200,300>, <200,150>, , ,title

; вывод текстовой строки
mov ecx, [sc.work_text] ; цвет фона
or ecx, 0x90000000 ; и тип строки
mcall 4, <10, 20>, 0x90000000, message

mcall 12, 2 ; функция 12.2, закончили рисовать

ret ; выходим из процедуры

;---------------------------------------------------------------------
;--- ДАННЫЕ ПРОГРАММЫ ----------------------------------------------
;---------------------------------------------------------------------

; Вот такая вот короткая "мелодия".
; Второй байт изменяется нажатием клавишы

Music:
db 0x90, 0x30, 0

sc system_colors

message db 'Нажмите любую клавишу...',0
title db 'Пример программы',0

;---------------------------------------------------------------------

I_END: ; метка конца программы

Примеры для Ассемблера использования box_lib.

SVN:/programs/develop/libraries/box_lib/asm/trunk/ctrldemo.asm и editbox_ex.asm

Пример для C—. SVN:/programs/cmm/examples/window.c

#define MEMSIZE 4096*10   #include "../lib/io.h" #include "../lib/gui.h"   void main() {         word id;         dword file;         io.dir.load(0,DIR_ONLYREAL);         loop() switch(WaitEvent())         {                 case evButton:                         id=GetButtonID();                                       if (id==1) ExitProcess();                         break;                           case evKey:                         GetKeys();                         if (key_scancode == SCAN_CODE_ESC ) ExitProcess();                         break;                                   case evReDraw:                         draw_window();                         break;         } } void draw_window() {         proc_info Form;         int i;         DefineAndDrawWindow(215,100,350,300,0x34,0xFFFFFF,"Window header");         GetProcessInfo(#Form, SelfInfo);         for (i=0; i<io.dir.count; i++)         {                 WriteText(5,i*8+3,0x80,0xFF00FF,io.dir.position(i));         }         DrawCaptButton(100, 10, 100, 22, 22, 0xCCCccc, 0x000000, "Button");         WriteText(100,50,0x80,0,"Textline small");         WriteText(100,70,0x90,0,"Textline big");         DrawBar(100, 110, 100, 100, 0x66AF86); } 

Примеры для gcc/tcc:
» svn:/programs/develop/libraries/newlib_example/
» svn:/programs/develop/ktcc/trunk/samples/
» Примеры использования box_lib из C: SVN:/contrib/C_Layer/EXAMPLE/

Компиляция как указана выше, для GCC линковать приложение нужно с ключиком --subsystem windows (или --subsystem native), если у вас не используется консольное окно.

Перечень библиотек можно посмотреть на Wiki. Это и работа с изображениями, и со шрифтами, OpenGL реализации, общесистемные библиотеки.
ссылка на оригинал статьи https://habrahabr.ru/post/313772/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *