联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> C/C++编程C/C++编程

日期:2023-10-27 10:47

MiniOS

In this project, you will extend a small operating system to set up a simple system call and

initialize a simple page table. You are provided with the code of a tiny operating system, which is

not based on any other OS (e.g., Linux). This OS does not include any interrupt or trap handlers,

except minimal system call support.

The system consists of three pieces:

1. The boot loader (boot.efi), which loads the OS kernel and a user application into

memory; you are already given a binary for the boot loader to simplify the build process

2. The OS kernel (kernel_x86_64), a piece of software that runs in the privileged mode

(ring 0)

3. A simple user application (user_x86_64), a piece of software that runs in the unprivileged

mode (ring 3).

The OS kernel supports a video frame buffer which uses 800x600 (RGB32) video mode. On top

of the video frame buffer console, the system implements text output functions such as printf,

which is analogous to the user-space equivalents for the most part but used inside the OS kernel.

Environment:

OS: Ubuntu 22.04 Desktop x86-64

CPU Architecture: x86_64

run:

sudo apt update

sudo apt install make gcc binutils

sudo apt install git

sudo apt install ovmf qemu-system-x86

You can also install additional packages that can be useful for you (e.g., vim, emacs, or any other

editor).

Provided Code:

The provided code consists of the “kernel” and “user” parts. The “user” part makes system calls

to print some messages. You will only need to modify the “kernel” part. You are ONLY allowed

to change kernel_code.c and kernel_extra.c inside “kernel”. Everything else will be discarded for

grading.

The boot loader allocates some memory (around 32 MB), which will be used inside our kernel.

Part of this memory is used for the heap (see the extra credit assignment). But the remaining part

can be used to initialize the page table. You can assume that the memory base address is already

page-aligned.

2

Your Coding Part:

In kernel_code.c, there are two functions that you need implement:

1. kernel_init. It passes addresses to the user space stack, user program (code and data), and

memory that can be used to initialize the page table. Initially, user stack and program will

reside in kernel space. Our system makes sure that it will still work even if you do not

relocate those into user space. However, your eventual goal (Q4) is to move those

addresses in a dedicated user space portion of the address space. To load the page table,

you need to use load_page_table. This is a special function, which checks your page

table (and returns a string with an error message if it fails) and then loads it to the CR3

register which is used to specify the top level (root) page table address in x86-64.

2. syscall_entry. This is the entry point for all system calls. You need to implement one

specific system call (n = 1) and return an error status (-1) in all other cases. Note that the

mechanism to route system calls from user space is already implemented, you only need

to wire it to the corresponding handler inside this function.

In kernel_extra.c, you need to write your memory allocator code.

To compile and test the OS code, you need to run:

make clean

make

make test

Output:

3

Q2: System calls [40 Points]

You need to modify syscall_entry and implement one specific system call (n = 1) to print a

message on the screen using ‘printf’. The return status of this call should be 0. You will return an

error status (-1) in all other cases. Note that the mechanism to route system calls from user space

is already implemented in kernel_asm.S, you only need to wire it to the corresponding handler

inside syscall_entry in kernel_code.c.

Remember that you are allowed to change kernel_code.c ONLY.

Q3: Page table [60 Points]

The boot loader already sets up the default page table, but you need to create your own x86-64

page table (this can be done fully in C). This page table will provide identical virtual-to-physical

mappings for the first 4 GB of physical memory, and you have to use 4 KB pages. All pages are

assumed to be used for the privileged (ring 0) kernel mode. Although your memory size does not

exceed 1 GB, we are asking you to map 4 GB because the frame buffer’s video memory (used by

‘printf’) is typically located somewhere in the region of 3-4 GB. You can ignore the fact that

some mappings will point to non-existent physical pages in this 4 GB region.

The code provided in kernel_init will already call a special load_page_table function,

which will verify your page table and load it into the CR3 hardware register. You need to

initialize the page table before this function is called.

Remember that all entries of bitfields for page tables must be initialized, including those that are

not currently used. (You should specify 0 for any reserved bits.) It may be more convenient (and

less error prone), if you simply use 64-bit integers (uint64_t) and set corresponding bits yourself

(i.e., avoiding bitfields completely).

For simplicity, we will only allow two bits: the ‘present’ bit and the ‘writable’ bit, both of which

must be set to 1 in the page table. Please do not attempt to use any other bits (except the ‘user’

bit in the next question)! Note that load_page_table will fail if you set any other bits. You only

need to consider the “long” (64-bit) mode and 4 KB pages. Our page table will only use

traditional 4 levels!

Note that even though user applications are only allowed to be executed in user space, the

provided load_page_table function will take care of that problem as long as you do not modify

user_stack and user_program. For now, you are only asked to create kernel-space mappings.

You will modify user_stack and user_program in the next question.

You are allowed to change kernel_code.c ONLY. Do not attempt to “trick” the operating system

to get points without actually implementing the page table.

4

Q4: User space support for the page table [30 pts]

You should extend the page table for the application so that you can also properly execute

application code from user space. The page table should still point to the kernel portion (i.e., the

first entry of PML4). However, this page table will also refer to the pages that are assigned to the

user application itself (the user program and the user stack). Note that the kernel portion should

only be accessible in kernel space, whereas the application portion is accessible in both user and

kernel space. Also note that both user_program and user_stack must point to user-space (rather

than kernel-space) virtual addresses. Initially, they point to the kernel-space virtual addresses

(somewhere in the first 4 GB).

You are allowed to assign any virtual addresses from the bottom 2 MB for the application

(i.e., 0xFFFFFFFFFFE00000 to 0xFFFFFFFFFFFFFFFF). x86-64 sign extends 48-bit virtual

addresses (from the page table) to 64-bit virtual addresses. You can assume that the program

occupies just 1 page, and the user stack is also just 1 page. The stack grows downwards, thus the

initial user_stack address points to the next page (i.e., stack_memory_base + 4096).

Consequently, you need to get the physical page address correctly and map that physical page to

the new virtual address. Finally, the new virtual address that you will write into user_stack

should also point to the next virtual page (i.e., stack_memory_base + 4096) since the stack

grows downwards. Note that user_program will still point to a “normal” base address, but you

also need to map the corresponding page and write the user-space virtual address.

As shown in Figure below, the user-space mappings correspond to the last entry of PML4 (Level

4), last entry of PDP (Level 3), and the last entry of PD (Level 2). You can use any entries in PT

(Level 1). Please make sure to set up correct permissions for these new mappings. The userspace portion can be accessed in both modes, and the kernel-space portion can only be accessed

in kernel/privileged mode.

5

You are allowed to change kernel_code.c ONLY. Do not attempt to “trick” the operating system

to get points without actually implementing the user-space portion of the page table.

Extra Credit:

Integrate the memory allocator implementation into kernel_extra.c. Remember that you are NOT

allowed to use any standard header files. The template in kernel_extra.c already includes some

headers that you will likely need. You need to provide mm_init, malloc, and free. The MiniOS

kernel will do some tests on your memory allocator.

You are allowed to change kernel_extra.c ONLY. Do not attempt to “trick” the operating system

to get points without actually implementing the extra-credit part.


版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp