Пишем на языке С/C++ в Windows под KolibriOS

imageKolibriOS — миниатюрная операционная система, ядро и большинство программ которой написано на языке ассемблер. Это, конечно же, не означает, что другим языкам программирования путь в KolibriOS закрыт. К примеру, за время эволюции этой операционной системы было несколько попыток разработать инструментарий или адаптировать библиотеки для создания приложений на языке C/C++. В репозитории KolibriOS до сих пор есть работающие примеры, использующие ранние наработки адаптации C/C++ кода, например (root)/programs/games/kosilka или (root)/programs/system/shell, использующие разные подходы и обертки C/Asm.На текущее время самой перспективной из существующих библиотек, на мой взгляд, является newlib. Она состоит из адаптированной libc, C-оберкой над основными coreAPI функциями и toolchain«а для сборки.

К сожалению, в KolibriOS нативного компилятора C/C++ еще не существует, текущий toolchain предполагает сборку приложений в ОС Windows или Linux.

Данная статья является инструкцией по настройке newlib для ОС Windows.

Установка toolchain

• Архив с актуальным toolchain находится по адресуftp.KolibriOS.org/users/Serge/new/ToolchainWindows-версия архива, msys-kos32-x.x.x.7z• Для установки toolchain нужна mingw/msys, для этого на сайте www.mingw.org по ссылке downloads нужно скачать и запустить файл mingw-get-setup.exeВ появившемся окне после нажатия кнопки «install» нужно выбрать путь установки, оставить галочки напротив »…support for graphics user interface» и нажать «Continue».Внимание, в данной статье предполагается, что установка mingw произведена в c:\MinGWВ появившемся окне нужно отметить mingw32-base и msys-base и начать установку.• После установки перейти в папку c:\MinGW\msys\1.0 и создать в ней дерево папок home\autobuild\tools• Распаковать msys-kos32-x.x.x.7z в c:\MinGW\msys\1.0\home\autobuild\tools (если все сделано правильно, файл kos32-gcc.exe должен находиться по пути c:\MinGW\msys\1.0\home\autobuild\tools\win32\bin\kos32-gcc.exe)• Проверить работоспособность toolchain можно запустив c:\MinGW\msys\1.0\msys.batв командной строке набрать

export PATH=$PATH:/home/autobuild/tools/win32/bin kos32-gcc –v На экране должна появиться информация о конфигурации и версии kos32-gccУстановка libc

• Актуальные компоненты libc находятся в svn репозитории KolibriOS, путь (root)/contrib/sdk/sources/newlibТакже можно воспользоваться веб интерфейсом KolibriOS.org в разделе SVN и скачать соответствующий архив.Внимание, в в данной статье предполагается, что установка newlib произведена в d:\kolibri\contrib\sdk\sources\newlib• После установки перейти в папку d:\kolibri\contrib\sdk и создать в ней папки bin и lib• Запустить c:\MinGW\msys\1.0\msys.bat• в командной строке набрать

cd d:/kolibri/contrib/sdk/sources/newlib/libc export PATH=$PATH:/home/autobuild/tools/win32/bin make shared make install • В результате в папке d:\kolibri\contrib\sdk\bin должен появиться файл libc.dllв папке d:\kolibri\contrib\sdk\lib — libapp.a, libc.dll.a, libdll.aУстановка Qemu

Qemu — система эмуляции (и виртуализации) компьютера, поддерживающего различные архитектуры. Файлы установки Qemu находятся по адресу qemu.weilnetz.de

• Для работы с Qemu нужно скачать «Загрузочный компакт-диск LiveCD» образ KolibriOS по адресу KolibriOS.org/ru/downloadВнимание, в в данной статье предполагается, что образ KolibriOS находится по пути d:/kolibri/dist/kolibri.iso• После установки в рабочей папке (например, d:\work) создать файл qemu.bat

Файл d:/work/qemu.bat

set QEMU_PATH=«c:/Program Files/qemu/» set PATH=%PATH%;%QEMU_PATH% qemu-system-i386.exe -L. -m 128 -cdrom d:/kolibri/dist/kolibri.iso -boot d -localtime -vga vmware -net nic, model=rtl8139 -net user -soundhw ac97 -usb -usbdevice tablet

• Подробнее о ключах запуска KolibriOS на Qemu можно почитать по адресу wiki.KolibriOS.org/wiki/Setting_up_QEMUСоздание приложения

Проверить работоспособность newlib можно, собрав простое приложение, выводящее «hello, world!» в окно и «hello, board!» в отладочную панель.

Файл d:/work/simple.c

#include «stdlib.h» #include «stdio.h» #include «string.h» #include «kos32sys.h»

//---------------------------------------------------------------

static const char *WND_HEADER_STR = «window header»; static const char *HELLO_WORLD_STR = «hello, world!»; static const char *HELLO_BOARD_STR = «hello, board!\n»; static const uint32_t CUSTOM_BUTTON_ID = 100;

//---------------------------------------------------------------

static void RenderWindow (void); static void BoardPuts (const char *c); static void SetMaskForEvents (unsigned int mask);

//---------------------------------------------------------------

void RenderWindow () { const uint32_t WND_STYLE = 3; // (window type III, skinned window) const int WND_X = 100; const int WND_Y = 100; const int WND_W = 320; const int WND_H = 320; const color_t WND_COLOR = 0xffffff;

const int BUTTON_W = 24; const int BUTTON_H = 24; const int BUTTON_X = WND_W / 2 — BUTTON_W — 8; const int BUTTON_Y = (WND_H — BUTTON_H) / 2; const color_t BUTTON_COLOR = 0×9e9e9e;

const color_t TEXT_COLOR = 0xff0000; BeginDraw (); DrawWindow (WND_X, WND_Y, WND_W, WND_H, WND_HEADER_STR, WND_COLOR, WND_STYLE); draw_text_sys (HELLO_WORLD_STR, WND_W / 2, WND_H / 2, strlen (HELLO_WORLD_STR), TEXT_COLOR); DefineButton (65536 * BUTTON_X + BUTTON_W, 65536 * BUTTON_Y + BUTTON_H, CUSTOM_BUTTON_ID, BUTTON_COLOR); EndDraw (); } //---------------------------------------------------------------

