Operating system boot exploration (Version 0.02)

xiaoxiao2021-03-06  48

Description: QQ: 13916830Email: xieyubo@126.com Welcome to letter, please indicate the author and source, please download the original (PDF) source code download

Original: http://purec.binghua.com/Article/class6/class7/200411/81.html Note: This article is published in << Pure C Forum · Electronic Journal >> 2004.10 (http: //purec.binghua .com / SOFT / CLASS2 / DL_HPCEM / 200410 / 74.HTML)

Operating system boot exploration (Version 0.02)

Harbin Institute of Technology Computer Architecture Laboratory Xie Yubo (xieyubo@126.com)

Version 0.02 Modify Record:

The description of the descriptor related to GDT is revised, and some errors appearing in the previous version have increased some description to make them more perfect.

Different from the previous versions are used in red tags.

Foreword

This article does not intend to discuss how to guide a multi-boot system program to guide different operating systems, but only plan to start from the perspective of the operating system, talk about how the computer starts from power, from nothing, will operate The system runs, which will make a detailed description of the transition from the real model to the protection mode, and the purpose is only to share the learned and the majority of enthusiasts, and leave a little information for friends who want to develop the operating system, and leave a little for yourself. Experience.

This article will take the PYOS system boot program in development as an example. PYOS is an experimental operating system under development. It does not intend to model the operating system in any of the current operations, but only want to write itself. A operating system from head to tail to learn knowledge, accumulate technology, if you are interested, welcome you to join!

This is a little experience in the learning process. If you find that there is a mistake or improper, I hope you will tell you.

First, what did the computer have done from power?

When the power button of the machine computer is pressed, the electrical signal line associated with this button will send an electric signal to the motherboard. The motherboard transmits this electrical signal to the power supply system. The power supply system starts working, and the entire system is powered. And send an electrical signal to the BIOS, notifying the BIOS power supply system ready to complete. Subsequent BIOS launched a program, hosting the host self-test, the main job of host self-test is to ensure that every part of the system has received power support, memory, other chips, keyboard, mouse, disk controller and some I / The O port is normal. Since then, the self-test program will control the control to the BIOS. Next, BIOS read the relevant settings in the BIOS, get the order of boot drive, then check until you find drives that can be used to boot (or can be booted, including floppy disk, hard disk, disc, etc.), then call The boot sector of the disk is booted on the drive. How does BIOS know or tell which disk can be used to boot?

Second, know the boot process

BIOS loads the first sector of the disk (512 bytes of the magnetic disk) to the memory, put it on 0x0000: 0x

7C

00 (see Figure 3), if the last two bytes of this sector are "55 aa", then this is a boot sector, which is a bootable disk. Usually this program of this size is 512B is called a boot program. If the last two bytes are not "55 aa", then BIOS checks the next disk drive.

Through the above expression we can summarize the characteristics of the following three points of boot procedures:

1. Its size is 512B, and it cannot be one byte by one byte because the BIOS reads only 512b to memory.

2. Its ends must be "55 AA", which is the sign of the boot sector. 3. It is always placed on the first sector of the disk (0 head, 0 track, 1 sector) because the BIOS reads only the first sector.

(Figure 1)

Therefore, when we write boot procedures, we must also pay attention to the above three principles, which meets the above three principles can be seen as a boot program, at least BIOS is thinking so, although it may be you will write A section does not have any actual code.

Because BIOS reads only a sector in a 512-byte data to memory, this is obviously not enough, and now the operating system is large, so we must in the boot sector, there will be the core of the operating system on the disk. Partially read into memory, then jump to the core part of the operating system to execute.

Third, through the BIOS read disk sector

