When do we write our Chinese OS? (2)

Source: Internet
Author: User
Tags clear screen

The previous article talked about how to start the computer with our own program. However, as I have already said, it was just the first
The first step only indicates that we can allow computers to execute a task according to our commands from the very beginning.
But it is not an operating system. When the computer is guided by a boot program, we need to make it
The operating system kernel is loaded into the memory, and then jumps to the real operating system kernel to run.
This article will complete a real operating system boot, not the computer boot described in the first article. This
We will switch from the 16-bit real-time mode when the computer is started to the current general 32-bit protection mode.
In addition to the lowest layer, the current operating system is completed in advanced languages. In this article, we will also use advanced languages.
Let's write our kernel. A kernel implemented in this article is written in C language. Write a Bootstrap program by using
The C kernel is loaded and executed. This is the task to be completed in this article.
It is better to have a little bit of Assembly basics to read this article ~~~
In my old saying, my level is extremely limited. This is just an attempt. For countless errors, I hope you can understand it,
Never cut me down ~~~
Thank you very much!
Now, let's continue our experiment.
First, I want to introduce the real mode and protection mode. They are very important concepts for this article! Essentials
Yes! Even if you understand something wrong, try to understand it as much as possible! We all know that Intel's CPU is 8086
The age was 16 bits, and later the technology was developed, and Intel's CPU was changed to 32 bits. However
Program compatibility. inetl retains the 16-Bit mode in its 32-bit CPU. In this way, the 32-bit CPU has two
One is the 16-Bit mode, which is called the real mode; the other is the 32-Bit mode, which is called the protection mode.
. When the computer was just started, it was working in real mode to make it work in protection mode.
Next, we need to set the bit to a Cr0 register in the CPU. In this way, when the 0th bit of the Cr0 is set, the CPU will go to 32
It works in bit mode. Therefore, it is very easy to switch from 16-bit to 32-bit.
Bit operation. However, we still need to make preparations. Here we will first talk about the 16-bit and 32-bit modes.
Storage is accessed.
All those who have learned assembly know that in 8086, the memory is segmented. A memory address consists of a segment base address: offset. This
The reason is that in a 16-bit CPU, the register size is 16 bits and only 2 ^ 16 = 64 K addresses can be accessed. This is too small.
So we need to use the segmentation mechanism to expand the scope of the program's access to memory. Obviously, in a 16-bit CPU
The maximum segment size is 64 K
However, in a 32-bit CPU, the register size is 32-bit. You can access the 2 ^ 32 = 4 GB space, which is too large! I
Programs only need a small part of space. Therefore, in a 32-bit CPU, the memory is also segmented
Allocate necessary space for each program to avoid waste. (Note: In a 32-bit CPU, there are two types of memory management: segmentation and paging.
Mode, paging is mainly used to implement virtual memory, this article only discusses the segment mode) So you need to remember that each segment is
Which program? What is it? Is it a data segment or a code segment? Is it accessible or not? Is read-only
Or writable ?... The information to be recorded is too much, and the CPU will organize them and put them in the memory.
This memory is called a segment descriptor, which describes the attributes of this segment. Each segment has a description
The segment descriptors of the attribute are organized in a special place in the memory to form the segment descriptors.
Table. A 32-bit CPU can be divided into a Global Descriptor Table (gdt) and a Local Descriptor Table (LDT. The Global Descriptor Table refers to this table.
Can be accessed by all programs. In a 32-bit CPU, the segment register does not represent the base address of the segment, but indicates
The index of the descriptor table, used to indicate the location of the descriptor of the segment used by this program in the descriptor table. Then, access this description
The descriptor is retrieved from the table to obtain the attribute information about the segment. 32-bit CPU segment register is still 16-bit, no
It uses 13 BITs as the index of the segment descriptor table. Therefore, we can define a maximum of 2 ^ 13 = 8192 segments. By
It can be seen that in the 32-bit protection mode, the memory is accessed through the segment descriptor table. Therefore, when we go to the 32-bit
Between the two modes, we need to create the segment and segment descriptor table.
Well, we already have the basic knowledge. Let's talk less about it. Let's write our pilot program. The complete source code is as follows:
Below:
Note: If you have already annotated the previous article, you will not note it this time. If you do not understand it, please refer to the previous article.
[Bits 16]
[Org 0x7c00]
JMP main
;---------------------------------------------------------------------------
; Data Definition
Bootdrive db 0
;--------------------------------------------------------------
; Gdt definition. Here the segment and segment descriptor are defined.
Gdt:
Gdt_null:; this is reserved by the CPU. the first segment of the CPU must be empty.
What do you want to do?
Dd 0
Dd 0; the descriptor of each segment is 64-bit (8 bytes), and the 64-bit empty descriptor is all 0
Gdt_code_addr equ $-gdt; obtain the position of the code segment in the gdt table.
Gdt_code:
DW 0 xFFFF; Segment Size: 4 GB
DW 0; base address (24 bits)
Db 0
DB 10011010b; attribute description bit, indicating that this is a code segment that can be read and executed
DB 11001111b; what does each bit represent? Intel CPU Programming Manual
Db 0; if you do not have any, you can go online or ask me for it.
Gdt_data_addr equ $-gdt; locate the data segment in the gdt table
Gdt_data:
DW 0 xFFFF
DW 0
Db 0
DB 10010010b; indicates that this is a data segment and can be read and written.
DB 11001111b
Db 0
Gdt_end:
Gdt_addr:
DW gdt_end-gdt-1; gdt table size
Dd gdt; location of the gdt table
;---------------------------------------------------------------------------
Main:; the pilot program starts to execute from here
MoV [bootdrive], DL; get the start drive letter
XOR ax, ax; Set DS
MoV ds, ax
; Clear screen
; MoV ax, 3; set the clear screen function number
; Int 0x10; call BIOS 10 to interrupt screen clearing
. Resetfloppy; resetting a disk is not necessary, mainly for security reasons
MoV ax, 0; set the disk reset function number
MoV DL, [bootdrive]; Select Start Disk
Int 0x13; call BIOS 13 to interrupt disk resetting
JC. resetfloppy; retry if an error occurs
. Readfloppy; read the kernel to 0000: 9000 (ES: BX) in the memory,
; Why is it not certain to read 9000 points,
You can read another suitable address.
; Which address is appropriate? How do I know that an address combination is inappropriate? Coming soon
XOR ax, ax; Set es registers
MoV es, ax
MoV BX, 0x9000
MoV ah, 2; set the disk read function number
MoV DL, [bootdrive]; set the drive letter to be read
MoV CH, 0; head number
MoV Cl, 2; Start sector ID, read from the second sector,
The first sector is the Boot Sector, and the second is the kernel.
MoV Al, 17; number of sectors to be read. 17 sectors are read here,
It is afraid that the kernel is large, and reading is not enough.
INT 13 h; call BIOS 13 to interrupt and start reading the sector,
; This interrupt will read data to ES: BX
JC. readfloppy; retry if an error occurs (AH is the error number, 0 is correct)
MoV DL, [bootdrive]; stop the drive
MoV edX, 0x3f2
MoV Al, 0x0c
Out dx, Al
CLI; disconnection
Lgdt [gdt_addr]; load the gdt Descriptor
MoV eax, Cr0; the following three statements set the 0th-bit (PE-bit) of Cr0 to 1,
; Indicates entering the protection mode
Or eax, 1
MoV Cr0, eax
JMP gdt_code_addr: code_32; jump into the 32-bit code segment
[Bits 32]
Code_32:
MoV ax, gdt_data_addr; the following three statements set ds, es, SS, FS, GS
Describes the table location for the Data Segment
MoV ds, ax
MoV es, ax
MoV SS, ax
MoV FS, ax
MoV Gs, ax
MoV ESP, 0 xFFFF; set the stack head pointer
JMP gdt_code_addr: 0x9000; jump to the kernel,
; Gdt_code_addr is the index of the descriptor of the defined code segment
Because we previously read the kernel to the position of 0x9000,
So now we will go to the kernel for execution,
The guiding program successfully completed its historical mission!
;---------------------------------------------------------------------------
Times 510-($-$) db 0
Db 0x55
DB 0xaa
Next, we use the most familiar C language to compile our system kernel. The source code is as follows:
Char * MSG = "Welcome to hit operation system! Version 0.0001 by xyb ";
Void main ()
{
Unsigned char * videomem = (unsigned char *) 0xb8000;/* get the video address */
While (* MSG! = '/0 '){
* Videomem ++ = * MSG ++;/* set the ASCII code of the displayed character */
* Videomem ++ = 0x1b;/* set the text attributes (such as the background color, foreground color, and whether to flash )*/
}
For (;;);
}
This code is too simple to explain in detail. Here we only need to explain what 0xb8000 is. Let's first
Let's take a look at how the memory is allocated by the CPU.
0x0000: 0x0000-> 0x0000: 0x03ff = place where the Split Phase table is located
0x0000: 0x0400-> 0x0000: 0x04ff = BIOS location (BIOS data zone unavailable)
0x0000: 0x0500-> 0x0000: 0x7bff = free memory zone you can use
0x0000: 0x7c00-> 0x0000: 0x7dff = home of the system boot program,
Now you know that [org 0x7c00] is added to the boot program.
0x0000: 0x7e00-> 0x9000: 0 xFFFF = free memory zone you can use
0xa000: 0x0000-> 0xb000: 0 xFFFF = VGA display memory !!!!!!!! (*)
0xc000: 0x0000-> 0xf000: 0 xFFFF = BIOS location (BiOS read-only memory zone)
.........
The above list shows the distribution of the memory reserved by the CPU. Pay attention to the * line and check the C language program. Obviously, we
Write the data directly to the video memory! In this way, the data may be displayed.
Now our program has been compiled. Next, we need to complete the work of generating our boot disk to start
I love computers, and I am always waiting for it ~~~, Tired !!!
Compile our boot program first, and then write it to the first 512 bytes of the IMG boot file.
After a detailed description, I will not describe it here. If you have any questions, please refer to the previous article.
Next, we need to generate our kernel, Which is troublesome because there are few compilation tools and links in windows.
Tools, the current VC and BC can only generate Win32 standard programs, rather than binary files. This problem has not been solved for a long time.
Is there any hero !!! Please let me know. Thank you! Pai_^
No way. The east and east of MS is too bad, so we have to compile it in Linux.
Compile the C language program in Linux (you can also compile it in windows and copy it to Linux ).
Xyb. c
Then, create the following command:
Gcc-C xyb. c
-C indicates that only compilation is not linked.
Next, try again.
LD-O xyb-ttext 0x9000-E Main xyb. o
-O indicates the output file name.-ttext 0x9000 indicates that the base address of the program is 0x9000-E Main.
Start execution
Also need to knock
Objcopy-R. Note-R. comment-S-O binary xyb. Bin
-R. Note-R. Comment indicates that the. Note and. Comment segments are removed.
-S indicates removing all flag and relocation Information
-O binary xyb. Bin indicates that the binary file xyb. Bin is generated by xyb.
Copy xyb. Bin back to Windows and write it to the imgfile using winhex to guide the program. OK!
Success!
The running result is as follows:

All the tasks and objectives in this article have been completed. The current Boot Program is already a complete guide
Program, but the kernel is not a kernel. If there is time, I hope to continue the experiment ~~~, Hope
You have a lot of support and more advice! Pai_^
All source code and the generated image file of the program described in this article can be found below
Surface address download
FTP: // 202.118.239.46/incoming/other/BTC/temp/pyos1.rar
Leave a mail. Thank you for your advice!
Xieyubo@126.com

Http://purec.binghua.com/Article/ShowArticle.asp? ArticleID = 4

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.