First step: Load the kernel into memory

Source: Internet
Author: User
Tags clear screen goto pack printf readable strlen

In the operating system learning notes, basically completed the "self-write operating system," the third chapter of several experiments (in addition to the paging mechanism experiment). The next step is to write your own operating system this long March first steps.

Before taking the first step, there are a few things to explain briefly.

First, name the operating system that will be implemented as: Maios. Please don't ask me what the meaning of this name is ...

Second, what is the purpose of making this operating system, or who is the user of this operating system? To put it simply, Maios is a personal operating system designed for its own development and for its own use. As for the specific functions to be implemented, there is no detailed explanation here.

Finally, what do you mean by scheduling and completion deadlines, hmm, schedule and deadlines?

Although writing their own operating system, but the beginning of these steps, basically or according to the "self-write operating system," the following chapters of the pace slowly.

The task in this step is to try to load the operating system kernel in the floppy disk (external memory) into memory, and to give execution to the kernel.

We know that the boot process of the operating system is generally: boot (boot) in the boot sector to load the loader (loader) into memory, by loader to complete some necessary initial preparation, then the operating system kernel loaded into the appropriate location of memory, and finally the execution of the power to the kernel ...

But because it is to write to their own operating system, there is nothing to initialize at the beginning, I would like to lazy, omit the loader (loader). Work directly on boot (boot) to load the kernel and into protected mode, then jump to the kernel entry point. In the future if the boot can not meet the needs, add loader or something;)

The following is the relevant code:

Code:run.c

File: Run.c//function: Run this program, will automatically compile "boot.c" file with "kernel.c" file, generate "maios.img" image file,//And then start the virtual machine running the image file in the operating system. You do not have to close this program while you are writing and modifying your code. After you change the code and save it, after you click Enter in this program (console), the modified code is compiled again. This makes it easy and quick to modify the operating system;)//run with the test written under Windows: Use the YC09 compiler to compile the program. Author: Miao//Time: 2010-5-13 #define FDISK_SIZE 1474560//Mirror size: 1.4MB//virtual machine set char *maiossrc = "megs:32/n" "Romimage:file=bi Os-bochs-latest, address=0xf0000/n "" vgaromimage:vgabios-elpin-2.40/n "" Floppya:1_44=maios.img, status=inserted/n " "Boot:a/n" "log:maios.out/n" "mouse:enabled=0/n" "keyboard_mapping:enabled=1, map=x11-pc-us.map/n"; Compiles the specified code file and puts it in the mirror at the specified location//filename: The file name to compile Imgbuffer: The image buffer to be saved//startindex: Specify the starting position limitsize: Post-compilation program-qualified int compilefile ( Char *filename, byte *imgbuffer, int startIndex, int limitsize) {char *tempbuffer;//Save the Post-compilation program's temporary buffer//compile the code in FileName, and put the result in t empbuffer int length = Yc_compilecpp (&tempbuffer, fileName, 0, 0); if (length <= 0 | | length > Limitsize) {printf ("File:%s has some errors or file is too large (more than%d bytes):%d bytes/n", filename,limitsize,length); ret URN 1; printf ("File:%s" was compiled successfully, size:%d bytes.) /n ", fileName, length); Put the compiled program into the mirrored boot sector buffer to specify the starting position memcpy (Imgbuffer + startIndex, tempbuffer, length); Free (tempbuffer); return 0; } int main (int argc, char **argv) {char * FilePath = argv[0];/////Current folder path char Filename[max_path];////For caching individual filenames//The full path to the executable file The path removes the file name, keeping the folder paths for (int i = strlen (FilePath); Filepath[i]! = '//'; i--) filepath[i] = '/0 '; byte *imgbuffer = new byte[fdisk_size];//Mirror buffer _start://Compile bootstrapper and place in boot sector if (Compilefile ("boot.c", Imgbuffer, 0, 509)) Goto _ Restart 0000H-01FFH is a fat boot sector [NO. 0 sector] with a AA flag ending length of 200H (512) bytes imgbuffer[510] = 0x55; IMGBUFFER[511] = 0xaa;//flag Floppy Boot end//compile kernel if (compilefile ("kernel.c", Imgbuffer,, 65536*8)) goto _restart; Create an operating system image maios.img if (Yc_writefile ("maios.img", Imgbuffer, fdisk_size)! = fdisk_size) {printf ("Write:%s file" Error occurred during the process.) /r/n ", fileName); Goto _restart; } printf ("/n%s created successfully. /n ", fileName); Generate operating system virtual machine profile Maios.src yc_writefile ("Maios.src", Maiossrc, strlen (MAIOSSRC)); Run the virtual machine yc_winexec (strcat (strcpy (fileName, FilePath), "Bochs.exe"), "-q-f maios.src"); _restart:printf ("/n" click Enter to recompile the run.) /n/n/n "); while (GetChar ()! = '/n '); Goto _start; return 0; }

Code:global.h

File: Global.h//function: Common header file for operating system//Author: Miao//Time: 2010-5-13//define GDT (Global Descriptor) Property #define DA_32 0x4000//32-bit segment #define DA_DRW 0x92// Existing read-write data segment property value #define DA_DRWA 0x93//existence of accessed read-write data segment type value #define DA_CR 0x9a//Existing executable readable Snippet property value #define Da_c 0x98//Existing executable readable code snippet property value Define the LDT (local descriptor) attribute #define DA_LDT 0x82//Local Descriptor Type value//define Gate Property #define Da_386cgate 0x8c//386 call class//Descriptor Privilege level (0~3: High to low) #define Da_dpl0 0x00//Descriptor Privilege Level 3//select sub #define SA_TIL 0x4//Will TI position 1, indicating is LDT Select sub typedef unsigned int t_32; 4-byte typedef unsigned short t_16; 2-byte typedef unsigned char t_8; 1-byte typedef int T_BOOL;//4 byte typedef unsigned int T_PORT;//4 byte//Bucket Descriptor/System Segment Descriptor struct Descriptor//Total 8 bytes {T_16 limit_ Low Limit 2 bytes t_16 base_low; Base 2 byte t_8 base_mid; Base 1 byte t_8 attr1; P (1) DPL (2) DT (1) TYPE (4) 1 bytes t_8 limit_high_attr2; G (1) D (1) 0 (1) AVL (1) Limithigh (4) 1 bytes t_8 Base_high; Base 1 bytes}; #define DESCRIPTOR (BAS,LEN,ATTR) {/(len) & 0xFFFF,/(BAS) & 0xFFFF,/((BAS) >>16) &0xff,/(attr) &amp ; 0xFF,/(((attr) >&GT;8) &0xf0) + (((len) >>16) & 0x0f),/((BAS) >>) & 0xFF}/#define Gate (Slector,offset,dcount , attr) {/(offset) & 0xFFFF,/Slector,/(DCount) &0x1f,/attr,/((offset) >>16) &0xff,/((offset) & gt;>) & 0xFF}/

Code:boot.c

File: boot.c//function: The boot program of the operating system, loading the kernel program (several sectors after boot sector content) into memory 0x7f00 (omit loader program)//after loading the kernel, enter protection mode and jump to the entry point of the kernel program (memory 0x7f00)// Run: Run.exe automatically compiles boot.c and generates an IMG and calls Bochs to run the program. Author: Miao//Time: 2010-5-13 #define YCBIT 16//Tell the compiler to compile the program in 16-bit format #define ycorg 0X7C00//Tell the compiler to load the program at 7C00 #include "global.h"/ /GDT bounds, only responsible for jumping to protected mode, will load new GDT descriptor label_gdt[] = {//segment base segment bounds attribute descriptor (0, 0, 0), descriptor (0x7f00, 0XFFFFF, Da_ CR | DA_32),//32-bit code snippet, executable readable}; GDT Selector, set the offset value according to the GDT bounds #define SELECTORCODE32 8*1//points at 32-bit segment #pragma pack (1) struct GDT_PTR {unsigned short size; void *a Ddr }; #pragma pack () gdt_ptr gdtptr = {sizeof (LABEL_GDT), (char*) LABEL_GDT}; Segment bounds, base address asm Void Main () {MOV ax, CS mov ds, ax mov ax, 0x0 mov es, ax//clear screen mov ah, 06h//screen initialization or roll mov aL, 00h//ah = 6, AL = 0h mov bx, 1110h//blue background mov cx, 0///upper left corner: (0, 0) mov dl, 4FH//No. 0 column mov dh, 1fh//No. 0 Line int 10h//display interrupt//number of sector information after the floppy boot sector (kernel program) move to memory mov al, 0x04//Move 4 sectors mov ah, 0x02//= read floppy disk sector to memory MOV bx, 0X7F00//move to position: ES:BX MOV cl, 0x2//Start sector (bit 0-5), track (cylinder) The height of the number 2Bit (bit 6-7) mov ch, 0x0//track (cylinder) number low 8 bit MOV dl, 0x0//drive number (if for hard disk, bit 7 1) mov dh, 0x0//magnetic number one int 0x13 mov ax, CS mov es, ax LGDT gdtpt R//Load GDTR CLI//OFF interrupt//Open Address line A20 in Al, 92h or Al, 00000010b out 92h, AL//ready to switch to protected mode, place CR0 PE bit for 1 mov eax, CR0 or eax, 1 mov CR0, EAX//Real into protected mode (kernel entry point) jmp DWORD selectorcode32:0x0}

Code:kernel.c

File: kernel.c//function: Kernel program, the current function is only to display a string. To demonstrate the successful loading of the kernel into memory and running kernel code. Run: Run.exe automatically compiles boot.c and generates an IMG and calls Bochs to run the program. Author: Miao//Time: 2010-5-13 #define YCBIT 32//Tell the compiler to compile the program in 32-bit format #define ycorg 0x0//This value will generate address base offset for variable functions such as at compile time, simple, set to 0 # Include "Global.h" #define PROTECADDR 0x7f00//Enter protected mode after the program base #define RETF DB 0XCB//Because the YC09 compiler does not recognize the directive RETF, use a macro to directly define instructions RETF ASM VO ID dispstr ();//Display a string, you need to set the ESI point to the string address, EDI point to the starting position of the string//GDT Select child #define SELECTORCODE32 8*1//point to the 32-bit segment code snippet, executable readable #define Selectorvideo 8*2//points to the first address of the memory #define SELECTORDATA32 8*3//points to 32-bit segments so that variables in the program can be read and written #define Selectorldt 8*4//point to the LDT, Through this jump to the local task//Gate Selector sub-#define SELECTORCALLGATETEST 8*5//Point Gate Task//gdt bounds, note that this is different from the GDT in Boot.c, the new GDT will be loaded immediately after jumping from boot.c. Descriptor label_gdt[] = {//segment base segment bounds attribute descriptor (0, 0, 0), descriptor (PROTECADDR, 0XFFFFF, DA_CR | DA_32),//32-bit code snippet, executable readable descriptor (0xb8000, 0xFFFF, DA_DRW),//memory address segment, readable writable descriptor (protecaddr, 0XFFFFF, DA_DRW | DA_32),//Make 32-bit code segment variable can read and write}; #pragma pack (1) struct GDT_PTR {t_16 size; void *addr;} Gdtptr = {SiZeof (LABEL_GDT), (char*) &label_gdt + protecaddr}; Segment bounds, base address #pragma pack () char msg1[] = "I am in kernel now!"; Kernel entry point ASM void Main () {LGDT cs:gdtptr//Load new GDTR mov eax, selectorvideo mov gs, AX//Video Segment Selector (purpose) mov eax, SelectorData32 Make 32-bit code snippet variable (printplace) can read and write mov ds, AX//below display a string (display has reached protection mode information) mov esi, &AMP;MSG1//source data offset mov edi, ((80 * 0 + 0) * 2) Destination data offset. Screen No. 0, column No. 0. Call Dispstr died:jmp died}//Display a string, you need to set the ESI point to the string address, EDI to the starting position of the string asm void Dispstr () {mov ah, 14h//Blue bottom red character (ah = 14h)/ /loop outputs the string one by one _dispstr:mov al, ds:[esi]//because it is readable, to use CS to point to the current segment of the MSG1 String Inc ESI CMP al, '/0 '//To determine if the string ends JZ _stop mov Gs:[edi], ax Add EDI, 2 jmp _dispstr _stop://show complete RET}

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.