📂
build a OS
  • Learn OS with me
  • OS Interfaces
    • OS interfaces
    • I/O and File descriptors
    • Process and Memory
    • Pipes
    • File
  • OS Organization
    • OS Organization
    • Challenge yourself
  • Memory Management
    • XV6 Virtual Memory
    • Page Table
      • Part 1: How to translate address
      • Part 2: Create an Address Space
      • Part 3: How Page Table is used
      • Part 4: Page Fault and Swap
      • Part 5: How to operate on page tables
    • xv6 buddy allocator
      • How to display physical memory
    • Memory Management Walk Through
  • Traps and Interrupts
    • Trap Home Page
      • 系统调用的核心原理
    • What is trapframe
    • What is trampoline
    • Traps from kernel space
    • How fork() works
    • How system calls get into/out of the kernel
    • How exec() works
  • Scheduling
    • XV6 CPU Scheduling
    • How unix pipes work?
    • How does wait(), exit(), kill() work?
  • File System
    • Overview and Disk Layout
    • Buffer Cache
    • Design Inode Layer
    • Inode Content
    • Block Allocator
    • Design a log system for crash recovery
    • Directory Layer
    • Path names
    • File Descriptor Layer
    • FS System Calls
    • XV6 VS Real World
    • Make Xv6 File disk management system
    • Write FS simulator in python
    • How Redirect Shell command works
  • Concurrency
    • Spinlock
    • How linux select work
    • Hardware Support Locking
    • Exercise: Implement atomic counter
    • Locking in Xv6
    • Concurrency in Xv6
    • Exercise: Socket Programming with Event loop
  • Labs
    • Lab 1 Xv6 and Unix utilities
    • Lab 2 Shell
    • Lab 3 Buddy Allocator
    • Lab 4 Lazy
    • Lab 5 Copy-on-Write Fork for xv6
    • Lab 6 RISC-V assembly
    • Lab 6 Uthread: switching between threads
    • Lab 6 Alarm
    • Lab 7 Lock
    • Lab 8 File System: Large Files
    • Lab 8 File System: Symbolic links
    • Lab 9 mmap
    • Lab 10 Networking Part 1
    • Lab 10 Networking Part 2
  • Hardware, Device, Assembly
    • RISC-V assembly
    • Assembly: Access and Store information in Memory
    • Start xv6 and the first process
    • Why first user process loads another program?
    • What does kernel.ld do in XV6?
    • XV6 Device Driver
Powered by GitBook
On this page
  • 3 kinds of traps:
  • Stack pointer也不正确, 不能依赖。
  • 核心原理
  • 重要细节

Was this helpful?

  1. Traps and Interrupts
  2. Trap Home Page

系统调用的核心原理

3 kinds of traps:

  1. system call

  2. something illegal

  3. device interrupts

    具体的执行方式详见[[how system calls get into / out of the kernel]].

trap from user space 比trap from kernel space难度大。 首先RISC-V Hardware不会switch page table, 我们要自己实现。

Stack pointer也不正确, 不能依赖。

核心原理

为了解决这些问题 xv6用了一个user page to map the trap vector instructions. 将这个特殊page的address 存给了stvec register.

这个传奇的user page就是大名鼎鼎的跳板page trampoline page.

Xv6 maps the trampoline page at the same virtual address in the kernel page table and in every user page table

这样就算切换到了kernel page table, 我们一样可以继续执行trap vector instruction

process还用了trapframe存了重要的信息,以及足够空间store registers.

It contains pointers to the current process’s kernel stack, the current CPU’s hartid, the address of usertrap, and the address of the kernel page table. uservec retrieves these values, switches satp to the kernel page table, and calls usertrap.

重要细节

stvec — ecall jumps here in kernel; address of trampoline

stvec: The kernel writes the address of its trap handler here

The RISC-V jumps here to handle a trap. Risc-V provides a separate opcode to call the operating system. This is the ECALL instruction.

static uint64 (*syscalls[28])(void) syscalls is an 28 elements of array of pointers point to function.

static uint64 (**syscalls*[])(void) = {
[SYS_fork]    sys_fork,
[SYS_exit]    sys_exit,
[SYS_wait]    sys_wait,
[SYS_pipe]    sys_pipe,
[SYS_read]    sys_read,
[SYS_kill]    sys_kill,
[SYS_exec]    sys_exec,
[SYS_fstat]   sys_fstat,
…

总结: 任何一个syscall在User space都是汇编。详见 usys.pl

sub entry {
    my $name = shift;
    print “.global $name\n”;
    print “${name}:\n”;
    print “ li a7, SYS_${name}\n”;
    print “ ecall\n”;
    print “ ret\n”;
}

entry(“fork”);
entry(“exit”);
entry(“wait”);
entry(“pipe”);
…

普通user program例如echo, cat等会call write syscall.

write其实一段生成的汇编代码(generate code如上)。将名字作为参数存入a7 register。

call RISC-V ecall instruction。

这个ecall会直接读取stvec的内容并且跳转。并且进入OS kernel模式。

uservec在OS初始化时会设置好,作为trap的入口。

所以进入uservec,做好一系列准备工作 进入C traphandler。

如果trap是来自system call 就会根据a7的数字 呼叫相应system call.

uint64 (*syscalls[])(void) syscalls is array of pointers point to function.

{ [SYS_fork] sys_fork,...} 是古老的语法 其实就是 [a]=b,表示当index是a的时候return b.

Open questions

a0 register到底存了什么 为什么和sscratch要swap? 而且为什么要换呢 为什么不能直接用sscratch offset来存registers呢 example: instead of

save the user registers in TRAPFRAME
        sd ra, 40(a0)
        sd sp, 48(a0)
        sd gp, 56(a0)
        sd tp, 64(a0)
        sd t0, 72(a0)
…

Can we do

save the user registers in TRAPFRAME
        sd ra, 40(sscratch)
        sd sp, 48(sscratch)
        sd gp, 56(sscratch)
        sd tp, 64(sscratch)
        sd t0, 72(sscratch)
PreviousTrap Home PageNextWhat is trapframe

Last updated 5 years ago

Was this helpful?

c - Need help to understand the syntax in xv6 kernel - Stack Overflow
Using the GNU Compiler Collection (GCC): Designated Inits