Making an OS user programmable

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
nitinjavakid
Member
Member
Posts: 65
Joined: Sat Oct 21, 2006 11:28 am
Location: Exams over!
Contact:

Making an OS user programmable

Post by nitinjavakid »

Having learnt a bit about VESA(thanks to Brendan), I would like to implement a small 2d library for my OS. Something similar to BGI in Turbo C(if you remember). But I have written all the functions in assembly(nasm) and would like to make them usable to other C programs written by users. I saw some for the tutorials but they just showed how kernel is made in C. For better understanding of the problem, let me put an example.
This is the exact procedure(Is it possible or I have declare rect function as subfunction of an interrupt)

function _rect is defined by the OS.

user creates a program
void main()
{
rect(..some args...);
}

compiles it and stores it as a .bin file onto the filesystem(provided by the OS). (Here, I donno from where _rect function will come be taken while linking)

OS reads the file and copies all the it into memory. Set the segment registers to where it has loaded the program and jumps to the first program instruction.

Is it possible without interrupts?
Regards


Nitin
martin.zielinski
Posts: 5
Joined: Mon Nov 06, 2006 2:40 pm
Location: Germany

Post by martin.zielinski »

What you mean by storing the app as .bin? If you mean a flat binary file than you will need to implement some form of executable format. A plain binary file do not store import tables and such stuff. So you are restricted to static linking. This is in my opinion not the right way, because this will include the hardware-manipulation code directly in the user-app, which could be a serious security problem, because you have to run the app in os-privileg.

So basicly what you need is some form of binary executable format that contains import/export tables (PE, ELF, whatever) to allow you dynamic linkage. This add a lot of flexibility.

Here is a simple scratch how this could be done:

- Kernel contains basic functionality and the HAL
- HAL implements accessors to the hardware and defines an interface for
"userland-usable-libraries"
- GfxLib links dynamicly to the HAL and implements gfx-functionality based
on the interface the HAL provided
- MyCoolApp links staticly or dynamicly to the gfx-lib and uses its exported
functions to accomplish it's task
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

You probably want to provide some sort of graphics library to the programmer. Its not hard to explain for gnu sytems, but as i have no clue how your toolchain works you have to figure that part.

Globally you have to do these steps
- Write the asm routines using the C Calling Convention
- Write C Headers with the prototypes of the functions you've just written
- Compile the graphics code
- Link/Archive the graphics code into an library (1)
- Compile the user program
- Link the user program with the archive created above

1: you can skip this step if you dont know how this works and you dont mind supplying all .o files manually to the linker in the last step. Also in this step you might be able to create shared libraries, DLL, .so's and that sort of thing.
Doing things the DOS way and include all graphics code in the end application can be a good place to start to avoid hassles (downside is that you will generate big binaries this way).

Sample ASM file
Corresponding C header
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
nitinjavakid
Member
Member
Posts: 65
Joined: Sat Oct 21, 2006 11:28 am
Location: Exams over!
Contact:

Post by nitinjavakid »

Thanks!
Looked at your source code. The header file is indirectly using interrupts to call kernel functions. Is that the same way in which windows it is 0x21 and on linux 0x80 call system calls? I mean
int main()
{
printf("Am I Calling an interrupt");
return 0;
}

Will the above function printf call 0x80 interrupt if it is compiled for linux?
Regards


Nitin
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I have no clue as to how the kernel calls in linux/windows work. The ASM file is just a small example simply calling the kernel. You could put actual code in there if you'd want it that way. (Some things dont need a kernel, and therefore no system call/interrupt)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Post by prajwal »

Syscall (in case of x86) is done by means of call gates/int gates...
Whenever user program tries to access any kernel resource like kernel memory for DMA transfer (in disk read/write), process table, file system tables... syscalls are required as kernel will be running (usually) at ring 0 and user program in ring x > 0.... this is how u enforce security for OS / kernel.... When it comes to printf... ultimately the chars has to be displayed on screen which invovles screen buffer updation which is part of kernel mem... so, syscall (ints) isinvovled in printf also.....

I have heard many guys (freshers out of college) saying "one should use library calls especially for file access ie. fopen instead of open, so that it doesn;t invovle context switch... that is totally a wrong notion.. its true that it decreases the no. of context switches due to library level buffering but ultimatey the task is carried out by kernel for the user program....
User avatar
nitinjavakid
Member
Member
Posts: 65
Joined: Sat Oct 21, 2006 11:28 am
Location: Exams over!
Contact:

Post by nitinjavakid »

main.c

Code: Select all

#include "link.h"

