Making an OS user programmable
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Making an OS user programmable
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?
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
Nitin
-
- Posts: 5
- Joined: Mon Nov 06, 2006 2:40 pm
- Location: Germany
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
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
- Combuster
- 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:
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
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
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
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?
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
Nitin
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....
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....
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
main.c
link.asm
link.h
command prompt commands
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
#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(;;);
}
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
Code: Select all
void print();
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
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
Nitin
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
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.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
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).
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact: