MIT operating system experiment mit Jos lab1

Source: Internet
Author: User
Jos lab1


Hey, the experiment environment is quite friendly. A lot of things are ready, and the focus is on the theoretical validation.


MIT is the best school to change and lead the world ~

At Peking University in China, the OS labs of schools such as handed-In are all directly using Jos. This evidence is still easy to find... to explain what is self-evident...

Certificate --------------------------------------------------------------------------------------------------------------------------------------------



Part 1: PC Bootstrap

This section briefly introduces how to use qemu and GDB to jointly tune the kernel...

Open two terminal statements and go to the lab directory. Then, input make qemu-GDB and input make GDB to view the following figure.

Interestingly, the step and next commands cannot be used during GDB debugging because the system still has a set stack at the BIOS information reading stage (stack information is required ), only step I commands that execute Assembly commands in a single row are available, and a question mark (?) is displayed ?? () Information. The currently executed command is not in any function.








Part 2: The Boot Loader


After reading the BIOS information, run the kernel code.

The President jumps to the 0x7c00 address.


When the BIOS finds a bootable floppy or hard disk, it loads the 512-byte boot sector into memory at physical addresses 0x7c00 through 0x7dff, and then uses a JMP Instruction to set the Cs: IP address to 0000: 7c00, passing control to the boot loader.




Switch from real mode to protected model, and the address length is changed from 16 bits to 32 bits! Observe the format of the [0: 7c2d] To 0x7c32 in GDB. We can also detect this point.



The next step is to set the data segment code segment and other information under the protected model, and then jump to bootmain. Note that the stack is set before the jump to bootmain!

Movl $ start % ESP

This is the earliest Kernel stack we have seen.



You need to answer some questions in this section:

Be able to answer the following questions:
At what point does the processor start executing 32-bit code? What exactly causes the switch
From 16-to 32-Bit mode?

Execute 32bit code when you jump from real model to protected Model


What is the last instruction of the boot loader executed, and what is the first instruction of
Kernel it just loaded?

The last line of Boot Loader code:



Where is the first instruction of the kernel?

First, you must locate the point pointed to by elfhdr-> e_entry, while elfhdr points to 0x10000 (forcibly converted to struct elf)


Here, elfhdr is initialized through readseg. The initialized data source is the kernel image on the hard disk.

So where can we find the location pointed to by elfhdr-> e_entry? Disassemble the kernel image!

Objdump-X./obj/Kern/kernel


The starting address of the kernel is 0x0000c.


When a breakpoint is set, the first statement of the kernel here is

Movw $0x1234, 0x472



We can find this code in Kern/entry. S.



The entry symbol in the kernel image points to the start address of the code of the file entry. S.

You will see the entry symbol in the disassembly! Value is 0xf00000c. This is the kernel entry address on our image. It does not conflict with 0x0000c. The former 0x1000c is converted from the latter 0xf00000c.


This kind of conversion was manual at the beginning. I found the same experiment code for 09 and 10 years.

Previous Code (left) current Code (right)

I found that there is a manual & Conversion here, and the code I used in 2014 does not have this forced conversion, so it has been a long struggle for this issue...

Many machines don't have any physical memory at address 0xf0100000, so we can't count on being
Able to store the kernel there. instead, we will use the processor's memory management hardware to map virtual address 0xf0100000 (the link address at which the kernel code expects to run) to physical address 0x00100000 (where the boot loader loaded the kernel into physical memory ). this way, although the kernel's virtual address is high enough to leave plenty of address space for user processes, it will be loaded in physical memory at the 1 MB point in the PC's Ram, just above the BIOS Rom. this approach requires that the PC have at least a few megabytes of physical memory (so that physical address 0x00100000 works ), but this is likely to be true of any PC built after about 1990.


Because the hardware has mapped 0xf0100000 to 0x100000, and 0xf00000c is mapped to 0x0000c in the same way,... in essence, manual conversion is actually a direct conversion from hardware (It feels even more obscure ~ It's better to manually switch... it took me an hour)

We can also know this from the startup information (previously this message was ignored by me)


Later, I found myself a huge scum... I could see the information when I was using the objdump... I only blame myself for being weak, Buji Island...

VMA = Virtual Memory Address LMA = load memory address

So, 0xf0100000 is the virtual address, which is the LMA and physical address used for loading.





How does the boot loader decide how many sectors it must read in order to fetch the entire kernel from disk? Where does it find this information?


I have some questions here. They are different from others' answers.

Some people think it is determined and read from the kernel image according to the ELF format file storage information.

The answer is:


I think the answer is:

According to the main. C source code, the number of sectors read is 8, and the size of each sector is 512 bytes.






Back in Boot/main. c, the pH-> p_pa field of each program header contains the segment's destination physical address (in this case, it really is a physical address, though the elf specification is vague on
The actual meaning of this field ).





Part 3: The Kernel



Mainly add some code.

First read the Code listed below

Read through Kern/printf. C, lib/printfmt. C, and Kern/console. C (I am doing side-read ...)


"We have omitted a small fragment of Code-the Code necessary to print Octal numbers using patterns of the form" % O ". Find and fill in this code fragment ."

Find printfmt. C and add the following code:


