Recently started to do MIT's Jos, did a period of time, intends to summarize, as a basis for a few experiments, the wrong estimate will be many, but also ask you a lot of advice.
A Lab1-booting a PC
LAB1 is about the PC boot process, the PC starts to follow the BIOS load (real mode)->bios jump to boot loader (the address in Jos is 0x7c00)->boot loader The process of importing the OS kernel. In the first step, you can use GDB to look at the PC power-up from the start of each BIOS assembly instructions, basically about some hardware IO settings, there is no more 0xfe05b, the students interested in these BIOS instructions can see here.
The next step is to jump to boot loader, first executing the assembly code in Boot.s, where the real mode is converted into protected mode. The values of several constants are set first, such as prot_mode_cseg=0x8, which represents the segment offset of the snippet in the new segment to 0x8 Then we look at the definition of GDT (in the last few lines of BOOT.S), which defines the GDT used after jumping to 32-bit protected mode, noting that the kernel-defined GDT will be reused after the kernel is loaded, and there is a difference between the two. This defines the three segments of the GDT: The Empty segment (Seg_null), the code SEG, and the data seg, taking the definition of the code snippet as an example: SEG (sta_x| Sta_r, 0x0, 0xFFFFFFFF) (see inc/mmu.h on line 145th for a definition of the SEG, the three parameters that seg accepts are to define the type, base address, and segment limit of a segment), which defines the type, base address, and bounds of the code snippet, You can see that the base site is 0x0, that is, the virtual address = Physical address, which is equivalent to shutting down the segment mapping. Next you can see the code for the real mode jump to 32-bit protected mode:
1. CLI off interrupt, ensure that at this time Boot.s is the only execution of the program;
2. Enable A20 bit, this step is interested in Google Bar O (∩_∩) o~ and understanding jump relationship is not big
3. LGDT GDTDESC//Loading defined GDT,GDTDESC is the GDT address immediately defined by the GDT
MOVL%cr0,%eax//The next three sentences modify the PE bit of the CR0 register to enable 32-bit protected mode
ORL $CR 0_pe_on,%eax
MOVL%eax,%cr0
4. Long jump instruction ljmp $PROT _mode_cseg, $protcseg jump to the next code to skip the remaining 16-bit instructions. Here we see that the new GDT is already functioning, seg= prot_mode_cseg, Offset=protcseg, because Cseg's base address is 0, the program jumps to the protcseg offset of the code snippet
5. Where's the protcseg? Very conspicuous. It is in the following, the instructions are re-written to the DS, ES and other segments of the value of the register, the last sentence to jump to the Bootmain function, start reading into the kernel, OK, real mode jump to the protection mode to complete. Bootmain function is located in Boot/main.c, is the operation from the hard disk sector to read the kernel, a variety of IDE IO instructions is very troublesome, patience of children's shoes to slowly realize it O (∩_∩) o~
The above instructions can be seen in the compiled obj/boot/boot.asm, it is recommended that you look at this file, you can have a clearer understanding of the whole process.
After jumping to the Jos kernel, the first file executed is KERN/ENTRY.S. The main role and layout of this document is similar to the above Boot.s, which is the process of establishing a new GDT, and why a new GDT is needed here. The reason is that the kernel's link address and the load address are different, in order to address the correct physical addresses, we must subtract the virtual address kernbase, get the correct physical address, this is the new GDT (defined in Entry.s last few lines, MYGDT), Codeseg and Dataseg's base site are defined as the reason for-kernbase.
However, there are several different two files, one is defined in Entry.s a RELOC (x) macro, RELOC (x) = ((x)-Kernbase), which is used to load the new GDT address in the LGDT instruction, because the new GDT is not yet in force, still perform the old GDT , that is, the segment base address = 0, and the second is to define the function call stack base MOVL $0X0,%EBP, which is also the end condition of the exercise 10 loop jump. The kernel then calls the I386_init () function, which is the key to the next few experiments.
As for a few exercise, personal feeling is not very difficult, after all, there are corresponding source code on the Internet, Khan ... I do this version of Tsinghua has an additional exercise--detecting Processor Features, is to read the EFlags register to get the information about the CPU, read and write register functions are also implemented well, the call to detect a bit better. In order to flip the 21st bit of the register value, the corresponding main code is pasted in the way of XOR 1:
bool
Is_cpuid_supported ()
{
uint32_t eflags=read_eflags ();
Write_eflags (eflags^0x00200000);
if (Read_eflags () ==eflags) return 0;
return 1;
}
by Feitian