Pull to refresh

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

Reading time 7 min
Views 22K
image
KolibriOS – миниатюрная операционная система, ядро и большинство программ которой написано на языке ассемблер. Это, конечно же, не означает, что другим языкам программирования путь в 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/Toolchain
Windows-версия архива, msys-kos32-x.x.x.7z
• Для установки toolchain нужна mingw/msys, для этого на сайте sourceforge.net/projects/mingw нужно скачать и запустить файл 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 репозитории svn://kolibrios.org, путь (root)/contrib/sdk/sources/newlib
Также можно воспользоваться веб интерфейсом KolibriOS.org в разделе SVN и скачать соответствующий архив.
Внимание, в в данной статье предполагается, что установка newlib произведена в c:\kolibri\contrib\sdk\sources\newlib
• После установки перейти в папку c:\kolibri\contrib\sdk и создать в ней папку bin если ее нет
• Скачать и FASM, сайт flatassembler.net
Внимание, в данной статье предполагается, что FASM установлен в c:\kolibri\fasm
• Запустить c:\MinGW\msys\1.0\msys.bat
• в командной строке набрать
	cd c:/kolibri/contrib/sdk/sources/newlib/libc
	export PATH=$PATH:/home/autobuild/tools/win32/bin
	export PATH=$PATH:/c/kolibri/fasm
	make shared
	make install

• В результате в папке c:\kolibri\contrib\sdk\bin должен появиться файл libc.dll

Установка Qemu

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

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

Файл c:\work\kolibri\qemu.bat
	set QEMU_PATH="c:/Program Files/qemu/"
	set PATH=%PATH%;%QEMU_PATH%
	qemu-system-i386.exe -L . -m 128 -cdrom c:/kolibri/dist/kolibri.iso -boot d -rtc base=localtime -vga vmware -net nic,model=rtl8139 -net user -soundhw ac97 -usb -device usb-tablet


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

Создание приложения

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

Файл c:\work\kolibri\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 = 0x9e9e9e;	

	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);
	define_button(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 $0x40"::"a"(63), "b"(1), "c"(*(s + i)));
		i++;
	}
}
//---------------------------------------------------------------

// coreAPI #40 set event mask
void SetMaskForEvents(unsigned int mask)
{
	asm volatile ("int $0x40"::"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(0x5);

	// 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;
}
//---------------------------------------------------------------


Файл c:\work\kolibri\Makefile

APPNAME = simple
    
CC = kos32-gcc
LD = kos32-ld
OBJCOPY = kos32-objcopy

KOS32_SDK_DIR = /c/kolibri/contrib/sdk

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

INCLUDE_PATH = -I$(KOS32_SDK_DIR)/sources/newlib/libc/include
LIB_PATH = -L$(KOS32_SDK_DIR)/lib -L/home/autobuild/tools/win32/mingw32/lib -L/home/autobuild/tools/win32/lib

LD_FLAGS = -static -S -nostdlib -T$(KOS32_SDK_DIR)/sources/newlib/app.lds -Map $(APPNAME).map --image-base 0
CFLAGS = -c -O2 -fomit-frame-pointer -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32 $(INCLUDE_PATH)

default: $(APPNAME)

$(APPNAME):$(APPNAME).o makefile
	$(LD) $(LD_FLAGS) $(LIB_PATH) -o $(APPNAME) *.o -lgcc -lc.dll
	$(OBJCOPY) $(APPNAME) -O binary

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


Для сборки приложения нужно запустить c:\MinGW\msys\1.0\msys.bat
в командной строке набрать
cd c:/work/kolibri
make

Результатом выполнения будет исполняемый в KolibriOS файл «simple»

Важно:
Для сборки с++ проекта нужно использовать компилятор kos32-gcc и другие либы:
Пример
$(LD) $(LDFLAGS) $(LIBPATH) -o $(EXEC) *.o -lstdc++ -lsup++ -lgcc -lc.dll

Перенос файлов между 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
Tags:
Hubs:
+36
Comments 4
Comments Comments 4

Articles