Опустим вопрос, зачем это нужно. Это одна из немногих компактных операционных систем open source с поддержкой русского языка, которые шагнули дальше концептуальной версии.
Что нужно для начала разработки для Колибри ОС (КОС)?
Источниками информации для вас будут (начало тут):
- Форум, чтобы знать в каком направлении двигаться;
- Вики, хотя к сожалению достаточно фрагментирована, но даст необходимый минимум обзорной информации;
- Исходные тексты программ в хранилище Subversion (SVN);
- Справочник по системным функциям на русском и английском языке SVN:/kernel/trunk/docs/sysfunc*.txt, или на Вики;
Чем пользоваться для разработки и что для этого нужно:
- Подготовить рабочую среду или машину для запуска системы. Можно работать и на живом железе (возможно с проблемами поддержки оборудования). Лично я запускаю ОС в бесплатном для некоммерческого использования 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 поддерживается).
- Ассемблер FASM, и редактор Tinypad идут в комплекте установленной системы, что естественно для системы, написанной на Ассемблере. Прямо из редактора можно открыть справочник по системным функциям, доску отладочных сообщений Board, оттранслировать программу и запустить ее независимо либо в системном отладчике Mtdbg. Пример программы тоже есть в ISO-образе, еще можно смотреть программы на SVN по пути SVN:/programs/demos.
- C--. Второй родной язык для этой системы, на котором написаны многие системные утилиты. Похож на С, но вместо стандартной С-библиотеки использует прямые системные вызовы и позволяет работать с регистрами процессора напрямую, за счет чего программа получается компактнее. Лежит тут, примеры программ, весьма кстати приятно написанных – SVN:/programs/cmm. Библиотека SVN:/programs/cmm/lib. Имеется работающий в Колибри и кросс компилятор для Windows. О нем есть более подробная статья на Хабре от Punk_Joker
- Кросс компилятор 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
- Простой компилятор 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
Здесь все проще, поскольку компилятор модифицирован специально для Колибри.
Более экзотичные варианты, но которые могут показаться вам удобными:
- Использовать другие С-компиляторы или языки согласно этой статье.
При рассмотрении примеров программ на С прошу особо обратить внимание, что в системе в разных программах используются разные варианты 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”
- Использовать Oberon. Это как стандартный Pascal, только лучше, а по синтаксису проще чем Object Pascal (Delphi). Описание языка занимает всего 13 страниц. Компилятор и документация тут, примером использования является fbreader. Кстати, пока эта статья готовилась, автор компилятора уже сделал статью про использование Оберона. Ожидайте скоро.
- Имеются также порты 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 встроено в ядро, то стандартная заготовка оконной программы очень простая.
; Простой пример программы для 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
#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 реализации, общесистемные библиотеки.
Автор: KolibriOS Project Team