// coreAPI #63 asm function call example void BoardPuts (const char *s) { unsigned int i = 0; while (*(s + i)) { asm volatile («int $0×40»:: «a»(63), «b»(1), «c»(*(s + i))); i++; } } //---------------------------------------------------------------

// coreAPI #40 set event mask void SetMaskForEvents (unsigned int mask) { asm volatile («int $0×40»:: «a»(40), «b»(mask)); } //---------------------------------------------------------------

int main () { enum SysEventTypes { REDRAW_EVENT = 1, GUI_BUTTON_EVENT = 3 }; // enabling only REDRAW_EVENT and GUI_BUTTON_EVENT, 0000000000000101b SetMaskForEvents (0×5);

// open BOARD application and check for a text message BoardPuts (HELLO_BOARD_STR); RenderWindow (); for (;;) { const uint32_t e = get_os_event (); switch (e) { case REDRAW_EVENT: { RenderWindow (); } break; case GUI_BUTTON_EVENT: { const uint32_t bt = get_os_button (); if (bt == CUSTOM_BUTTON_ID || bt == 1) // 1 — [x] window button id { return 0; } } break; } } return 0; } //---------------------------------------------------------------

Файл d:/work/Makefile EXEC = simple CC = kos32-gcc LD = kos32-ld OBJCOPY = kos32-objcopy

SDK_DIR:= /d/kolibri/contrib/sdk LDFLAGS = -static -S -nostdlib -T$(SDK_DIR)/sources/newlib/app.lds -Map $(EXEC).map --image-base 0 CFLAGS = -c -O2 -fomit-frame-pointer -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32

INCLUDES= -I$(SDK_DIR)/sources/newlib/libc/include LIBPATH:= -L$(SDK_DIR)/lib -L/home/autobuild/tools/win32/mingw32/lib

export PATH=$PATH:/home/autobuild/tools/win32/bin:/MinGW/bin

default: $(EXEC)

$(EXEC):$(EXEC).o makefile $(LD) $(LDFLAGS) $(LIBPATH) -o $(EXEC) *.o -lgcc -lapp -lc.dll $(OBJCOPY) $(EXEC) -O binary

%.o: %.c makefile $(CC) $(CFLAGS) $(INCLUDES) -o $@ $<

Для сборки приложения нужно запустить c:\MinGW\msys\1.0\msys.batв командной строке набрать cd d:/work make Результатом выполнения будет исполняемый в KolibriOS файл «simple«Перенос файлов между Windows и KolibriOS

Самый простой способ переносить файлы между Windows и KolibriOS — это flash-usb накопитель.Еще один способ, при использовании Qemu — создать образ диска и подключить его как hdd. В этом случае qemu.bat дополняется еще одним ключом, -hda d:\work\c100.img, где c100.img — имя образа. Образ должен быть уже отформатированным, поэтому его лучше не создавать, а снять с небольшого по объему flash-usb накопителя с помощью утилиты Win32DiskImager.exeРедактировать образ можно с помощью WinImage.

Если при загрузке KolibriOS содержимое /hd0/1 диска пустое, нужно перезагрузить систему и в предложенном меню загрузки выбрать пункт »[b] Добавить диски, видимые через BIOS», и включить эту опцию (1)

Известные проблемы

По умолчанию, приложения, собранные с newlib требуют наличия файла /KolibriOS/lib/libc.dll в KolibriOS.При использовании Qemu из-за этого могут возникнуть проблемы с «минимальной» версией kolibri.img.Решений данной проблемы две:

• Использовать iso-версию (Загрузочный компакт-диск LiveCD)Если приложение «simple» при запуске выдает ошибку, скорей всего на образе старая версия libc.dll. Обычно на уже указанном выше ftp.KolibriOS.org/users/Serge/new/Toolchain можно найти самые последние библиотеки в архиве sdk.zip. Простой способ обновить библиотеки на образе — воспользоваться утилитой MagicISO.

• Воспользоваться встроенным функционалом KolibriOS «searchapp»: — в корень подключаемого диска (flash-usb накопитель, образ диска *.img) нужно скопировать kolibri.lbl из d:\kolibri\dist\kolibri.iso (kolibri.iso можно распаковать архиватором 7z или winrar, kolibri.lbl лежит в корне)— в корне того же подключаемого диска создать дерево папок kolibrios/lib— в папку /kolibrios скопировать исполняемый файл («simple»)— в папку /kolibrios/lib скопировать libc.dll из d:\kolibri\contrib\sdk\bin

Полезные ссылки

Все header-файлы оберток и адаптированных библиотек находятся в (kolibri)\contrib\sdk\sources\newlib\libc\include

Описание системных функций (пример работы с coreAPI в примере simple.c, функция board_puts)

Ветка форума, посвященная newlib

Файловый архив по данной статье• в папке _kos содержатся готовые файлы для запуска в KolibriOS• в папке _win32 содержатся image/c100.img (образ диска для Qemu с собранным «simple»), makefile, qemu.bat, simple.c

P.S. Выражаю огромную благодарность наставнику Sourcerer за терпение, помощь и советы!

image

© Habrahabr.ru