This is one of the most useless idea I've ever had -- making an operating system that only shows my resume.
8 years ago, when I was a student, I started a big project -- build my own operating system, just for fun. The very basic functionalities are here : multithreading, pagination, text console, interruption, exceptions.
From this project, I took only what I need to boot and show my resume on 2 screens. This is a fantastic start to explain how it works.
To build my binary file, I use only 3 softwares :
It results is a binary file. Do'nt waste your time trying to execute it on your machine ; it will never work.
Qemu has the capability to execute special binaries (kernels) without a bootloader.
qemu-system-i386 -kernel kernel.bin
A bootloader is the first binary code executed on your computer. Windows has its own ; Linux often use grub or lilo.
With grub, it's possible to build a bootable iso file with grub, its configuration file and a binary file : the kernel.
grub-mkrescue -o os.iso isofiles
"isofiles" is a directory :
isofiles
boot
kernel.bin
grub
grub.cfg
My grub.cfg file :
set timeout=0
set default=0
menuentry "my os" {
multiboot /boot/kernel.bin
boot
}
https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
" Every operating system ever created tends to have its own boot loader. Installing a new operating system on a machine generally involves installing a whole new set of boot mechanisms, each with completely different install-time and boot-time user interfaces. Getting multiple operating systems to coexist reliably on one machine through typical chaining mechanisms can be a nightmare. There is little or no choice of boot loaders for a particular operating system — if the one that comes with the operating system doesn't do exactly what you want, or doesn't work on your machine, you're screwed."
"While we may not be able to fix this problem in existing proprietary operating systems, it shouldn't be too difficult for a few people in the free operating system communities to put their heads together and solve this problem for the popular free operating systems. That's what this specification aims for. Basically, it specifies an interface between a boot loader and a operating system, such that any complying boot loader should be able to load any complying operating system. This specification does not specify how boot loaders should work — only how they must interface with the operating system being loaded."
2 files :
start.asm
my file comes from : http://wiki.osdev.org/Barebones#Implementingthe_Kernel
All comments in the file explains how it works.
No need to copy/paste it here.
main.c
Previous file calls an external function (kernel_start). This is the entrypoint. From here, do what you want but think about one thing : no libc... you have to do by hand every function you need.
No printf available ! One information : a character written at 0xB8000 is show on top left of your screen. Next Byte is an argument for background color and text color.
typedef struct {
unsigned char c;
unsigned char attr;
} __attribute__ ((packed)) video_mem[width*lines];
static int x, y = 0;
static volatile video_mem *screen = (volatile video_mem *)start_video_mem;
void printchar(char c){
long offset = x+y*width;
(*screen)[offset].c =c ;
(*screen)[offset].attr = aff;
}
Here it is ! A basic function to write any character.
Keep 2 integers with the current position. Increase them while you write characters.
http://wiki.osdev.org/PS/2_Keyboard
There is 2 ways to do this :
IRQ (interruptions) are basics for an operating system. But, in my case, code needed to init interruptions, IDT, tables and functions is bigger than all the rest ! ASM and C is needed... a terrible mix for someone not aware with this kind of concepts.
tables with codes are shown here :
http://wiki.osdev.org/PS/2Keyboard#ScanCodeSet1
In my project, do not need a table. Why ? "press any key" and problem is solved :)
getScancode();
This function waits until a key is pressed.
Feel free to improve this OS, add a console mode or better, a console on a serial port.
Note : I use a special function to call a assembly function :
static inline char inb(short port)
{
char ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port) );
return ret;
}
qemu-system-i386 -cdrom os.iso
sources :
http://mikeos.sourceforge.net/write-your-own-os.html
http://os.phil-opp.com/multiboot-kernel.html
http://wiki.osdev.org/Bare_bones
http://www.cs.vu.nl/~herbertb/misc/writingkernels.txt