From the above description we can know that the boot program needs to read the operating system existing on the disk into memory, so we have to talk about it, how to do not read the disk without operating system (because there is still no operating system now) The content is on. Generally speaking, there are two methods to be implemented, one is the I / O port of directly read the disk, one is implemented by the BIOS interrupt. The former method is the lowest layer method (the latter method is also implemented on the basis of it), with extremely flexibility, can read the contents of the disk to anywhere in memory, but the programming is complex. The second method is a slight higher level of the previous method, sacrificing a flexibility, for example, it cannot read the contents of the disk to 0x0000: 0x0000 ~ 0x0000: 0x03FF. Why can't you read this? Here we will have to describe the interrupt processing mechanism of the CPU after power-on.

3.1 Bios Interrupt Processing

What is interrupt? I believe that people who have learned the computer will not be unfamiliar. If you don't understand the interruption, I don't know if you suggest you look at the "Computer Composition Principle" (Higher Education Press Tang Yushang), there is a very detailed description, and the general assembly materials are also There are more talks, so it is only intended to talk about BIOS to interrupt.

(Figure II)

From the above figure (Figure 2), we can clearly see that when the interrupt signal is generated, the interrupt signal generates an interrupt vector address via "Interrupt Address Forming Part", which is actually pointing to a pointer to an actual memory address, and this A jump instruction (JMP) jumps to actually handles this interrupt service program in the actual memory address. This block is specifically used to process the memory that interrupts the jump is called an interrupt vector table. Where is this interrupt vector table in memory? And where is the actual interrupt handler?

3.2 System's memory schedule (

1M

)

To answer the above two questions, we need to see how memory in the system is arranged. When the CPU is powered, the initial

1M

The memory is arranged by BIOS for us, and each byte has a special place.

(Figure 3)

By the figure above, we can now very convenient question and answer the two issues proposed above. Since 0x00000 ~ 0x003FF is where the interrupt vector table is located, the operating system in the disk cannot be read here, as this will overwrite the interrupt vector table, it is no longer able to read the disk content through the BIOS interrupt. You may say: I am calling first, read again. But in fact, the BIOS will call other interrupt assistance multiple times during reading.

3.3 Using the BIOS 13 interrupt reading disk sector

With the previous description, we can formally describe how to read the disk sector through the BIOS interrupt. To read the disk sector, we need to use the BIOS 13 interrupt, and the 13 interrupt will make the value of several registers as its parameters, so we need to set the register first during the call 13 interrupt. So how do you set registers? What registers will be used? Please see the next: AH register: Store function number, when 2, indicate use of disk function

DL Register: Save the drive letter, indicating which one drive

CH register: Save the head number, indicating which one of the magnetic head wants to read

CL register: the fan area number, indicating the starting sector to read

Al Register: Dos on the value, indicating the number of sectors to be read

After setting these registers, we can use the INT 13 instruction to call the BIOS 13 interrupt to read the specified disk sector, which reads the disk sector to the ES: BX, so before calling it, We actually need to set ES and BX registers to indicate where data is stored in memory.

Fourth, in the protection mode, the paragraph mode memory address is accessed

The write program is inseparable from memory access, however the memory accesses in the protection mode is completely different from the access in the real mode, where we will describe the access method of the memory mode. Of course, this is not intended to introduce all memory access methods and mechanisms in the protection mode, and only the transformations you need to go to the protected mode, and complete memory access, please see "Intel User Manual". Of course, as Pyos's experiments, I will gradually describe the experimental reports later.

4.1 Memory Access in Real Mode

When the computer is powered up, in "real mode", there is a CR0 register in the computer, also known as the 0 control register, in which the lowest bit is 0th, called PM (protected mode: protection) Mode) Bit, when it is cleared, the CPU is working under "real mode", indicating that the CPU works under "protection mode" when it is set. When the computer is powered up, it is cleared, and the computer is at this time is in "real mode".

Memory Accesss under "Real Mode" are composed of segment registers and offset, such as 0x: 0000: 0x0001, which often appears in the previous description, is a memory address in a real mode. The value in front of the semicolon represents the value in the segment register, the value behind the semicolon indicates the offset, and the actual physical address is shown as shown in:

(Figure 4)

However, in the protection mode, the memory address is not formed by the method shown above. So how is it formed?

4.2 Memory address formation in protection mode

The memory address is more complicated in the protection mode, we must first divide three concepts: logical addresses, linear addresses and physical addresses. The physical address is very understandable, the logical address is also understood, the address used by the program. So what is linear address?

In fact, if you do not use the paging mechanism, the linear address is the physical address, which corresponds to the physical address, linear address 0, which is physical address 0. But we know, 32-bit CPU has 32 address lines, which is accessible:

= 4GB

Memory space, this is really a big space! There are very few physical memory energy that now. How do you use 4GB space in a limited physical space? People divide physical memory into many pages, and also divide the entire 4GB linear address space into many pages identical. In linear address space, some pages may not be used when some pages are used, and the operating system allows the CPU to not use the page that is not used physical memory (stored in some place in the disk, for need Time to transfer it again), and transfer the page you need to use so that although the physical memory space is limited, all linear address space can be used. This is called a mapping from a linear address to a physical address. This is a multi-to-one mapping, which means pages in multiple linear spaces corresponding to a page in a physical space. I hope that one of the following pictures will help you. Understand such paging mechanism. (Figure 5)

The above is the simplest mapping method, which is called "direct connection" mapping, which can only be used to explain the problem, and in an actual operating system is usually "full interconnected" mapping, that is, linearity The page in the address can be in any page mapped to the physical address, as long as the physical address space is now free. However, the problem can be explained by the above figure. When the page 5 in the linear address needs to be accessed, the CPU converts it to the physical address through the address mapping mechanism and discovers the page 1 in the physical address. So the CPU will generate a so-called missing page interrupt to notify the operating system for processing, the operating system corresponding to this interrupt, and put the contents of the physical address page 1 in the disk (virtual memory) in the interrupt service program, then Load the page 5 in the linear address into the physical memory page 1. Here, when you can distinguish what is linear address, what is a physical address.

However, when the paging mechanism is not used, the linear address is used by the CPU as a physical address, and the linear address will be placed directly on the address signal line of the CPU. However, when writing applications, we usually use another address-logical address, and there is a mapping mechanism similar to the above mechanism from logical address to linear addresses, but this mechanism is often referred to as " Segment mode ", which is done by the operating system and the CPU hardware. The task of the operating system is the assignment mapping table, and the task of the CPU hardware is to map in the mapping table. Such a mapping table is also known as "Descriptive Table" in the operating system writing, there are two important descriptors, one is "Global Descriptor Table (GDT)", the other is "local descriptor Table (LDT) ", the use of these two tables is different, but their usage is approximate, and we will describe the global descriptor table.

When it comes to the table, people who have learned the data structure know that it is a data structure, and the global descriptor table is also a data structure. When this structure is placed in a continuous memory, it is called a table. The table consists of the table item, the global descriptor table consists of its entry "global descriptor", in fact, a simple term is called "descriptor", just because it is placed in the global descriptor, it has become a full descriptor. . This descriptor consists of 8 bytes. Let's take a look at its structure:

(Figure 6)

TYPE: Indicates the type of this paragraph, when the highest bit in the 4-digit is clear 0, the table is the data segment, the corresponding three digits, from left to right as E, W, A, ie data TYPE To: 0ewa. Where E represents the downward growth bit, set down to the down growth (this is mainly used in the stack segment of the dynamic change in the size, if it is a downward growth, the size limit of the dynamic change segment will make the stack space Add it to the bottom of the stack. If the size of the stack does not need to change, then this segment can either grow down, or may be a paragraph with a non-downward growth); W represents a writable, set 1 means writable; The visited bits (if the CPU has accessed it, this bit will be set). The highest bit in the 4-bit is set to 1 indicates that it is a code segment, the corresponding three digits, from left to right as C, R, A, ie the type of code segment is: 1CRA. Where c is indicated whether this code segment is a consistent code segment, if C is set 1, it indicates that this is a consistent code segment. The consistent code segment is mainly used for privileged access control, which will be discussed in detail in the later experimental report; R indicates whether this paragraph is readable, and 1 means readable; A means being accessed, which is the same as the foregoing.

S: Time indicates that this is a code segment or data segment descriptor, indicating that this is a system segment descriptor. The system segment descriptor is also known as a special segment descriptor, including: Local Descriptor Table (LDT) Descriptor, Task Status Section (TSS) Descriptor, Call Door Descriptor, Interrupt Door Descriptor, Trap Gate and Task Door Descriptor Wait.

DPL: Represents privilege level, from 00 ~ 11, total 0, 1, 2, 3 four privileges

P: 0 means that this descriptor is invalid, it cannot be used

AVL: Leave to programmer

D / B: When 0, it means that it is a 16-bit segment, indicating that it is a 32-bit segment.

When G: is 0, the unit indicates that the unit is 1 byte, and the unit indicates the unit of the segment is 4KB, and the minimum 12 bits of the segment offset will not be detected in the segment limit. (This may now be unbearable, but I will explain now).

There are two parties in this, one is "base address", one is "segment". The base address should be better understood that it gives the starting address in linear memory. For "segment", as the name suggests, it is the limit of segment size. However, it is a bit special, and the maximum accessible address CPU for a segment is calculated by the following formula:

Segment base address segment limited value * segment limited unit = the maximum accessible address of this paragraph

If an offset address is greater than this maximum accessible address, the CPU will generate an error interrupt, so that a program can prevent illegal access to another program, which plays a protective role in memory, "Protection Mode "is named.

Therefore, if the limit is 0, then the maximum accessible address of this paragraph is the base address, so when the segment limit unit is one byte, the size of this segment is 1 byte; when the paragraph limit unit is 4KB Because the CPU will not detect the minimum 12 bits of the offset, the 12-bit maximum may be 0xFFF, so the accessibility range of this segment is 4KB, so:

(Different value 1) * Duan unit = this segment size

Now we can formally began to describe how to access memory in the protection mode. It is necessary to emphasize "Section Mode" because there is a memory access mode-page mode in the protected mode, which is responsible for converting a linear address to a physical address. "Page Mode" is also based on segment mode. When it is not used, the linear address will be placed directly on the address line as a physical address. "Segment mode" is inevitable, so "pure page mode" just uses the entire linear address as a whole, there is no way to truly bypass "segment mode" because this is specified by the CPU memory access mechanism. . This article only describes segment mode. We already know that the logical address from the program to the linear address is completed by "descriptor", and the "descriptor" is placed in the descriptor table, then there are many descriptors in a descriptor, Which descriptor is you elected? This is determined by a claim, which will point out that the first few descriptors in the table have a dedicated term to describe, often referred to as "segment selector". "Segment Selection" consists of 2 bytes, and let's take a look at what information it provides:

(Figure 7)

among them:

RPL: Indicates the privilege level, 00 ~ 11, and four privilege levels, as described above.

TI: Time indicating that this is a selection of the global descriptor table, indicating a local descriptor table.

The index value: used to indicate the second descriptor in the table. The index value has a total of 13 bits, so each descriptor table can have 8K entries, and a group item is as mentioned earlier, and a descriptor table is up to 64K.

I don't know if you pay attention to such a fact, if you use the last 3 position of "Segment Selection], this whole segment selector is actually a descriptor in the descriptor table offset! Here we can find that Intel's engineer is really very delicate, so arrangement, you can make the speed of choosing a descriptor, because the last 3 digits of the segment is clear and the descriptor table The base is added, and the physical address of a descriptor can be obtained immediately. You can get a descriptor directly through this address. So where is the base address of this descriptor table?