void kmain()
{
  unsigned char *vidmem = (unsigned char *)0xB8000;
  vidmem[0] = 'r'; // before going into print
  print(); 
  vidmem[0] = 's'; //after coming out from print
  for(;;);
}
link.asm

Code: Select all

section .text
[bits 32]
global _print
_print:
      push eax
      push ds
      mov ax,0x08
      mov ds,ax
      mov eax, 0xB8000
      mov  byte [eax],'A'
      pop ds
      pop eax
     jmp $ ; for checking
      ret
link.h

Code: Select all

	void print();
command prompt commands

Code: Select all

nasm -f bin bootsect.asm -o bootsect.bin
nasm -f elf link.asm -o link.o
gcc -ffreestanding -mno-stack-arg-probe -c main.c -o main.o

ld -e _kmain -Ttext 0x1000 -o kernel.o main.o link.o

ld -i -e _kmain -Ttext 0x1000 -o kernel.o main.o link.o
objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin

makeboot a.img bootsect.bin kernel.bin
I am getting 's' on the top left of the screen which should not be the case if print is called. So, I assume that print is not being called. What could be the mistake?

objdump for more info

Code: Select all

E:\osdev>objdump -d -f kernel.o

kernel.o:     file format pe-i386
architecture: i386, flags 0x0000013b:
HAS_RELOC, EXEC_P, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x00001000

Disassembly of section .text:

00001000 <_kmain>:
    1000:       55                      push   %ebp
    1001:       89 e5                   mov    %esp,%ebp
    1003:       83 ec 08                sub    $0x8,%esp
    1006:       c7 45 fc 00 80 0b 00    movl   $0xb8000,0xfffffffc(%ebp)
    100d:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
    1010:       c6 00 72                movb   $0x72,(%eax)
    1013:       e8 00 00 00 00          call   1018 <_kmain+0x18>
    1018:       8b 45 fc                mov    0xfffffffc(%ebp),%eax
    101b:       c6 00 73                movb   $0x73,(%eax)
    101e:       eb fe                   jmp    101e <_kmain+0x1e>

00001020 <_print>:
    1020:       50                      push   %eax
    1021:       1e                      push   %ds
    1022:       66 b8 08 00             mov    $0x8,%ax
    1026:       8e d8                   movl   %eax,%ds
    1028:       b8 00 80 0b 00          mov    $0xb8000,%eax
    102d:       c6 00 41                movb   $0x41,(%eax)
    1030:       1f                      pop    %ds
    1031:       58                      pop    %eax
    1032:       eb fe                   jmp    1032 <_print+0x12>
    1034:       c3                      ret
        ...
Regards


Nitin
User avatar
nitinjavakid
Member
Member
Posts: 65
Joined: Sat Oct 21, 2006 11:28 am
Location: Exams over!
Contact:

Post by nitinjavakid »

From the output of objdump, all i can see is while calling kprint, jmp to next instruction is being performed :roll: .
Regards


Nitin
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

nitinjavakid wrote:

Code: Select all

nasm -f bin bootsect.asm -o bootsect.bin
nasm -f elf link.asm -o link.o
gcc -ffreestanding -mno-stack-arg-probe -c main.c -o main.o

ld -e _kmain -Ttext 0x1000 -o kernel.o main.o link.o

ld -i -e _kmain -Ttext 0x1000 -o kernel.o main.o link.o
objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin

makeboot a.img bootsect.bin kernel.bin
You link to the output file. Then you relink to the output file as a relocatable file (which seems pointless). You then pretend to have a non-relocatable output file (objdump doesn't relocate, ld should've done that but you overwrote the output with one that wasn't relocated) and objcopy just copies the current contents of the sections. That explains the call 0.

Remove the ld -i line and you should be all set. LD should relocate, objcopy creates the binary file. FYI, ld also has a --oformat flag that allows the same thing basically but is less error-prone (since LD will just warn you about intermediate linking to a binary file).
User avatar
nitinjavakid
Member
Member
Posts: 65
Joined: Sat Oct 21, 2006 11:28 am
Location: Exams over!
Contact:

Post by nitinjavakid »

on removing -i, program works fine but size of .bin file increases to a large extent(from 48 to 4118 approx. bytes). Is there any way to reduce that. Also, objdump shows the required code with some extra unwanted code(donno what that is for).
Regards


Nitin
User avatar
nitinjavakid
Member
Member
Posts: 65
Joined: Sat Oct 21, 2006 11:28 am
Location: Exams over!
Contact:

Post by nitinjavakid »

ok got it now. Linker script can be used for such purposes.
Regards


Nitin
Post Reply