Sie sind auf Seite 1von 14

How to develop an operating system using

C++?
Score: 3.9/5 (536 votes)

how operating systems are developed?


using C(or actually) C++, assembly and any programming languages like ada,
fortran, pascal you can develop your own operating system
but you have to use assembly in some places

an intruduction to assembly language


assembly is a low-level programming language that you can use it to control
everything like adding something to CPU registers, control the memory and
much more

how can i start to develop an operating system?


firstly, you have to know everything of your programming language like
pointers, functions (here i want to use C++)
secondly, you must have some knowledge of the assembly language

what tools i need to develop an operating system?


to develop an operating system you must have these:
1. an assembler
assembler takes your assembly code and give's you the low-level outputs like
an object containing your controls on CPU registers
the assembler here i want to use is nasm(netwide assembler)
you can download it from http://nasm.us
2. a cross-compiler
in order to develop an operating system, you must have a cross compiler
because you must compile your kernel for it's executable format
here i use gcc(gnu compiler collection)
you can download it from http://gcc.gnu.org/
3. a linker
the linker take's your objects and link them to getter
here i use gnu binutils
you can download it from http://gnu.org/software/binutils
4. a virtual machine
in order to test your operating system, you must have a vm(virtual machine)
but it isn't necessary
here i use virtualbox
you can download it from http://virtualbox.org/

notes before you get started


1. in developing an operating system, you cannot and cannot and cannot use
<iostream>, <fstream>, <memory>, <cstdio>, <cstdlib>, <windows.h>,
<unistd.h> and all the platform API's
you must create all of them yourself
2. you must very very be careful
when you are developing, you have control of everything
so, you can destroy one or some or all of your hardwares
in this case, i recommend to use a virtual machine to test your operating system
instead of rebooting more and more times

the bootloader
a bootloader is a bunch of code that is written in assembly language and must
be 512 byets(1 sector)
it load's your operating system's kernel
we skip this section and use grub as are bootloader
you can download grub source code from http://gnu.org/software/grub
or actually you maybe want a compiled for floppy: searching in google will
help you

a simple kernel
we want to develop an operating system
so, we have to create the functions ourselves
firstly, we create a file boot.asm with these contents:
1 ;boot.asm:the bootloader to boot are operating system with grub
2 [bits 32] ;we are in 32 bit
3 global start ;start's the operating system:we call it in the linker
4 script Edit &
5 extern _kernel_main ;this is in are .cpp file and it is the main function Run
6 of are kernel
7 ;do not modify these lines(these are needed by grub)!
8 section .mbHeader
9
10 align 0x4
11
12 ; setting up the Multiboot header - see GRUB docs for details
13 MODULEALIGN equ 1<<0 ; align loaded modules on page
14 boundaries
15 MEMINFO equ 1<<1 ; provide memory map
16 FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag'
17 field
18 MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader
19 find the header
20 CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
21
22 MultiBootHeader:
23 dd MAGIC
24 dd FLAGS
25 dd CHECKSUM

;you can modify these


start:
push ebx ;this is optional and load's the grub structure
call _kernel_main

now create a file: kernel.cpp with these contents:


1 #include <stddef.h> //we can use it: it doesnt use any platform-related
2 api functions
3 #include <stdint.h> //include it to get int16_t and some integer types
4
5 /* Hardware text mode color constants. */
6 enum vga_color
7 {
8 COLOR_BLACK = 0,
9 COLOR_BLUE = 1,
10 COLOR_GREEN = 2,
11 COLOR_CYAN = 3,
12 COLOR_RED = 4,
13 COLOR_MAGENTA = 5,
14 COLOR_BROWN = 6,
15 COLOR_LIGHT_GREY = 7,
16 COLOR_DARK_GREY = 8,
Edit &
17 COLOR_LIGHT_BLUE = 9, Run
18 COLOR_LIGHT_GREEN = 10,
19 COLOR_LIGHT_CYAN = 11,
20 COLOR_LIGHT_RED = 12,
21 COLOR_LIGHT_MAGENTA = 13,
22 COLOR_LIGHT_BROWN = 14,
23 COLOR_WHITE = 15,
24 };
25
26 uint8_t make_color(enum vga_color fg, enum vga_color bg)
27 {
28 return fg | bg << 4;
29 }
30
31 uint16_t make_vgaentry(char c, uint8_t color)
32 {
33 uint16_t c16 = c;
34 uint16_t color16 = color;
35 return c16 | color16 << 8;
36 }
37
38 size_t strlen(const char* str)
39 {
40 size_t ret = 0;
41 while ( str[ret] != 0 )
42 ret++;
43 return ret;
44 }
45
46 static const size_t VGA_WIDTH = 80;
47 static const size_t VGA_HEIGHT = 24;
48
49 size_t terminal_row;
50 size_t terminal_column;
51 uint8_t terminal_color;
52 uint16_t* terminal_buffer;
53
54 void terminal_initialize()
55 {
56 terminal_row = 0;
57 terminal_column = 0;
58 terminal_color = make_color(COLOR_LIGHT_GREY, COLOR_BLACK);
59 terminal_buffer = (uint16_t*) 0xB8000;
60 for ( size_t y = 0; y < VGA_HEIGHT; y++ )
61 {
62 for ( size_t x = 0; x < VGA_WIDTH; x++ )
63 {
64 const size_t index = y * VGA_WIDTH + x;
65 terminal_buffer[index] = make_vgaentry(' ',
66 terminal_color);
67 }
68 }
69 }
70
71 void terminal_setcolor(uint8_t color)
72 {
73 terminal_color = color;
74 }
75
76 void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
77 {
78 const size_t index = y * VGA_WIDTH + x;
79 terminal_buffer[index] = make_vgaentry(c, color);
80 }
81
82 void terminal_putchar(char c)
83 {
84 terminal_putentryat(c, terminal_color, terminal_column,
85 terminal_row);
86 if ( ++terminal_column == VGA_WIDTH )
87 {
88 terminal_column = 0;
89 if ( ++terminal_row == VGA_HEIGHT )
90 {
91 terminal_row = 0;
92 }
93 }
94 }
95
96 void terminal_writestring(const char* data)
97 {
98 size_t datalen = strlen(data);
99 for ( size_t i = 0; i < datalen; i++ )
100 terminal_putchar(data[i]);
101 }
102
103 void kernel_main()
104 {
105 terminal_initialize();
terminal_writestring("wellcome to my first operating system!");
for(;;);
}

the linker script


create a file: linker.ld with these contents:
1 /* The bootloader will look at this image and start execution at the symbol
2 designated as the entry point. */
3 ENTRY(start)
4
5 /* Tell where the various sections of the object files will be put in the final
6 kernel image. */
7 SECTIONS
8 {
9 /* Begin putting sections at 1 MiB, a conventional place for kernels
10 to be
11 loaded at by the bootloader. */
12 . = 1M;
13
14 /* First put the multiboot header, as it is required to be put very early
15 early in the image or the bootloader won't recognize the file format.
16 Next we'll put the .text section. */
17 .text BLOCK(4K) : ALIGN(4K)
18 {
19 *(.mbHeader)
20 *(.text)
21 }
22
23 /* Read-only data. */
24 .rodata BLOCK(4K) : ALIGN(4K)
25 {
26 *(.rodata)
27 }
28
29 /* Read-write data (initialized) */
30 .data BLOCK(4K) : ALIGN(4K)
31 {
32 *(.data)
33 }
34
35 /* Read-write data (uninitialized) and stack */
36 .bss BLOCK(4K) : ALIGN(4K)
37 {
38 *(COMMON)
39 *(.bss)
40 }
41
42 /* The compiler may produce other sections, by default it will put them
43 in
a segment with the same name. Simply add stuff here as needed. */
}

how to compile it
go to the shell (on windows cygwin is required):
type these commands:
1 nasm -f elf boot.asm -o boot.o
2 g++ -c kernel.cpp -o kernel.o -ffreestandinng -fno-exceptions -fno-rtti
3 gcc loader.o kernel.o -T linker.ld -o kern -nostdlib -nodefaultlibs -lgcc

kingratulations!
your first operating system has been compiled successfully!
now you can create an image using grub-mkrescue:
create a directory: iso
in that directory, create another directory: boot then in the boot directory, create
a directory: grub and then create a file: grub.cfg with these contents(do not add
the braces in a new line) in the grub directory:
1 menuentry "myOS" {
2 multiboot /boot/kern
3}

then copy your kernel (kern) to iso/boot directory and run your shell again:
switch to the main directory of your kernel and type:
grub-mkrescue iso --output=kern.iso

now you can boot and enjoy from your first operating system:: this simple
kernel without anything
Rate this
Please, choose stars to award:
(hover mouse and click)

C++

• Information
• Tutorials
• Reference
• Articles
• Forum

Articles

• Algorithms
• C++ 11
• Graphics and multimedia
• How-To
• Language Features
• Unix/Linux programming
• Source Code
• Standard Library
• Tips and Tricks
• Tools and Libraries
• Visual C++
• Windows API

Home page | Privacy policy


© cplusplus.com, 2000-2015 - All rights reserved - v3.1
Spotted an error? contact us

How to develop an operating system using


C++?
Score: 3.9/5 (536 votes)