The base address for the descriptor table is the start address of this descriptor table in memory, that is, the memory address in which the first descriptor in the table is located, and the system is stored in two special registers, one for Store the base address of the global descriptor table, called "Global Descriptor Table Register (GDTR)", another base address for depositing a local descriptor table, called "local descriptor table register (LDTR)", Their structure is shown below:

(Figure 8)

Among them, the table is limited to the size limit of the table, and its use is similar to the species described above, so it is not described herein.

In the protection mode, the segment register in the previous real mode is still useful, but it is no longer used to store the base address of the segment, but used to store the "segment selection", its name is also become "segment selector Register ", when accessing memory, we need to give" Segment Select Subs ", not a section base address.

For example, I now want to use the second entry in the global descriptor table, that is, the second "segment descriptor", this "segment selector" needs to be constructed as follows:

RPL: 00, because we are now writing operating systems, working in 0 privileges

TI: 0, we use global descriptor

Argument value: 1, we use the second global descriptor, the first global descriptor number is 0, the second is 1, therefore, our "segment selector" is: 0000 0000 0000 10000, i.e., 0x0008, so For 0x0008: 0x0000 such a logical address, in the protection mode, it should be regarded as the segment described in the global descriptor segment, and the offset is 0 memory address.

How is the linear address of this logical address? Please see the following picture:

(Figure 9)

I believe that you can clearly see how a logical address is converted to a 32-bit linear address.

V. PYOS boot program

PYOS is an operating system in writing. It is a project in an experiment. I have been talking about the purpose and motivation of the written, here, here, talk about the contents of the PYOS boot program on this article, Refer to Linux 0.11 kernel boot program during writing, but PYOS is not Linux-based, there are many different places in their boot programs. Let's take a look at the memory arrangement of the entire boot area of ​​PYOS:

(Figure 10)

The above picture is PYOS memory schema, which is also a bootstrap process. PYOS is a two-stage boot system. The first is BOOT reads in BIOS. Subsequent BOOT reads setup, setup reads the system program to the temporary storage area, then put The System program moves to the top of the memory and establishes a segment descriptor and establishing GDT to the SYSTEM program, then switching the CPU to the protection mode, and finally jumps to the System program. To this PYOS system is guided, the System program will be PYOS real System kernel. The data storage area in the figure is used to store parameters that need to be passed between boot, setup, and PYOS three programs.

The reason why the two level guidance is mainly considering the convenience of future expansion, and each program is almost independent, and the Boot or Setup can be rewritten to provide more optional boot mode. The SYSTEM program is because the data cannot be read directly to the original interrupt vector table in the interrupt vector table. After the data is read, the program is moved to the internal interrupt to cover the original interrupt. Vector table, for the interrupt vector table in the protection mode, will be established by the System program, handing over a complete and clean memory for System.

For the PYOS process memory schedule, ready to refer to Linux 0.11, the memory arrangement is as follows:

(Figure 11, source "Linux 0.11 kernel code full notes")

A process

64M

Space, 4GB /

64M

= 64, that is, the system's maximum number of processes is 64. So a segment is limited to: 64MB, each process takes up two descriptors in the global infrastructure, one is a data segment descriptor, one is a code segment descriptor, and the segment is 64MB.

Six, PYOS boot program source code

The entire source code for the PYOS boot program will be provided below, because System has not been completely completed, so this is just a simple printing of a character to show the boot work, and there is a more detailed note in the code. If it is still not clear Place, you can go to http://purec.binghua.com (pure C forum) operating system experimental area, view PYOS previous experiment reports, with a very detailed annotation and related principles, and describe how to compile and experiment.

; File name: boot.asm

; Author; Xie Yubo

Emailv: xieyubo@126.com

;

The memory allocation is as follows

The memory start address is 0x90000

The maximum end address is 0x9fffff

Maximum total of 64KB

All startup code is convenient to call within one segment

The startup code is divided into two parts, one is boot, one is setup, this is the design of Linux 0.11

