Writing applications for KolibriOS: Difference between revisions

From KolibriOS wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
= Structure of an application =
= Structure of an application =


Programming for KolibriOS is easy as you first learn the basic structure of an application. At this point I assume you have some experience in assembly language. The KolibriOS API (Application Programming Interface) is a easy-to-learn set of functions with practically no hierarchial accesses.
KolibriOS's application structure is not specifically reserved for asm programming, the header can be produced with practically any other language. However, the overall application programming design is intended for easy 32 bit asm programming. The GUI is extremely easy to handle with especially asm language.
 
Programming for KolibriOS is easy as you first learn the basic structure of an application. At this point I assume you have some experience in assembly language.<br>
The KolibriOS API (Application Programming Interface) is an easy-to-learn set of functions with practically no hierarchical accesses.


The operating of an application is based on events. The application is notified by the OS with the event type and the application acts accordingly. There are three event types an application is expected to handle by default: window redraw, keypress and buttonpress.
The operating of an application is based on events. The application is notified by the OS with the event type and the application acts accordingly.<br>
There are three event types an application is expected to handle by default: window redraw, keypress and buttonpress.


Flow chart and structure of an application with default events:
Flow chart and structure of an application with default events:
Line 52: Line 56:
</syntaxhighlight>
</syntaxhighlight>


Since KolibriOS still is more or less API compatible with MenuetOS, it has the same header. There is also an older version of the header wich uses 'MENUET00' but it should not be used anymore.
Since KolibriOS still is more or less API compatible with MenuetOS, it has the same header. There is also an older version of the header which uses 'MENUET00', but it should not be used anymore.


<syntaxhighlight>
<syntaxhighlight>
Line 70: Line 74:
</syntaxhighlight>
</syntaxhighlight>


This is the total size of the program code in bytes, its easy to use a label wich you place at the end of the code.
This is the total size of the program code in bytes, its easy to use a label which you place at the end of the code.


<syntaxhighlight>
<syntaxhighlight>
Line 88: Line 92:
</syntaxhighlight>
</syntaxhighlight>


If you want to use parameters, this should be a pointer to a 1024 byte buffer, in wich those parameters will be written by the kernel. If you dont want to use them, set this dword to 0.
If you want to use parameters, this should be a pointer to a 1024 byte buffer, in which those parameters will be written by the kernel. If you don't want to use them, set this dword to 0.


<syntaxhighlight>
<syntaxhighlight>
Line 98: Line 102:
= System calls =
= System calls =


The System calls (API) are explained in various sources. There is the file syscalls.txt wich you can find in kolibrios itself, but also in the zip file of the distribution.< If you understand russian, you can also find system calls on this wiki.
The System calls (API) are explained in various sources. There is the file syscalls.txt which you can find in KolibriOS itself, but also in the zip file of the distribution.< If you understand russian, you can also find system calls on this wiki.


To execute a system call, you first need to fill the registers with the correct value. Say we want to wait a couple of milliseconds, we need to use system function 5 and place the time we want to wait in ebx.
To execute a system call, you first need to fill the registers with the correct value. Say we want to wait a couple of milliseconds, we need to use system function 5 and place the time we want to wait in ebx.
Line 113: Line 117:
</syntaxhighlight>
</syntaxhighlight>


But also with more modern instructions such as syscall, sysenter etc. It's convenient to use the mcall macro from macros.inc, then you can chose to use int 0x40 or another method, at compile time. This macro also accepts parameters, first is eax, second is ebx, ... Code for the above would be:
But also with more modern instructions such as syscall, sysenter etc. It's convenient to use the mcall macro from macros.inc, then you can choose to use int 0x40 or another method, at compile time. This macro also accepts parameters, first is eax, second is ebx, ...<br> Code for the above would be:


<syntaxhighlight>
<syntaxhighlight>
Line 121: Line 125:
= Coding Style =
= Coding Style =


It's adviseable to use the coding style, as descibed here: [[Style]]
It's advisable to use the coding style, as described here: [[Style]]


