ECE391: Computer Systems Engineering Machine Problem 3
Spring 2022 Checkpoint 1: 6pm 3/22 Tuesday Checkpoint 2: 6pm 3/28 Monday Checkpoint 3: 6pm 4/11 Monday Checkpoint 4: 6pm 4/18 Monday Checkpoint 5: 5pm 5/2 Monday Final Demos: TBD
1 Introduction
2 Using the Group Repository
Copyright By PowCoder代写 加微信 powcoder
3 Getting Started: Booting and GRUB
4 The Pieces
6 What to Hand in
Illinix 391
6.1 Checkpoint1:ProcessorInitialization ……………………………. 4
6.1.1 GroupRepository………………………………….. 4
6.1.2 LoadtheGDT …………………………………… 4
6.1.3 InitializetheIDT………………………………….. 4
6.1.4 InitializetheDevices………………………………… 5
6.1.5 InitializePaging ………………………………….. 5
6.1.6 Troubleshooting/Debugging …………………………….. 5
6.1.7 TestCoverage……………………………………. 5
6.1.8 Checkpoint1Handin………………………………… 6
6.2 Checkpoint2:DeviceDrivers ……………………………….. 7
6.2.1 CreateaTerminalDriver . . . . . . . . .
6.2.2 Parse the Read-only File System . . . . .
6.2.3 TheReal-TimeClockDriver…….
6.2.4 TestCoverage……………
6.2.5 Checkpoint2Handin………..
6.3 Checkpoint 3: Staring System Calls and Tasks . . 1
………………………. 7 ………………………. 7 ………………………. 7 ………………………. 7 ………………………. 8 ………………………. 9
6.3.1 SupportSystemCalls………………………………… 9
6.3.2 Tasks……………………………………….. 9
6.3.3 SupportALoader………………………………….. 9
6.3.4 ExecutingUser-levelCode……………………………… 9
6.3.5 ProcessControlBlock ……………………………….. 10
6.3.6 TestCoverage……………………………………. 10
6.4 Checkpoint4:CompletingSystemCallsandTasks ……………………… 10 6.4.1 TestCoverage……………………………………. 10
6.5 Checkpoint5:Scheduling………………………………….. 12 6.5.1 MultipleTerminalsandActiveTasks ………………………… 12 6.5.2 Scheduling …………………………………….. 12 6.5.3 TestCoverage……………………………………. 12 6.5.4 Checkpoint5Handin………………………………… 13
6.6 ExtraCredit………………………………………… 14 6.6.1 Signals ………………………………………. 14 6.6.2 DynamicMemoryAllocation ……………………………. 14 6.6.3 OtherIdeas…………………………………….. 14
7 Grading 15
8 Appendix A: The File System 16
8.1 FileSystemUtilities ……………………………………. 16 8.2 FileSystemAbstractions ………………………………….. 17
9 Appendix B: The System Calls 18
10 Appendix C: Memory Map and Task Specification 20
11 Appendix D: System Calls, Exceptions, and Interrupts 21
12 Appendix E: Stack Switching and the TSS 21
13 Appendix F: Signals 22
14 Appendix G: Troubleshooting 24
14.1DebuggingwithQEMU…………………………………… 24 14.2/mnt/tmpmp3CompileError ………………………………… 24 14.3 Buffer I/O error on device loop0, logical block #### lost page write due to I/O error on loop0 . . . . . 24
1 Introduction
Read the whole document before you begin, or you may miss points on some requirements (for example, the bug log).
In this machine problem, you will work in teams to develop the core of an operating system. We will provide you with code that boots you into protected mode, sets up the GDT, LDT, and initial TSS, and maps a read-only file system image into physical memory for you. You must set up the interrupt descriptor table (IDT), basic paging support for tasks, separate 4 MB pages for the kernel and applications, initialize a few devices, write the system call interface along with ten system calls, provide support for six tasks from program images in the file system which interface with the kernel via system calls, multiple terminals and basic scheduling.
The goal for the assignment is to provide you with hands-on experience in developing the software used to interface between devices and applications, i.e., operating systems. We have deliberately simplified many of the interfaces to reduce the level of effort necessary to complete the project, but we hope that you will leave the class with the skills necessary to extend the implementation that you develop here along whatever direction you choose by incrementally improving various aspects of your system.
2 Using the Group Repository
You should be receiving an invite to your group repository within the next two days or so. Your repo can be found at:
https://gitlab.engr.illinois.edu/ece391 sp22/mp3 group XX
where XX is your assigned group number. Please check the course website Assignment page to know what is your group number.
To use Git on a lab computer, you’ll have to use Git Bash. You are free to download other Git tools as you wish, but this documentation assumes you are using Git Bash. To launch Git Bash, click the Start button in Windows, type in git bash, then click on the search result that says Git Bash.
Run the following commands to make sure the line endings are set to LF (Unix style):
git config –global core.autocrlf input git config –global core.eol lf
Switch the path in git-bash into your Z: drive by running the command: cd /z.
If you do NOT have a ssh-key configured, clone your git repo in Z: drive by running the command, it will ask for your NETID and AD password:
git clone https://gitlab.engr.illinois.edu/ece391 sp22/mp3 group XX.git mp3
If you do have a ssh-key configured, clone your git repo in Z: drive by running the command:
git clone sp22/mp3 group XX.git mp3
Inside a newly created MP3 directory. You can add/delete files to/from the repository with git add [file list] and git rm [file list] respectively. Remember to git pull each time you sit down to work on the project and git commit and git push when you are done. Doing so will ensure that all members are working on the most current version of the sources. As a final note, it is bad practice to commit broken sources. You should make sure that your sources compile correctly before committing them to the repository. As with previous MPs, please do not modify the Makefile as we will be grading using the vanilla Makefile initially provided.
As you work on MP3 with your teammates, you may find it useful to create additional branches to avoid conflicts while editing source files. Remember to merge your changes back into the master branch by each checkpoint deadline, as this is the only branch we will use for grading.
3 Getting Started: Booting and GRUB
For this project, you will make use of GRUB (GRand Unified Bootloader) to boot your OS image file. GRUB imple- ments the Multiboot specification, the details of which can be found online at http://www.gnu.org/software/grub/manual/multiboot/multiboot.html. You will need to read through at least the chunk of this documentation entitled ”Boot information format” to understand the information that GRUB provides to your operating system upon bootup. Various boot parameters are stored in a multiboot info t data structure, whose address is passed in via EBX to the entry point of the OS image. The multiboot.h file contains this and other structure definitions that you should use when accessing the boot information.
GRUB drops you into protected mode, but with paging turned off and all the descriptor tables (GDT, LDT, IDT, TSS) in an undefined state. The first thing to do is set up a GDT, LDT, and TSS. The given code in boot.S does this for you, and then calls entry() in kernel.c, passing the address of the multiboot info t to it. GRUB has loaded the file system image at some place in physical memory, as a module; there is a section in the multiboot info t structure which describes how to access the module information, including physical addresses and size information. You will need to keep the base address of this file system module around, since many operations will need to interact with the file system. You may need to extract other boot information as well, such as the physical memory map provided to you by the BIOS (and also passed in as part of the boot information structure).
To get started, read the INSTALL file given in the MP distribution for instructions on booting the OS image file. Once you have the skeleton OS booting, you are ready to begin designing and implementing features. Necessary references for this project are the x86 ISA manuals, which can be found in the “Tools, References, and Links” section of the class website. Volume 3: System Programming details things like segmentation, virtual memory, interrupts and exceptions, and task support in all of their gory detail. The other volumes provide invaluable resources such as x86 instruction specifications. You will need to reference these manuals early and often; familiarize yourself with their contents before beginning. To debug your MP, you will take advantage of QEMU, which by now, you should be comfortable with.
One final note: GRUB depends on seeing the Multiboot header within the first 8 kB of the OS image file. This header is located in the boot.S file of your sources, and boot.o is passed as the first object file to the linker to ensure that it falls within the first 8 kB of the OS image. Don’t move boot.o to a different position in the link order given in the Makefile, or GRUB may not be able to boot your OS image.
4 The Pieces
The materials provided to you will launch your machine into protected mode, set up the GDT and LDT as well as a TSS. A file system image with a shell, a few utilities, a single directory entry, and a real-time clock (RTC) device file will also be mapped into physical memory for you. We will also provide you with the tools necessary to develop your own test applications, including the compilation infrastructure used to produce the shell and utilities and the file system image itself (the createfs). For simplicity, we will stick to text-mode graphics, but your OS will in the end support operation of a user-level animation package from MP1. Some basic printf support is also provided to aid in debugging, but eventually you will need to write your own output support for the terminal.
Work plan:: Although we are not explicitly requiring that you tell us how you plan to split up the work for this project, we do expect that you will want to do so to allow independent progress by all team members. A suggested split of the work (after getting the devices initialized) is to have each person work on one of the subgoals of Checkpoint 2 with one person concentrating on how these functions will eventually integrate with system calls in Checkpoint 3 and 4 , which connects all previous pieces using the system calls as glue. Checkpoint 5 also requires the group to work together on terminal drivers, RTC interrupts, and everything learned in Checkpoint 3 and 4.
Setting up a clean testing interface will also help with partitioning the work, since group members can finish and test parts of the project without other members having finished the other parts (yet).
For this project, we require you to demonstrate unit tests with adequate coverage of your source code.
As your operating system components are dependent on one another, you may find it useful to unit test each compo- nent individually to isolate any design or coding bugs.
We have provided you with a starter test suite in the tests.c file. As you add more components to your operating system, we encourage you to add corresponding tests that verify the functionality of each component at the interface level. Minimum test coverage for each checkpoint is detailed in the following sections.
You may launch tests individually from each of your source files, but all your tests should be defined in tests.c. This will be especially useful when passing in state variables from your modules to test functions. Remember to use the RUN TESTS macro to exclude test launches when compiling your code for handin.
Keep in mind that passing all of your unit tests does not guarantee bug free code. However, the test suite provides a convenient means to run your tests frequently without having to re-debug older components as you add new function- ality.
6 What to Hand in
6.1 Checkpoint 1: Processor Initialization
For the checkpoint, you must have the following accomplished:
6.1.1 Group Repository
You must have your code in the shared group repository, and each group member should be able to demonstrate that he/she can read and change the source code in the repository.
6.1.2 Load the GDT
You learned about the global descriptor table (GDT) in class. Linux creates four segments in this table: Kernel Code Segment, Kernel Data Segment, User Code Segment, and User Data Segment. In x86 desc.S, starting at line 38, we have created an empty GDT for you.
Write code that makes an emulated Intel IA-32 processor use this GDT. We have marked a location in the code (boot.S
line 27) at which you will need to place this initialization code for the GDT to ensure that you follow the correct boot
sequence. You will need to look through the ISA Reference Manual for information about how to write this code (https://courses.engr.illinois.edu/ece391/secure/references/IA32-ref-manual-vol-3.pdf).
6.1.3 Initialize the IDT
Your IDT must contain entries for exceptions, a few interrupts, and system calls. Consult the x86 ISA manuals for the descriptor formats and please see Appendix D for more information. The exception handler(s) should use the printing support to report errors when an exception occurs in the kernel, and should squash any user-level program that produces an exception, returning control to the shell (the shell should not cause an exception in a working OS)— see System Calls (Appendix B) for further details. You will also need to handle interrupts for the keyboard and the RTC. Finally, you will need to use entry 0x80 for system calls, as described below.
6.1.4 Initialize the Devices
Adapt the initialization code from Linux to initialize the PIC, the keyboard, and the RTC. Set up a general-purpose infrastructure similar to what is done in the Linux kernel. You need to handle the keyboard and RTC interrupts, but you also need to make sure that these devices are initialized before taking interrupts. We suggest that you first mask out all interrupts on the PIC, then initialize the PIC, initialize the devices, and, as part of each device’s initialization, enable its associated interrupt on the PIC. The handler addresses should be installed dynamically/indirectly via a data structure used by the default handlers (as in Linux). You may also want to review the RTC data sheet linked from the class web page.
For the checkpoint, your OS must execute the test interrupts handler (provided in lib.c) when an RTC interrupt occurs. When a keyboard interrupt occurs, you must echo the correct characters to the screen. These simple tests will determine if you have the IDT entries set up correctly, the PIC enabled, and the devices initialized and able to generate interrupts.
6.1.5 Initialize Paging
As preparation for the next steps in the MP you must have pag- ing enabled and working. You will be creating a page directory and a page table with valid page directory entries (PDEs) and page table entries (PTEs). More information about this process appears in Appendix C and in the Intel ISA manual linked from the class web page.
The image to the right shows how virtual and physical mem- ory are laid out for this checkpoint. To keep things simple, the kernel and video memory will be at the same location in virtual memory as they are in physical memory. Your kernel code is already loaded at 4 MB for you, so you need only map virtual memory 4-8 MB to physical memory at 4-8 MB. This kernel page should be a single 4 MB page, whereas the first 4 MB of memory should broken down into 4 kB pages. In addition to 8MB to 4GB being marked not present, you should also set any unused pages to not present as well. In this layout everything in the first 4MB, that isn’t the page for video memory, should be marked not present.
Make sure that you align your pages (page directory and page tables) on 4 kB boundaries. To align things in x86:
.align BYTES_TO_ALIGN_TO label:
(whatever you want aligned)
To align things in C:
Video Memory
int some_variable __attribute__((aligned (BYTES_TO_ALIGN_TO)));
6.1.6 Troubleshooting/Debugging
See Appendix G for more information about debugging and common issues.
6.1.7 Test Coverage
At minimum, your tests should cover:
Not Present
• Values contained in the IDT array – An example has been provided in tests.c • Receiving an RTC interrupt
• Interpreting various scancodes in the keyboard handler
• Values contained in your paging structures
• Dereferencing different address ranges with paging turned on
• Checking bad or garbage input and return values for any function you write
This list is subject to change. Keep an eye out for the rubric. You are encouraged to add more unit tests than those specified above.
6.1.8 Checkpoint 1 Handin
For all handins, we expect you to write your own unit tests and to use those to demonstrate functionality. For this handin, you should write your own “blue screen” of death for each of the exceptions. At a minimum, this screen must identify the exception taken. You may also want to read about how exceptions are handled in the Intel ISA and print more useful information, such as the memory address reference that caused a page fault. This information will be of use to you later for debugging. We expect you to be able to boot your operating system with paging turned on and to enter a halt loop or a while (1) loop. Then we expect you to boot your operating system and explicitly dereference NULL to demonstrate your “blue screen” identifying the resulting page fault. We also expect you to be able to press a key and demonstrate that your operating system reaches the test interrupts function in on RTC interrupts, but you do not need to write a full interrupt handler for RTC yet, merely show that you can receive interrupts. Finally, we expect your keyboard interrupt handler to echo the correct character to the screen, although where each character appears on the screen doesn’t matter. As with the RTC, you need not write a full interrupt handler for the keyboard for this checkpoint. How you demonstrate these is up to you; do not rely on us to test it for you during handin. If you cannot prove functionality on your own, then we cannot give you points.
6.2 Checkpoint 2: Device Drivers
6.2.1 Create a Terminal Driver
When any printable characters are typed at the keyboard, they should be displayed to the screen. This includes handling all alphanumeric characters, symbols, shift and capslock, but you do not need to support the number pad. You will now need to keep track of the screen location for this purpose. You do need to support vertical scrolling (but not history) and will need to interpret CTRL-L (non-printable key) as meaning “clear the screen and put the cursor at the top” which will make your testing experience more pleasant. You do also need to support backspace and line-buffered input. The size of the buffer should be 128 characters for this checkpoint. For more details on how the terminal read and write functions should work, and how to handle the buffer filling up, please see Appendix B.
Keep in mind that you will also want to have an external interface to support delivery of external data to the terminal output. In particular, write system calls to the terminal should integrate cleanly with keyboard input. The hello program in the file system will ev
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com