But in fact, Boot will not move yourself to 0x90000, and directly jump to 0x90100.

; 0x90000 ~ 0x900FF (256B) system reserved to store some key data from BIOS

0x90100 ~ 0x904FF (1KB): Start storage of Setup, setup size is 1KB

[BITS 16]; compiled instructions

[ORG 0X

7C

00]

; ------------------------------------------------- ------------------------------------------

JMP

Main

; ------------------------------------------------- ------------------------------------------

Data definition

MSG DB "Loading Pyos ..."; Output Information

DB 13, 10, 0; 13 Represents the carriage return, 10 indicates the wrap,

0 indicates the end of the string

BootSeg EQU 0x0000; Segment base address in Boot

Setupseg EQU 0x9000; Segment base address in SETUP

Setupoffset EQU 0x0100; offset in SETUP

Setupsize EQU 1024; SETUP size, must be a multiple of 512

Bootdriver DB 0; Save the boot drive letter

; ------------------------------------------------- ------------------------------------------

SHOWMESSAGE:

; The following program behavior displays the output information

MOV AH, 0x0E; Set display mode

MOV BH, 0x00; set page number

MOV BL, 0x07; set font properties

.NEXTCHAR:

Lodsb

OR Al, Al

JZ .Return

INT 0x10

JMP .nextchar

. Return:

RET

; ------------------------------------------------- ------------------------------------------

Main

:

MOV [BootDriver], DL; get the started drive letter; the following program sets the data segment

Mov AX, BootSeg

MOV DS, AX

MOV Si, MSG

Call showMessage; display information

Read setup

; Read 0x90100 from the second sector of the disk

.readfloopy:

MOV AX, Setupseg

Mov ES, AX

MOV BX, Setupoffset

MOV AH, 2

MOV DL, [BootDriver]

MOV CH, 0

MOV CL, 2

MOV Al, Setupsize / 512; reading in sector (2 a total of 1KB)

INT 0x13

jc .readfloopy

; Save the start drive number at 0x90000

MOV Al, [BootDriver]

MOV [0], Al

Jump

JMP Setupseg: Setupoffset

; ------------------------------------------------- ----------------------------

Times 510 - ($ - $$) DB 0

DB 0x55

DB 0xAA

; File name: setup.asm

; Author; Xie Yubo

Emailv: xieyubo@126.com

This setup program completes the boot work of Boot,

; Includes reading the system information from the BIOS in the specified location

; Initialize the GDT, LDT table, complete the conversion from the protection mode to real mode

The code of the real mode is also read by this program.

[BITS 16]

[Org 0x0100]

; ------------------------------------------------- ------------------------------------

JMP

Main

; ------------------------------------------------- ------------------------------------

Setupseg EQU 0x9000

Setupoffset EQU 0x0100

Setupsize EQU 1024; SETUP size 1KB, must be a multiple of 512

SYSTEG EQU 0x0000

SYSTEMOFFSET EQU 0x0000

Systemsize EQU 1024; SYSTEM size 1kb, this value must be a multiple of 512

The actual value can not match

; Define the descriptor of the temporary GDT table below

A total of three segments, one empty segment is reserved by Intel, a code segment, a data segment

GDT_ADDR:

DW 0x7FFF; GDT table size

DW gdt; GDT table location DW 0x0009

GDT:

GDT_NULL:

DW 0x0000

DW 0x0000

DW 0x0000

DW 0x0000

GDT_SYSTEM_CODE:

DW 0x3FFF; segment limit (0x3FFF 1) * 4KB = 64KB

DW 0x0000

DW 0x

9A

00

DW 0x

00C

0

GDT_SYSTEM_DATA:

DW 0x3FFF

DW 0x0000

DW 0x9200

DW 0x

00C

0

; ------------------------------------------------- ------------------------------------

Waiting for the keyboard controller idle subroutine

EMPTY_8042:

IN Al, 0x64

Test al, 0x2

