26
Virtual memory, user program execution Michal Sojka 1 Czech Technical University in Prague, Faculty of Electrical Engineering Email: [email protected] April 27, 2016 1 Based on exercises by Benjamin Engel from TU Dresden. M. Sojka A3B33OSD, task E2 April 27, 2016 1 / 19

Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

  • Upload
    others

  • View
    11

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Virtual memory, user program execution

Michal Sojka1

Czech Technical University in Prague,Faculty of Electrical Engineering

Email: [email protected]

April 27, 2016

1Based on exercises by Benjamin Engel from TU Dresden.M. Sojka A3B33OSD, task E2 April 27, 2016 1 / 19

Page 2: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

NOVA microhypervisor

I Research project of TU Dresden (< 2012) and Intel Labs (≥ 2012).I http://hypervisor.org/, x86, GPL.I We will use a stripped down version (2 kLoC) of the microhypervisor

(kernel).

M. Sojka A3B33OSD, task E2 April 27, 2016 2 / 19

Page 3: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Assignment

Extend the kernel so that it is able to run a user space application.The kernel will be run in hardware emulator qemu (i.e. in a virtualmachine).

Initial state

I CPU and kernel initializedI Application binary loaded in memory

Steps to do

1. Read and parse program header from ELF binary2. Setup page table entries so that the application can run3. Jump to the application entry point (and switch the CPU from

kernel to user mode)

M. Sojka A3B33OSD, task E2 April 27, 2016 3 / 19

Page 4: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/dataEIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIPEIPEIPEIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 5: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/data

EIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIPEIPEIPEIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 6: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/dataEIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIPEIPEIPEIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 7: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/data

EIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIP

EIPEIPEIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 8: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/data

EIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIP

EIP

EIPEIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 9: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/data

EIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIPEIP

EIP

EIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 10: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/data

EIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIPEIPEIP

EIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 11: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Assignment

Graphical representation of the assignment

1. CPU reset, BIOS executes2. Bootloader loads the kernel binary and user application into memory3. Bootloader starts executing the kernel (kern/src/start.S)4. Kernel initializes CPU and paging (virtual memory) (start.S, init.cc)5. Kernel allocates and maps one page for application stack (kern/src/ec.cc,

Ec::root_invoke())6. You look at ELF program header to see where the application wants to be loaded.7. You create page table entries according to the ELF header8. You jump to application entry point (using iret instruction)

Physicalmemory

kern/build/hypervisor

Kernel code/data

user/hellomultibootinfo

User code/data

EIP

Virtualmemory

3G (0xC0000000)0

User space Kernel space

4G

EIPEIPEIPEIP

0x2000

User stack

Remappage

ELF header

EIP

M. Sojka A3B33OSD, task E2 April 27, 2016 4 / 19

Page 12: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Prerequisites

What you need to know?

I NOVA is implemented in C++ (and assembler).I Each user “program” is represented by execution context data

structure (class Ec).I The first executed program is called root task (similar to init

process in Unix).I Where the user program expects to be loaded in memory.

Where the program expects to have stack, data, code.I Structure of the program binary file.

M. Sojka A3B33OSD, task E2 April 27, 2016 5 / 19

Page 13: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Prerequisites

User space memory mapAs defined by so called “linker script” (user/linker.ld)

I Stack is expected to go from 0x2000downwards.

I First page is left “not present” to catchNULL pointer deference errors.

I Entry point and sizes of text/data sectionsis stored in various headers in the programbinary.

0x2000

Entry point

0x2000 +sizeof(data)

0x0000

Text(code)

Data

Stack }

PageNot

present

0x1000

M. Sojka A3B33OSD, task E2 April 27, 2016 6 / 19

Page 14: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Prerequisites

Program binaries

Executable and Linkable Format (ELF)http://www.sco.com/developers/devspecs/gabi41.pdf, chapter 4

Segment 1(e.g. code)

ELF header

Program headertable (optional)

Section 1

...

Section n

...

...

Section headertable

ELF header

Program headertable

Segment 2(e.g. data)

...

Section headertable (optional)

Linking view Execution viewI Composed of headers,

segments and sections

I One segment containsone or more sections

I A section may or maynot belong to a segment

I All of this is controlledby “linker scripts” –they tell the linker howto link the program(more info later).

M. Sojka A3B33OSD, task E2 April 27, 2016 7 / 19

Page 15: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Prerequisites

ELF headerelf.h, class Eh

magic: 7f ’E’ ’L’ ’F’class data version padd.

paddingpadding

type machineversionentry

ph_offsetsh_offset

flagseh_size ph_sizeph_count sh_sizesh_count strtab

I Each binary starts with thisheader

I Can be shown byreadelf -h

I Your code should:I Check magic, data == 1

and type == 2I Read entry, i.e. user EIPI Read information about

program headersI ph_count: number of

program headersI ph_offset: where

within the file theprogram header tablestarts

M. Sojka A3B33OSD, task E2 April 27, 2016 8 / 19

Page 16: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Prerequisites

Program header tableelf.h, class Ph

ELF header

type

file offsetvirtual addressphysical address

file sizemem sizeflags

alignment

type

file offset. . .

I Describes segments of the binaryI Your program should:

I If type == PT_LOAD (1) ⇒ map thissegment to memory

I If flags has PF_W (2) set ⇒ thememory must be writable

I Read offset to know where this segmentstarts relative to the beginning of the file

I Read virtual address to know where tomap this segment to

I Read file/mem size to know the segmentsize (in file and memory)

M. Sojka A3B33OSD, task E2 April 27, 2016 9 / 19

Page 17: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Howto

Getting started

tar xf osd-e2.tar.gzcd osd-e2make # Compile everythingmake run # Run it in Qemu emulator

Understanding qemu invocation

qemu-system-i386 -serial stdio -kernel kern/build/hypervisor -initrd user/hello

I Serial line of the emulated machine will go to stdoutI Address of user/hello binary will be passed to the kernel via

Multiboot info data structure

Source code layout

I user/ – user space code (hello world + other simple programs)I kern/ – stripped down NOVA kernel

I you will need to modify kern/src/ec.ccM. Sojka A3B33OSD, task E2 April 27, 2016 10 / 19

Page 18: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Howto

Step 1 – Decode ELF headers

1. Find TODO in Ec::root_invoke()

2. mod.mod_start is the physical address of the user binary3. Remap and read the ELF header4. Remap program header table and iterate over all (two)

program segments4.1 If type != PT_LOAD, ignore this segment4.2 Print all virt/phys addresses and mem sizes

I Align them properly to 4k page boundaries!I phys/virt addresses: align downI mem size: align up

When anything goes wrong here, call panic ("ELF error\n");

M. Sojka A3B33OSD, task E2 April 27, 2016 11 / 19

Page 19: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Howto

Step 2 – Setup page table entries for the application

1. Some sanity checks:I File size and mem size should be equalI Virtual address and file offset should be equal (modulo page

size)

2. Add mapping for all pages in all segments:Ptab::insert_mapping (virt, phys, attr)

I Inserts a mapping from virtual address virt to physicaladdress phys with attributes attr

I If flags & Ph::PF_W ⇒ should be mapped writable, thusattr = Ptab::PRESENT | Ptab::RW | Ptab::USER, otherwiseattr = Ptab::PRESENT | Ptab::USER

I See the Ptab::insert_mapping slide later and class Ph inkernel/include/elf.h

M. Sojka A3B33OSD, task E2 April 27, 2016 12 / 19

Page 20: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Howto

Step 3 - First switch to user space

I After mapping the memory to the right place,we can start executing application code.

I Use iret instruction to switch the CPU fromkernel to user mode and jump to the user code.

I iret takes the operands from the stack!I Prepare an array with 5 elements:

I Entry point: user instruction pointer to return toI SEL_USER_CODE: new CS (include/selectors.h)I 0x200: EFLAGS – just set interrupt enabled flagI 0x2000: user stack pointerI SEL_USER_DATA: new SS stack segment

I Point ESP to the array and execute iret instruction.I If you are successful, the application prints

“Hello world!”

M. Sojka A3B33OSD, task E2 April 27, 2016 13 / 19

0x2000

Entry point

0x2000 +sizeof(data)

0x0000

Text(code)

Data

Stack }

PageNot

present

0x1000

EIPCS

EFLAGSESPSS

ESP 048

1216

Page 21: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Additional information

Additional information

M. Sojka A3B33OSD, task E2 April 27, 2016 14 / 19

Page 22: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Additional information

Linker script

Linker scripts tell the linker how to link the program, i.e.I which sections go to which segment,I at which address the segments should be loaded, etc.I Documentation: run “info ld Scripts”

user/linker.ld

I Program entry point at symbol _startI Two segments: data (6 ⇒ RW) and text (5 ⇒ RX)I Put section .text into segment text and sections .data,

.rodata and .bss into segment dataI ALIGN end of data (and start of text) to page boundary

(0x1000)

M. Sojka A3B33OSD, task E2 April 27, 2016 15 / 19

Page 23: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Additional information

Program startup – user/src/start.SCode that runs before main()

.text

.global _start_start:

mov $stack_top, %espcall mainud2

I Put this into the .text sectionI Define global symbol _start:I Setup a stack by loading the address of stack_top into esp

(stack_top is defined in linker.ld)I Call main()I If main retuns, execute undefined unstruction. This generates

exception and the kernel tells us about that.

M. Sojka A3B33OSD, task E2 April 27, 2016 16 / 19

Page 24: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Additional information

Building and inspecting the user program

I Goto user and make user binaryI Inspect binary by nm user/hello

00003000 T main00002000 D stack_top00003029 T _start

I There are three symbols in the text section (T) and three indata section (D)

I Decode headers: readelf -h -l user/hello or objdump -xuser/hello

M. Sojka A3B33OSD, task E2 April 27, 2016 17 / 19

Page 25: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Additional information

Understanding kernel exceptions

I void main() {*((int*)0x234) = 0x12; /* Write 0x12 to address 0x234 */

}

I Address 0x234 is in page zero, which is not present (i.e. present flag in pagetable entry is 0).

I Access to this page generates “Page fault” exception.I The kernel “handles” the exception by printing useful information about it.I After your kernel is capable of running user binaries, running:

qemu-system-i386 -serial stdio -kernel kern/build/hypervisor \-initrd user/pagefault

produces this output:

NOVA Microhypervisor 0.3 (Cleetwood Cove)

Ec:: handle_exc Page Fault (eip=0 x3000 cr2=0x234)eax=0 xcfffffdc ebx=0 x1803000 ecx=0x5 edx ==0 xc0009000esi=0 xdf001074 edi=0x5 ebp=0 x1801000 esp ==0 x1ffcunhandled kernel exception

I eip – the instruction that caused the fault, cr2 – the faulty addressI Find the address 0x3000 (eip) in objdump -S user/pagefault

M. Sojka A3B33OSD, task E2 April 27, 2016 18 / 19

Page 26: Virtual memory, user program executionlabe.felk.cvut.cz/~stepan/33OSD/files/osd-e2-kernel.pdf · Virtualmemory,userprogramexecution MichalSojka1 Czech Technical University in Prague,

Additional information

Understanding Ptab::insert_mapping – x86 page tablesSee kern/src/ptab.cc

pdir addr

20 bit phys addr . . .S

U

R

WP

1

1

page directory page table

31 012

P – present (1 : entry valid)

R/W – 0 : read only, 1 : writable

S/U – 0 : kernel only, 1 : user

12

ptab addr

ptab addr

page addr 1

1page addr

.data

.stack

.text

0x1000

0x2000

cr3

See also Intel System Programming Guide, sect. 4.3 “32-bit paging” (link)M. Sojka A3B33OSD, task E2 April 27, 2016 19 / 19