how operating systems are developed?


using C(or actually) C++, assembly and any programming languages like ada,
fortran, pascal you can develop your own operating system
but you have to use assembly in some places

an intruduction to assembly language


assembly is a low-level programming language that you can use it to control
everything like adding something to CPU registers, control the memory and
much more

how can i start to develop an operating system?


firstly, you have to know everything of your programming language like
pointers, functions (here i want to use C++)
secondly, you must have some knowledge of the assembly language

what tools i need to develop an operating system?


to develop an operating system you must have these:
1. an assembler
assembler takes your assembly code and give's you the low-level outputs like
an object containing your controls on CPU registers
the assembler here i want to use is nasm(netwide assembler)
you can download it from http://nasm.us
2. a cross-compiler
in order to develop an operating system, you must have a cross compiler
because you must compile your kernel for it's executable format
here i use gcc(gnu compiler collection)
you can download it from http://gcc.gnu.org/
3. a linker
the linker take's your objects and link them to getter
here i use gnu binutils
you can download it from http://gnu.org/software/binutils
4. a virtual machine
in order to test your operating system, you must have a vm(virtual machine)
but it isn't necessary
here i use virtualbox
you can download it from http://virtualbox.org/

notes before you get started


1. in developing an operating system, you cannot and cannot and cannot use
<iostream>, <fstream>, <memory>, <cstdio>, <cstdlib>, <windows.h>,
<unistd.h> and all the platform API's
you must create all of them yourself
2. you must very very be careful
when you are developing, you have control of everything
so, you can destroy one or some or all of your hardwares
in this case, i recommend to use a virtual machine to test your operating system
instead of rebooting more and more times

the bootloader
a bootloader is a bunch of code that is written in assembly language and must
be 512 byets(1 sector)
it load's your operating system's kernel
we skip this section and use grub as are bootloader
you can download grub source code from http://gnu.org/software/grub
or actually you maybe want a compiled for floppy: searching in google will
help you

a simple kernel
we want to develop an operating system
so, we have to create the functions ourselves
firstly, we create a file boot.asm with these contents:
1 ;boot.asm:the bootloader to boot are operating system with grub
2 [bits 32] ;we are in 32 bit
3 global start ;start's the operating system:we call it in the linker
4 script
5 extern _kernel_main ;this is in are .cpp file and it is the main function
6 of are kernel
7 ;do not modify these lines(these are needed by grub)!
8 section .mbHeader
9
10 align 0x4
11 Edit &
12 ; setting up the Multiboot header - see GRUB docs for details Run
13 MODULEALIGN equ 1<<0 ; align loaded modules on page
14 boundaries
15 MEMINFO equ 1<<1 ; provide memory map
16 FLAGS equ MODULEALIGN | MEMINFO ; this is the Multiboot 'flag'
17 field
18 MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader
19 find the header
20 CHECKSUM equ -(MAGIC + FLAGS) ; checksum required
21
22 MultiBootHeader:
23 dd MAGIC
24 dd FLAGS
25 dd CHECKSUM

;you can modify these


start:
push ebx ;this is optional and load's the grub structure
call _kernel_main

now create a file: kernel.cpp with these contents:


1 #include <stddef.h> //we can use it: it doesnt use any platform-related
2 api functions
3 #include <stdint.h> //include it to get int16_t and some integer types
4
5 /* Hardware text mode color constants. */
6 enum vga_color
7 {
8 COLOR_BLACK = 0,
9 COLOR_BLUE = 1,
10 COLOR_GREEN = 2,
11 COLOR_CYAN = 3,
12 COLOR_RED = 4,
13 COLOR_MAGENTA = 5,
14 COLOR_BROWN = 6,
15 COLOR_LIGHT_GREY = 7,
16 COLOR_DARK_GREY = 8,
17 COLOR_LIGHT_BLUE = 9,
18 COLOR_LIGHT_GREEN = 10,
19 COLOR_LIGHT_CYAN = 11,
20 COLOR_LIGHT_RED = 12,
21 COLOR_LIGHT_MAGENTA = 13,
22 COLOR_LIGHT_BROWN = 14,
23 COLOR_WHITE = 15,
Edit &
24 }; Run
25
26 uint8_t make_color(enum vga_color fg, enum vga_color bg)
27 {
28 return fg | bg << 4;
29 }
30
31 uint16_t make_vgaentry(char c, uint8_t color)
32 {
33 uint16_t c16 = c;
34 uint16_t color16 = color;
35 return c16 | color16 << 8;
36 }
37
38 size_t strlen(const char* str)
39 {
40 size_t ret = 0;
41 while ( str[ret] != 0 )
42 ret++;
43 return ret;
44 }
45
46 static const size_t VGA_WIDTH = 80;
47 static const size_t VGA_HEIGHT = 24;
48
49 size_t terminal_row;
50 size_t terminal_column;
51 uint8_t terminal_color;
52 uint16_t* terminal_buffer;
53
54 void terminal_initialize()
55 {
56 terminal_row = 0;
57 terminal_column = 0;
58 terminal_color = make_color(COLOR_LIGHT_GREY, COLOR_BLACK);
59 terminal_buffer = (uint16_t*) 0xB8000;
60 for ( size_t y = 0; y < VGA_HEIGHT; y++ )
61 {
62 for ( size_t x = 0; x < VGA_WIDTH; x++ )
63 {
64 const size_t index = y * VGA_WIDTH + x;
65 terminal_buffer[index] = make_vgaentry(' ',
66 terminal_color);
67 }
68 }
69 }
70
71 void terminal_setcolor(uint8_t color)
72 {
73 terminal_color = color;
74 }
75
76 void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
77 {
78 const size_t index = y * VGA_WIDTH + x;
79 terminal_buffer[index] = make_vgaentry(c, color);
80 }
81
82 void terminal_putchar(char c)
83 {
84 terminal_putentryat(c, terminal_color, terminal_column,
85 terminal_row);
86 if ( ++terminal_column == VGA_WIDTH )
87 {
88 terminal_column = 0;
89 if ( ++terminal_row == VGA_HEIGHT )
90 {
91 terminal_row = 0;
92 }
93 }
94 }
95
96 void terminal_writestring(const char* data)
97 {
98 size_t datalen = strlen(data);
99 for ( size_t i = 0; i < datalen; i++ )
100 terminal_putchar(data[i]);
101 }
102
103 void kernel_main()
104 {
105 terminal_initialize();
terminal_writestring("wellcome to my first operating system!");
for(;;);
}

the linker script


create a file: linker.ld with these contents:
1 /* The bootloader will look at this image and start execution at the symbol
2 designated as the entry point. */
3 ENTRY(start)
4
5 /* Tell where the various sections of the object files will be put in the final
6 kernel image. */
7 SECTIONS
8 {
9 /* Begin putting sections at 1 MiB, a conventional place for kernels
10 to be
11 loaded at by the bootloader. */
12 . = 1M;
13
14 /* First put the multiboot header, as it is required to be put very early
15 early in the image or the bootloader won't recognize the file format.
16 Next we'll put the .text section. */
17 .text BLOCK(4K) : ALIGN(4K)
18 {
19 *(.mbHeader)
20 *(.text)
21 }
22
23 /* Read-only data. */
24 .rodata BLOCK(4K) : ALIGN(4K)
25 {
26 *(.rodata)
27 }
28
29 /* Read-write data (initialized) */
30 .data BLOCK(4K) : ALIGN(4K)
31 {
32 *(.data)
33 }
34
35 /* Read-write data (uninitialized) and stack */
36 .bss BLOCK(4K) : ALIGN(4K)
37 {
38 *(COMMON)
39 *(.bss)
40 }
41
42 /* The compiler may produce other sections, by default it will put them
43 in
a segment with the same name. Simply add stuff here as needed. */
}

how to compile it
go to the shell (on windows cygwin is required):
type these commands:
1 nasm -f elf boot.asm -o boot.o
2 g++ -c kernel.cpp -o kernel.o -ffreestandinng -fno-exceptions -fno-rtti
3 gcc loader.o kernel.o -T linker.ld -o kern -nostdlib -nodefaultlibs -lgcc

kingratulations!
your first operating system has been compiled successfully!
now you can create an image using grub-mkrescue:
create a directory: iso
in that directory, create another directory: boot then in the boot directory, create
a directory: grub and then create a file: grub.cfg with these contents(do not add
the braces in a new line) in the grub directory:
1 menuentry "myOS" {
2 multiboot /boot/kern
3}

then copy your kernel (kern) to iso/boot directory and run your shell again:
switch to the main directory of your kernel and type:
grub-mkrescue iso --output=kern.iso

now you can boot and enjoy from your first operating system:: this simple
kernel without anything
Rate this
Please, choose stars to award:

(hover mouse and click)

C++

• Information
• Tutorials
• Reference
• Articles
• Forum
Articles

• Algorithms
• C++ 11
• Graphics and multimedia
• How-To
• Language Features
• Unix/Linux programming
• Source Code
• Standard Library
• Tips and Tricks
• Tools and Libraries
• Visual C++
• Windows API

Home page | Privacy policy


© cplusplus.com, 2000-2015 - All rights reserved - v3.1
Spotted an error? contact us

Das könnte Ihnen auch gefallen