JNZ EMPTY_8042

RET

; ------------------------------------------------- ------------------------------------

Main

:

Initialization registers because BIOS interrupts and CALLs use the stack or SS register

; When the CPU is started or reset, it is initialized by the BIOS, and now the segment transfer is performed, we need to reset

MOV AX, Setupseg

MOV DS, AX

Mov ES, AX

Mov SS, AX

MOV SP, 0xFFFF

; ------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------

What useful information should be read from the BIOS, it is still not sure, so this function block is temporarily skipped

; -----------------------------------------------

; 0x90000 (1B): Save the boot drive letter, deposited by the boot program

; ------------------------------------------------- -------------------------

Next, read the SYSTEM to the SETUP program.

Because the 0x00000 is now placing the BIOS interruption, I can't read the SYSTEM directly at 0x00000 directly.

Otherwise, the BIOS interrupt reading disk will not be called.

.readfloopy:

MOV AX, Setupseg

Mov ES, AX

MOV BX, Setupoffset setupsize

MOV AH, 2

MOV DL, [0]

MOV CH, 0

MOV CL, 1 1 setupsize / 512; start sector where SYSTEM is located

The first 1 refers to the count from 1; the second 1 is the number of sector of the boot.

MOV Al, SystemSize / 512; read the number of sectors (2 sectors a total of 1KB)

INT 0x13

jc .readfloopy

; Next, the read SYSTEM is moved to 0x00000 position

CLD

MOV Si, Setupoffset setupsize

MOV AX, SystemSeg

Mov ES, AX

MOV DI, Systemoffset

MOV CX, SystemSize / 4

REP MOVSD

; Below begins to initialize the protection mode

CLI;

LGDT [GDT_ADDR]; a descriptor loaded with GDT

; Turn on the A20 address line below

Call Empty_8042

Mov al, 0xd1

OUT 0x64, Al

Call Empty_8042

MOV Al, 0xDF

OUT 0x60, Al

Call Empty_8042

The following settings enter the 32-bit protection mode operation

MOV Eax, Cr0

OR EAX, 1

MOV CR0, EAX

JMP DWORD 0x8: 0x0

; ------------------------------------------------- ------------------------------------

Times 1024 - ($ - $$) DB 0

; File name: kernel.asm

; Author; Xie Yubo

Emailv: xieyubo@126.com

[BITS 32]

[ORG 0x0]

; ------------------------------------------------- -----------------------------------------

JMP

Main

; ------------------------------------------------- -----------------------------------------

Main

:

Set the register

MOV AX, 0x10

MOV DS, AX

MOV CL, '1'

MOV [0xB8000], CL

MOV CL, 0x04

MOV [0xB8001], CL

JMP $

There is also a place in the above programs and has not been mentioned in this article and the previous experimental report. This is the problem of the A20 address line. It is very detailed in "Linux 0.11 kernel source code full note" in "Linux 0.11 kernel source code" for A20 address line. Description, the author also lists several other ways to open A20 address lines, and analyzes possible problems. This is a very good book, recommend everyone to read. Pure C Forum (http://purec.binghua.com) You can download the electronic version of this book (PDF format) or another other relevant resources can be found. Below is the screenshot of the runtime, now it can only boot, what can't do it, I hope that next time it can do ~~

Reference

1. "IA-32 Intel® Architecture Software Developer's Manual Volume 3: System Programming Guide" (Intel 2001)

2. "Linux Core 0.11 Complete Notes" (Zhao Wei, 2003)

3. "Computer Composition Principle" (Tang Yushang, Higher Education Press)

[Full text · Responsible Editor: Iamxiaohan @ hitbbs]

Note: This article is published in the << Pure C Forum · Electronic Magazine >> 2004.10 (http://purec.binghua.com/soft/class2/dl_hpcem/200410/74.html)

转载请注明原文地址:https://www.9cbs.com/read-91189.html

New Post(0)