언제 CPU가 하던 걸 제쳐두고 special 코드로 이동하냐면
이것들을 전부 통틀어서 trap이라고 부르겠다.
user space, kernel space에서의 trap과 timer interrupts는 구분해서 실행해야 함!
얘네는 supervisor mode에서 trap handling에 대한 이야기고, machine mode에서도 비슷한 매커니즘이 있는데 얘네는 timer interrupt 처리함!
Context Switch에 대해 생각해보자
Process A가 돌고 있었음
====> Interrupt가 들어오면
sstatus의 SIE bit 체크해서 가능하면 interrupt를 disable함
sepc <- PC (돌아갈 곳 저장해야하니까)
current mode 역시 저장해놓고
scause에 trap 원인 저장
mode supervisor로 변경
pc <- stvec
(kernel 안의 trap handler 위치가 저장된 stvec으로 감)
(이때 CPU가 PC 말고는 저장하지 않는 다는 걸 알아야함
register나 page table 건드리지 않음 XXXXXXXXXXXXXX)
따라서 stvec이 user page table에 있어야함 헐ㄷㄷㄷ
여기까지가 hardware가 하는 일
===============Kernel=======
커널은 각 process마다 trapframe이라는 structure를 할당하고 여기에 32개의 register 값들을 저장한다. satp가 user의 page table을 가리키고 있고, 이러한 trapframe은 user page table에 연결됨
p->trapframe 얘는 physical address임 (kernel에서도 볼 수 있게)
a0 값을 sscartch에 저장
a0에 TRAPFRAME 주소를 저장하고, 나머지 register들 + sscratch에서 a0 값 가져와서 trapframe에 저장한다.
trapframe은 current process의 kernel stack address와, CPU hartid, usertrap function의 주소, kernel page table 주소
이제 trap 처리하고 다시 user space로 돌아올때 usertrapret() call함
이때 sepc<- uservec (Process B)로 바뀌는 거지!
userret call해서 page table 바꿔줌
a0에 user page table pointer
satp에 해당 프로세스의 paga table pointer