Розробка прикладних програм для 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/ukr/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
<code class="cpp">#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 реалізації, загальносистемні бібліотеки.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.