How to Develop an operating system in C language [1]
--------------------------------------------------------------------------------
Author: tianxiangyuan Source: original updated: Views: 24
Although my question is "using C language to write an operating system", I cannot write an operating system only using C language. I have seen many articles about self-developed operating systems, almost all of which come from an English article called "write your own operating system tutorial". Besides, they all use assembly languages. Nowadays, there are very few people who can be proficient in assembly languages, and the main part of modern operating systems is written in C language. Is the so-called "own operating system" only applicable to assembly languages? Later, I wrote an operating system comparable to the operating system mentioned in the above article using the C language (in some parts, it must be integrated with the Assembly Language, we hope to develop it into a real Chinese operating system.
I developed it in a Windows environment, not the Linux environment that most people choose. Development tools are also Microsoft's development tools: masm615 and vc15. Microsoft's MASM has been widely spread, and everyone should be familiar with it. It may be unfamiliar with vc15. vc15 is the most "advanced" compiler for developing DOS Programs (despite many bugs ). If you cannot find these development tools, you can use tasm, Turbo C, or Borland C ++. The example given is based on masm615 and vc15, and transferred to the tasm, TC, or BC platform is not difficult. Note that the source code must be compiled in tiny mode, that is, the real-mode code must be generated.
1. Establish a Development Environment
This step is very simple.
Decompress the masm613 and vc15 packages to the E:/masm615 and E:/msvc15 directories respectively. You can also put it in another directory, depending on your situation, but the compilation commands used below need to be modified accordingly. You do not need to add or modify any environment variables.
2. ibm pc startup and memory usage at the time
This part of the content is already commonplace, but it cannot be said. We only talk about boot from the hard disk.
After the BIOS passes the post (power on test self), read the hard disk MBR to the memory 0x0000: 0x7c00 location, and then start execution from here. Generally, MBR selects active partitions to start the operating system. When the MBR starts to run, the memory usage is shown in. Address data is represented in hexadecimal notation:
This is an old-fashioned content, but it was very popular 20 years ago. If you want to learn more about this, please refer to this DoS book.
Our own operating system will be loaded to 0x1000: 0x0100. This is not necessary or necessary. It is a human choice. You can also place it in other places such as 0x4321: 1234. However, the memory area with other purposes should be retained. Otherwise, you will regret it.
How to Develop an operating system in C language [2]
--------------------------------------------------------------------------------
Author: tianxiangyuan Source: original updated: Views: 29
3. Develop the Operating System
Our own operating system runs in the real-mode environment (if you do not know what the real-mode is, please refer to the very popular book published 20 years ago, or you can directly consult your predecessors ). Even if your computer is a P4 CPU, it is only equivalent to 8086 of the clock speed at startup. However, it does not matter.
First, write a framework in assembly language with the file name entry. ASM:
;
; Entry. ASM
; Copyright (c) 2004, Tian xiangyuan
;
. Model tiny, c
. 386 P
Option expr32
Option Casemap: None
Cmain proto near C
. Code
Org 0100 h; offset address
_ Start:
JMP begin
NOP
DB 'tianxiangyuan', 0; the magic of my OS
Begin:
CLI
MoV ax, CS
MoV ds, ax
MoV es, ax
MoV SS, ax
MoV sp, 0 ffffh
STI
Call cmain; call the main function written in C Language
MoV ax, 4c00h; calls the DOS Function (for debugging), and has nothing to do with our own Operating System
Int 21 h
This code is very simple and there should be no problems.
As mentioned, the operating system will load data from 0x1000: 0x0100. We know that the starting address of a tiny program running in DOS is 0x0100, and the preceding 256byte is the parameter part. If the operating system is directly loaded to 0x1000: 0x0100 at system startup, debugging is very troublesome. We set the starting address to 0x0100 so that it can run in DOS (this is also the reason that the program finally contains the int 21h command). After confirming that it is correct, then proceed to the next step of development.
Next, let's look at the C language code. The file name is main. C:
......
Static void initshell ()
{
}
Void cmain ()
{
Initshell ();
Termshell ();
}
As the name implies, a simple shell is implemented. Because the program itself is part of the operating system, some C-library functions that are frequently used are unavailable here. In short, everything must be implemented by yourself. Fortunately, in real mode, almost all the drivers of the device are included in the bios and can be used directly. Otherwise, it is too difficult to write a keyboard driver to read a key value from the keyboard. This is why our operating system has not switched the CPU to the protection mode. You can try it.
Almost all of the following things can be implemented in C language.
First, initialize the display mode. When the system starts, the video card has been initialized to the 3 mode, that is, the 80x25 color mode (unless your display is a monochrome display), we do not need to do anything. Of course, you can also set the video card to VGA or even svga mode, as long as your BIOS and video card support.
Second, implement a shell with simple interaction functions. The code is incomplete. Complete the code by yourself or refer to the attachment.
/*
* Read a character from the keyboard. If there is no input, wait. The low byte of the returned value is asii, and the high byte is the Keyboard Scan code.
*/
Static int getch ()
{
Int CHR = 0;
_ ASM
{
MoV ah, 00 h
Int 16 h
MoV CHR, ax
}
Return CHR;
}
/*
* Output a character to the screen in tty mode.
*/
Static void putch (unsigned char key)
{
_ ASM
{
MoV BH, 0
MoV Al, key
MoV ah, 0eh
Int 10 h
}
}
# Define key_backspace 0x08
# Define key_enter 0x0d
# Define key_newline 0x0a
# Define key_escape 0x1b
Static int printk (const char * STR ,...)
{
...... // Give everyone some space to implement it by yourself
}
Static void endline ()
{
Putch (key_newline); // line feed (LF)
Putch (key_enter); // enter (CR)
}
Static char msg_prompt [] = "cmd :";
Static void deal_cmd (char * cmd_line, int cmd_len)
{
...... // You can implement it by yourself. For example, you can implement help, Dir, CLS, halt, and other commands.
...... // Actually, it is the process of string comparison
}
Static void termshell ()
{
Char performance_line [80] = {0 ,};
Int listen _len = 0;
Endline ();
Printk (msg_prompt, sizeof (msg_prompt ));
For (;;)
{
Cmd_line [cmd_len] = getch ();
Switch (cmd_line [cmd_len])
{
Case key_enter:
If (then _len> 1)
Deal_cmd (cmd_line, cmd_len );
// Break;
Case key_escape:
Required _len = 0;
Endline ();
Printk (msg_prompt, sizeof (msg_prompt ));
Break;
Case key_backspace:
If (then _len> 0)
{
Putch (0x08 );
Putch ('');
Putch (0x08 );
Performance_len --;
}
Break;
Default:
Putch (cmd_line [cmd_len]);
Performance_len ++;
}
}
}
For more complex and more powerful methods, refer to the BIOS documentation. You can also use your imagination to continuously expand your functions. To put it bluntly, this "Operating System" is more primitive than dos! However, it is your own operating system.
4. Compilation Method
The following is the content of build. bat. For various compilation options, see the relevant compiler instructions.
0x1000: 0x0100 when the system is loaded to the memory, and the CPU is working in real mode. If you cannot find a suitable boot program, you have to write one by yourself.
@ Echo off
Set Path = E:/masm615/bin; E:/msvc15/bin;
Set as = E:/masm615/bin/ml.exe
Set aflags =/AT/W3/X/GD/zp1/nologo
Set cc = E:/msvc15/bin/cl.exe
Set cflags =/OD/G3/GD/GS/ZL/zp1/X/W3/nologo
Del *. OBJ *. com *. Cod *. dbg *. PDB *. Map *. lst
% As %/C % aflags % entry. ASM
If errorlevel 1 goto Error
% CC %/C % cflags %/Fc main. c
If errorlevel 1 goto Error
% As % aflags %/Fe "boot.com" entry. OBJ main. OBJ
If errorlevel 1 goto Error
Goto exit
: Error
Echo failure ......
: Exit
Pause
@ Echo on
5. Bootstrap program
Although we have finished writing our own operating system, there is no way to guide it so that it has control of the system. You can use a third-party boot program, as long as it can load our operating system to the memory 0x1000: 0x0100, And the CPU works in real mode. If you cannot find a suitable boot program, you have to write one by yourself.
;
; Bootsect. ASM
; Copyright (c) 2004, Tian xiangyuan
;
. Model tiny, c
. 386 P
Option expr32
Option Casemap: None
Sysseg equ 1000 h
Sysoff equ 0100 H
. Code
Org 7c00h
_ Start:
JMP begin
NOP
DB 'bootsecret', 0; magic
Pack_size dB 16
Db 0; reserved
DW 60; Sectors
DW sysoff; buf_addr_off
DW sysseg; buf_addr_seg
DD 2; sector_from
Dd 0; sector_from_high
Begin:
CLI
MoV ax, CS
MoV ds, ax
MoV es, ax
MoV SS, ax
MoV sp, 0 ffffh
STI
MoV CX, msg_load_len; Length
Lea bp, msg_load; es: BP
Call display_msg
; Read disk for my OS
Lea Si, pack_size
MoV DL, 80 h
MoV ax, 4200 H
INT 13 h; use LBA to read the hard disk
JC Error
; Test magic of my OS
Lea Si, magic_test; DS: Si
MoV ax, sysseg
MoV es, ax
MoV Di, sysoff
Add Di, 3; es: Di
MoV CX, magic_test_len
ClD
Test_again:
Cmpsb
Jnz Error
Loop test_again
Push sysseg
Push sysoff
Retf; transferred to the Operating System for execution
Error:
MoV ax, CS
MoV es, ax
Lea bp, msg_error; es: BP
MoV CX, msg_error_len
Call display_msg
Failure:
Hlt
JMP failure
; CX: length of message
; Es: BP: Address of message
; Void display_msg ();
Display_msg proc near C
; Scrollup a line
Push CX
Push BP
MoV ax, 0601 H
MoV BH, 07 h
MoV CX, 0000 h; y/x
MoV dx, 184fh; y2/X2, 24/79
Int 10 h
Pop BP
Pop CX
; Display message
MoV ax, 1301 H
MoV BX, 000ah
; MoV CX, msg_error_len
MoV DL, 0; x
MoV DH, 24; y
; Lea bp, msg_error; es: BP
Int 10 h
RET
Display_msg endp
. Data
Msg_load dB 'loading... ', 0
Msg_load_len DW $-msg_load
Msg_error db' no booter, Please reboot! ', 0
Msg_error_len DW $-msg_error
Magic_test dB 'tianxiangyua', 0
Magic_test_len DW $-magic_test
End _ start
The above code is the MBR content. He reads the hard disk in LBA mode (supports large hard disk) and reads our operating system into 0x1000: 0x0100, and then transfer to the operating system for execution.
Obviously, our operating system must be placed within 60 sectors starting with the No. 2 (LBA Positioning Method) Sector of the hard disk (in fact, our operating system is far from that large ), in this case, the hard rules of our boot program may be more convenient if a third-party boot program is used.
You can develop your own installation program or use the winhex tool to write it to the hard disk. Please pay attention to data security. Do not break down hard disk partitions. We recommend that you back up data or use a test hard disk without important data. By the way, I use winhex to write data to the test hard disk.
The Bootstrap program is compiled in the same way as the operating system. The build. dat file is as follows:
@ Echo off
Set Path = E:/masm615/bin;
Set as = E:/masm615/bin/ml.exe
Set aflags =/AT/W3/wx/GD/zp1/X/nologo
Del *. OBJ *. com *. Cod *. dbg *. PDB *. Map
% As %/C % aflags % bootsect. ASM
If errorlevel 1 goto Error
% As % aflags %/Fe "bootsect.com" bootsect. OBJ
If errorlevel 1 goto Error
Goto exit
: Error
Echo failure ......
: Exit
Pause
@ Echo on
6. Postscript
Our own operating system has started in Taiyuan, and DoS is worse! Here, we mainly introduce a development method to illustrate how to develop underlying software like an operating system using C language.
In my spare time, I moved it to the Linux platform for development and used the CPU protection mode. After all, we can use the powerful functions of the 80x86 series CPU.
Welcome to comments: tianxiangyuan@sina.com.cn