Here, because many mechanisms are sound, we only need to follow the hexadecimal output to make a preliminary processing of the octal output.


Be able to answer the following questions:
1. Explain the interface between printf. C and console. C. Specifically, what function does console. c
Export? How is this function used by printf. C?
 

All printf-related functions (in Jos) are essentially "one layer of shell". It calls the putch function in console. C.

Furthermore, the implementation of printf utilizes the variable length technique.

For the use of this technique, I have a detailed description here: http://blog.csdn.net/cinmyheart/article/details/24582895



2. Explain the following from console. C:


It mainly checks whether the current screen's output buffer is full. Here, note that memmove actually moves the address pointed to by the second parameter to the address pointed to by the first parameter, N byte is specified by the third parameter.

If the buffer is full, overwrite the first line of the screen to move up one line by one, empty the last line, and fill the for loop with ''(Space ), finally, place crt_pos at the beginning of the last row!






3. For the following questions you might wish to consult the notes for lecture 2. These notes cover GCC's calling convention on the x86.

Trace the execution of the following code step-by-step:


int x = 1, y = 3, z = 4;cprintf("x %d, y %x, z %d\n", x, y, z);



In the call to cprintf (), to what does FMT point? To what does AP point?

FMT points to the format specifier string. AP points to a va_list Type Variable

But where is the code? I have never found... and will find update later.


List (in order of execution) each call to cons_putc, va_arg, and vcprintf. for cons_putc, list its argument as well. for va_arg, list what AP points to before and after the call. for vcprintf list the values of its two arguments.




4. Run the following code.


unsigned int i = 0x00646c72;cprintf("H%x Wo%s", 57616, &i);

What is the output? Explain how this output is arrived at in the step-by-step manner of the previous exercise. Here's an ASCII table that maps bytes to characters.

The output is he110 world.

I just want to say... Haha... the principle is that it is very simple to output according to ASCII.

Note that the % s part is printed at the I address. Because it is a little endian machine, the I value is stored in 72 6C 64 00 sequence during storage. the corresponding ASCII code is r l d.


The output depends on that fact that the x86 is little-Endian. If the x86 were instead big-Endian
What wocould you set I to in order to yield the same output? Wocould you need to change 57616 to a different value?
Here's a description of little-and big-Endian and a more whimsical description.

If it is big endian, it is I = 0x0000c6400 and does not need to be changed by 57616.


5. In the following code, what is going to be printed after 'y = '? (Note: the answer is not a specific value.) Why does this happen?
Cprintf ("x = % d y = % d", 3 );

The Spam value will be printed after y


6. let's say that GCC changed its calling convention so that it pushed arguments on the stack in Declaration order, so that the last argument is pushed last. how wocould you have to change cprintf or its interface so that it wocould still be possible to pass it a variable number of arguments?

Let's take a look at the implementation of the variable length parameter.

#ifndef _STDARG_H#define _STDARG_Htypedef char *va_list;/* Amount of space required in an argument list for an arg of type TYPE.   TYPE may alternatively be an expression whose type is used.  */#define __va_rounded_size(TYPE)    (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))#ifndef __sparc__#define va_start(AP, LASTARG)  (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))#else#define va_start(AP, LASTARG)  (__builtin_saveregs (),  AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))#endifvoid va_end (va_list);/* Defined in gnulib */#define va_end(AP)#define va_arg(AP, TYPE) (AP += __va_rounded_size (TYPE),  *((TYPE *) (AP - __va_rounded_size (TYPE))))#endif /* _STDARG_H */

From the above, we can see that va Arg extracts the address of the next parameter variable from the address increase every time. By default, this method assumes that the compiler adds parameters to the stack in the order from right to left, because the stack increases from high to low. The parameters of the Back-pressure Stack are placed at a low location of the memory address. Therefore, if you want to extract each variable from left to right, the compiler must press the parameter Stack from right to left in the reverse order. If the compiler changes the stack pressure sequence, you need to modify the va_start and va_arg Macros in the above Code to still retrieve all the parameters correctly, change it to subtraction to get the new address. I think it is not difficult to analyze the specific situation.


The best way to understand the stack is to do the apue lab 2 bomb ~ I wish you good luck in advance :)


Questions about display color output:

Observe the cga_putc function,



The system checks whether the 8-bit or above of C is 0. If yes, the printed characters are displayed in black and white. If not, it's just a strange thing...

In fact, the principle is very simple

Int C: the variable is 8-bit lower than the displayed ASCII code. Next 8 ~ 15 bits is used to control the color output.

This is just to illustrate the principle. I have not improved the function interpretation here. If you are interested in the problem, please contact us ~

Modify./lib/printfmt. c. I have made minor changes to case 'C', added a case 'C', and added a global variable color to pass the display color information.


Test method: Modify the./Kern/monitor. c file.




Ko ~! Actually, I want to print the green color, but I am not familiar with the color CONTROL OF THE 8bits...



In this experiment, there are some stack exercises, but I think it is better to split the bombs, so I "Save time" (lazy) and did not do it...

Http://blog.csdn.net/cinmyheart/article/details/39161471



There are still many incomplete answers to the Jos lab1 experiment, and we will update it later ....






MIT operating system experiment mit Jos lab1

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.