= The API =
= The API =
You can find the latest API documention in /kernel/docs/ in the SVN repository ([http://websvn.kolibrios.org/listing.php?repname=Kolibri+OS&path=%2Fkernel%2Ftrunk%2Fdocs%2F WebSVN])  
You can find the latest API documentation in /kernel/docs/ in the SVN repository ([http://websvn.kolibrios.org/listing.php?repname=Kolibri+OS&path=%2Fkernel%2Ftrunk%2Fdocs%2F WebSVN])<br>
Inside KolibriOS, you can find sysfuncs.txt (english version) or sysfuncr (russian version) in DOCKPACK program.<br>
These files also come with the so called distribution kit, in documents folder.


= Assembly examples =
= Assembly examples =
Some examples are listed on this page, more can be found on the SVN server in the folder /programs/develop/examples/ ([http://websvn.kolibrios.org/listing.php?repname=Kolibri+OS&path=%2Fprograms%2Fdevelop%2Fexamples%2F WebSVN])


== Simple example ==
== Simple example ==
Line 139: Line 147:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; The header
format binary as ""                    ; Binary file format without extenstion


use32                                  ; Tell compiler to use 32 bit instructions
use32                                  ; Tell compiler to use 32 bit instructions


org 0x0                                ; the base address of code, always 0x0
org 0x0                                ; the base address of code, always 0x0
; The header


db 'MENUET01'
db 'MENUET01'
Line 289: Line 299:


[[Image:Example_1.png]]
[[Image:Example_1.png]]
KolibriOS's application structure is not specifically reserved for asm programming, the header can be produced with practically any other language. However, the overall application programming design is intended for easy 32 bit asm programming. The GUI is extremely easy to handle with especially asm language.


== Using uniform system colours ==
== Using uniform system colours ==
Line 298: Line 306:
You can use uniform desktop colors defined by a colour setup application.
You can use uniform desktop colors defined by a colour setup application.


New fuction in this example is get_system_colours.
New function in this example is get_system_colours.


<syntaxhighlight>
<syntaxhighlight>
Line 309: Line 317:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; The header
format binary as ""               
 
use32
use32
org 0x0


org 0x0
; The Header


db 'MENUET01'
db 'MENUET01'
Line 467: Line 475:
== Freeform window ==
== Freeform window ==


In this example we concentrate on shaping the window from rectangle to any form desired by the programmer. New fuction in this example is shape_window.
In this example we concentrate on shaping the window from rectangle to any form desired by the programmer. New function in this example is shape_window.


<syntaxhighlight>
<syntaxhighlight>
Line 478: Line 486:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; The header
format binary as ""                   


use32
use32


org 0x0
org 0x0
; The Header


db 'MENUET01'
db 'MENUET01'
Line 581: Line 591:


draw_window:
draw_window:
         mcall  12, 1                  ; notice os about start of redraw
         mcall  12, 1                  ; notice OS about start of redraw


         mov    eax, 0                  ; function 0: define and draw window
         mov    eax, 0                  ; function 0: define and draw window
Line 614: Line 624:
== Threads ==
== Threads ==


KolibriOS assembly threading has some great advantages over higher level languages. If you keep all the variables in registers, you can start as meny threads as desired with the _same_ code, since no memory is affected and needs no saving. The registers are saved to Task Switch Segments by KolibriOS. All you have to do is to set a new stack.
KolibriOS assembly threading has some great advantages over higher level languages. If you keep all the variables in registers, you can start as many threads as desired with the _same_ code, since no memory is affected and needs no saving. The registers are saved to Task Switch Segments by KolibriOS. All you have to do is to set a new stack.


Threads have no difference with the main process and use the same memory area as the process which starts it. They can have their own independent windows etc. In the closing of application, all threads have to be terminated with the default (eax = -1) system call.
Threads have no difference with the main process and use the same memory area as the process which starts it. They can have their own independent windows etc. In the closing of application, all threads have to be terminated with the default (eax = -1) system call.
Line 629: Line 639:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


format binary as ""                 
use32
use32
org 0x0
org 0x0


Line 684: Line 694:
;
;
; All we have to do is to give the thread entry address in ecx and
; All we have to do is to give the thread entry address in ecx and
; a new stack postition in edx with function eax=51, ebx=1
; a new stack position in edx with function eax=51, ebx=1


create_thread:
create_thread:
Line 836: Line 846:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


format binary as ""                 
use32
use32
org 0x0
org 0x0



Latest revision as of 20:07, 18 March 2014

Structure of an application

KolibriOS's application structure is not specifically reserved for asm programming, the header can be produced with practically any other language. However, the overall application programming design is intended for easy 32 bit asm programming. The GUI is extremely easy to handle with especially asm language.

Programming for KolibriOS is easy as you first learn the basic structure of an application. At this point I assume you have some experience in assembly language.
The KolibriOS API (Application Programming Interface) is an easy-to-learn set of functions with practically no hierarchical accesses.

The operating of an application is based on events. The application is notified by the OS with the event type and the application acts accordingly.
There are three event types an application is expected to handle by default: window redraw, keypress and buttonpress.

Flow chart and structure of an application with default events:

<syntaxhighlight>

;
HEADER DATA  ;
;

START:

       call    draw_window
;
WAIT UNTIL EVENT  ; <-----------------------------------------------I
; I
I
I
I
; redraw -> call draw_window -> I
READ EVENT TYPE  ; -> key -> read keypress -> process -> I
; button -> read buttonpress -> process -> I

draw_window:

;
DRAW STATIC WINDOW PARTS  ;
;
       ret
;
STATIC DATA  ;
;

</syntaxhighlight>

The header

<syntaxhighlight> db 'MENUET01' </syntaxhighlight>

Since KolibriOS still is more or less API compatible with MenuetOS, it has the same header. There is also an older version of the header which uses 'MENUET00', but it should not be used anymore.

<syntaxhighlight> dd 0x01 ; header version </syntaxhighlight>

Speaks for itself.

<syntaxhighlight> dd START ; start of execution </syntaxhighlight>

START is the label in your program where kernel will jump to after loading the program. You could use another name, but it's convenient to always use the same.

<syntaxhighlight> dd I_END ; size of image </syntaxhighlight>

This is the total size of the program code in bytes, its easy to use a label which you place at the end of the code.

<syntaxhighlight> dd 0x100000 </syntaxhighlight>

This is the amount of ram that will be reserved for your app. You could use a static value as shown here, or you could use I_END + xx bytes. There, I_END would be the label to the end of code + all static declarations you made after the code. The xx bytes then are the number of bytes you want to use for the stack. Also note, this value can later be changed by using system functions.

<syntaxhighlight> dd 0x100000 ; stack position in memory area </syntaxhighlight>

Where the end of stack is (the value of esp at start of program). Logically, this would be the same as the previous value.

<syntaxhighlight> dd 0x0 ; Parameters </syntaxhighlight>

If you want to use parameters, this should be a pointer to a 1024 byte buffer, in which those parameters will be written by the kernel. If you don't want to use them, set this dword to 0.

<syntaxhighlight> dd 0x0 ; Path </syntaxhighlight>

Path value, works the same as parameter.

System calls

The System calls (API) are explained in various sources. There is the file syscalls.txt which you can find in KolibriOS itself, but also in the zip file of the distribution.< If you understand russian, you can also find system calls on this wiki.

To execute a system call, you first need to fill the registers with the correct value. Say we want to wait a couple of milliseconds, we need to use system function 5 and place the time we want to wait in ebx.

<syntaxhighlight>

       mov     eax, 5
       mov     ebx, 10

</syntaxhighlight>

Now, we need to execute the function, this can be done with int 0x40:

<syntaxhighlight>

       int     0x40

</syntaxhighlight>

But also with more modern instructions such as syscall, sysenter etc. It's convenient to use the mcall macro from macros.inc, then you can choose to use int 0x40 or another method, at compile time. This macro also accepts parameters, first is eax, second is ebx, ...
Code for the above would be:

<syntaxhighlight>

       mcall   5, 10

</syntaxhighlight>

Coding Style

It's advisable to use the coding style, as described here: Style

The API

You can find the latest API documentation in /kernel/docs/ in the SVN repository (WebSVN)
Inside KolibriOS, you can find sysfuncs.txt (english version) or sysfuncr (russian version) in DOCKPACK program.
These files also come with the so called distribution kit, in documents folder.

Assembly examples

Some examples are listed on this page, more can be found on the SVN server in the folder /programs/develop/examples/ (WebSVN)

Simple example

<syntaxhighlight>

;
EXAMPLE APPLICATION  ;
;
Compile with FASM  ;
;

format binary as ""  ; Binary file format without extenstion

use32  ; Tell compiler to use 32 bit instructions

org 0x0  ; the base address of code, always 0x0

The header

db 'MENUET01' dd 0x01 dd START dd I_END dd 0x100000 dd 0x7fff0 dd 0, 0

The code area

include 'macros.inc'

START:  ; start of execution

       call    draw_window             ; draw the window
After the window is drawn, it's practical to have the main loop.
Events are distributed from here.

event_wait:

       mov     eax, 10                 ; function 10 : wait until event
       mcall                           ; event type is returned in eax
       cmp     eax, 1                  ; Event redraw request ?
       je      red                     ; Expl.: there has been activity on screen and
                                       ; parts of the applications has to be redrawn.
       cmp     eax, 2                  ; Event key in buffer ?
       je      key                     ; Expl.: User has pressed a key while the
                                       ; app is at the top of the window stack.
       cmp     eax, 3                  ; Event button in buffer ?
       je      button                  ; Expl.: User has pressed one of the
                                       ; applications buttons.
       jmp     event_wait
The next section reads the event and processes data.

red:  ; Redraw event handler

       call    draw_window             ; We call the window_draw function and
       jmp     event_wait              ; jump back to event_wait

key:  ; Keypress event handler

       mov     eax, 2                  ; The key is returned in ah. The key must be
       mcall                           ; read and cleared from the system queue.
       jmp     event_wait              ; Just read the key, ignore it and jump to event_wait.

button:  ; Buttonpress event handler

       mov     eax,17                  ; The button number defined in window_draw
       mcall                           ; is returned to ah.
  
       cmp     ah,1                    ; button id=1 ?
       jne     noclose
       mov     eax,-1                  ; Function -1 : close this program
       mcall

noclose:

       jmp     event_wait              ; This is for ignored events, useful at development
*********************************************
****** WINDOW DEFINITIONS AND DRAW ********
*********************************************
The static window parts are drawn in this function. The window canvas can
be accessed later from any parts of this code (thread) for displaying
processes or recorded data, for example.
The static parts *must* be placed within the fn 12 , ebx = 1 and ebx = 2.

draw_window:

       mov     eax, 12                 ; function 12: tell os about windowdraw
       mov     ebx, 1                  ; 1, start of draw
       mcall
       mov     eax, 0                  ; function 0 : define and draw window
       mov     ebx, 100 * 65536 + 300  ; [x start] *65536 + [x size]
       mov     ecx, 100 * 65536 + 120  ; [y start] *65536 + [y size]
       mov     edx, 0x14ffffff         ; color of work area RRGGBB
                                       ; 0x02000000 = window type 4 (fixed size, skinned window)
       mov     esi, 0x808899ff         ; color of grab bar  RRGGBB
                                       ; 0x80000000 = color glide
       mov     edi, title
       mcall
       mov     ebx, 25 * 65536 + 35    ; draw info text with function 4
       mov     ecx, 0x224466
       mov     edx, text
       mov     esi, 40
       mov     eax, 4
 .newline:                             ; text from the DATA AREA
       mcall
       add     ebx, 10
       add     edx, 40
       cmp     byte[edx], 0
       jne     .newline
       mov     eax, 12                 ; function 12:tell os about windowdraw
       mov     ebx, 2                  ; 2, end of draw
       mcall
       ret
*********************************************
************* DATA AREA *****************