스위칭 시스템 및 프로세스의 과정의 일반 구현
교과서의 첫째, 내용
- 일정 시간의 과정 실시
- 스케줄 기능에 의해 리눅스 커널 구현 프로세스 스케줄링, 스케줄 기능은 실행 큐에서 CPU가 할당 프로세스를 찾을 수
- 함수가 호출 일정 기능을 예약되어 예약 전화, 그것은 일정 시간의 과정이다
- 커널이 사용자 공간에 복귀하려고 할 때, 커널 확인합니다 need_resched 플래그는, 설정 한 경우, 통화 예약 기능을 설정하고,이 시점에 인터럽트 핸들러에서 예약 기회의 고정 된 지점으로 공간에 대한 사용자 반환했다입니다
- 커널 스레드가 특별한 과정뿐만 아니라 커널 모드 사용자 모드, 커널 스레드와 인터럽트 핸들러 위치의 실행 경로의 임시 정지를 필요로 할 수있는 직접 호출 일정 ()
- 프로세스의 특별한 커널 스레드로도 수동 예약을 할 수 있으며, 수업 일정 기능은 CPU를 허용 전화 주도권을 쥐고 있습니다
- 문맥
- 또한 프로세스 실행을 제어하기위한 컨텍스트 스위치 수단으로 알려진 프로세스 스위치, 커널은 이전에 실행 프로세스를 중단 재개, CPU에서 실행되는 과정을 중지 할 수 있어야합니다
- 커널 스레드는 커널 공간에서 프로세스 컨텍스트의 형태로 실행
- 자신의 주소 공간을 가질 수 있습니다 각 프로세스의 가치,하지만 CPU와 모든 프로세스가 레지스터를 공유해야 할 때, 그래서 프로세스 실행을 다시 시작하기 전에, 커널은 각 레지스터가 일시 중단 된 프로세스에로드되어 있는지 확인해야합니다
- 데이터 세트를 수행하기 전에 복구 프로세스는 레지스터에로드 하드웨어 컨텍스트 호출되어야
- 프로세스 문맥은 프로세스 실행에 필요한 모든 정보가 들어 있습니다
- 사용자 주소 공간 : 사용자 스택에 이렇게 프로그램 코드, 데이터 및 포함
- 정보 제어 : 공정 기술자, 커널 스택 등
- 하드웨어 컨텍스트 관련 레지스터의 값
- 프로세스는 코어가 저장된 여러 키 레지스터를 변환하고, 이상의 가변 프로세스 컨텍스트 스위치로
- CR3 레지스터는 프로세스 페이지 디렉토리 테이블, 그 주소 공간 데이터를 나타냅니다
- ESP 레지스터 (커널 모드) 프로세스 커널 스택 구조체 스레드 PCB이고, 8킬로바이트가 연속 영역에 저장된 커널 스택, ESP는 IP 어드레스를 획득
- EIP 레지스터 및 다른 처리 하드웨어 컨텍스트를 대신하여 등록, 다음 명령이 실행되고, 환경 될
- 이러한 레지스터는 다른 프로세스의 상태로 한 프로세스의 상태로 전환되고, 전환 프로세스는 심지어 완성
- 실제 코드는, 전환 과정의 각은 실질적으로 두 단계로 이루어
- 가상 주소 다른 다른 물리적 주소로 여러 페이지 테이블을 통해 이동합니다 0x8048400과 같은 처리 할 수 있도록 전역 디렉토리 CR3 스위치 페이지, 새 주소 공간을 설치
- 커널 모드 및 하드웨어 컨텍스트는 새로운 커널 실행을 처리하기 위해 필요한 모든 정보를 제공하기 때문에, 하드웨어 컨텍스트 스위칭 스택은, 상태 레지스터는 CPU를 포함
- 스위칭 (사용자 모드 프로세스 Y의 실행 프로세스 스위칭 X 사용자 모드 처리)하는 과정
- 사용자 모드가 실행 X를 처리
- 중단 (등 예외, 시스템 호출 포함), 하드웨어는 다음과 같은 조치를 완료
- 저장 CS : EIP / SS는 : ESP / EFLAGS은 : 현재 컨텍스트 CPU 사용자 모드 프로세스 X로 밀어 커널 스택
- CS를로드 : EIP (특정의 ISR의 항목) 및 SS를 : ESP (커널 스택 점) : 부하 전류 프로세스 커널 스택 정보, 실행 경로의 시작을 중단 인터럽트 핸들러로 점프
- 공정 X는 X된다 SAVE_ALL은 장면을 보존, 이는 사용자 모드와 커널 모드 프로세스에 대한 인터럽트 문맥 전환, 즉을 완료
- 키 프로세스 컨텍스트 스위치를 제작 switch_to 반환하기 전에 인터럽트 처리 또는 통화 일정 기능 인터럽트. 현재 사용자 프로세스 X 커널 스택 다음 스위칭 처리 선택 (여기서, 프로세스 Y) 커널 스택, 프로세스 콘텍스트를 완료까지
- EIP 레지스터 상태처럼 전환하는 데 필요한
- 런들 후 (\ t 즉, 코드 1의) 사용자 모드 프로세스 번호 1 Y
- restore_all, 사이트 복원하고, 해당 장면의 보존
- IRET - CS 팝업 : EIP / SS를 : ESP / EFLAGS는 하드웨어에서 팝업 푸시 내용이 프로세스의 커널 스택 Y.를 완료 이것은 인터럽트 컨텍스트 전환, Y Y 사용자 모드 처리 커널 모드로부터의 복귀 즉 프로세스를 완료
- 사용자 모드 프로세스 Y를 계속 실행
- 운영 체제 커널
- 리눅스 운영 체제 커널 컨텍스트 스위칭 및 프로세스 컨텍스트는 가장 기본적이고 중요한 서비스를 사용자에게 제공하기 위해 다음과 같은 기본 운영 메커니즘을 전환 인터럽트를 통해 리눅스 운영 체제 커널을 보호 할 수 있습니다. 으로는 다음과 같습니다 :
- 시스템 호출의 형태로 프로세스에 대한 다양한 서비스를 제공
- 하드웨어의 정상적인 작동에 대한 예외 핸들러 인터럽트 서비스 루틴을 통해 다양한 서비스를 제공한다
- 커널 스레드와 인터럽트 서비스 작업에 의한 동적 시스템에 대한 유지 보수 서비스를 제공하는 것은 처리가 지연 될 수 있습니다
- 부분 (커널 모드) 각 논리 비록 더 3기가바이트 볼 모든 프로세스의 일부 콘텐츠 어드레스보다 정확하게보다 더 3기가바이트 모든 프로세스 주소 공간 x86-32 비트 시스템과 동일한 지, 공유 프로세스의 어드레스 공간은 독립적
- 리눅스 운영 체제 커널 컨텍스트 스위칭 및 프로세스 컨텍스트는 가장 기본적이고 중요한 서비스를 사용자에게 제공하기 위해 다음과 같은 기본 운영 메커니즘을 전환 인터럽트를 통해 리눅스 운영 체제 커널을 보호 할 수 있습니다. 으로는 다음과 같습니다 :
둘째, 실험 과정
실험실 건물, 구성 menuOS 사용 :
매크로 정의 switch_to입니다 열기 GDB, 세트 중단 점을, 중단 점을 설정할 수 없습니다, 당신은 context_switch 단계 실행 함수 호출에 필요한 :
C 실행 절차, 절차는 일정 기능에 중지 된, pick_next_task 기능 해제 점에서 context_switch
셋째, 코드 분석
- context_switch 기능 부
static inline void context_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next)
{
struct mm_struct *mm, *oldmm;
prepare_task_switch(rq, prev, next);
mm = next->mm;
oldmm = prev->active_mm;
/*
* For paravirt, this is coupled with an exit in switch_to to
* combine the page table reload and the switch backend into
* one hypercall.
*/
arch_start_context_switch(prev);
if (!mm) { //如果被切换进来的进程的mm为空切换,内核线程mm为空
next->active_mm = oldmm; //将共享切换出去的进程的active_mm
atomic_inc(&oldmm->mm_count); //有一个进程共享,所有引用计数加一
enter_lazy_tlb(oldmm, next); //普通mm不为空,则调用switch_mm切换地址空间
} else
switch_mm(oldmm, mm, next);
if (!prev->mm) {
prev->active_mm = NULL;
rq->prev_mm = oldmm;
}
/*
* Since the runqueue lock will be released by the next
* task (which is an invalid locking op but in the case
* of the scheduler it's an obvious special-case), so we
* do an early lockdep release here:
*/
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
context_tracking_task_switch(prev, next);
// Here we just switch the register state and the stack.切换寄存器状态和栈
switch_to(prev, next, prev);
barrier();
/*
* this_rq must be evaluated again because prev may have moved
* CPUs since it called schedule(), thus the 'rq' on its stack
* frame will be invalid.
*/
finish_task_switch(this_rq(), prev);
}
일정 기능을 실행하고 통화 context_switch 컨텍스트 스위칭 기능하는 새로운 프로세스를 선택합니다
- switch_to 기능 부
#define switch_to(prev, next, last)
do {
/*
* Context-switching clobbers all registers, so we clobber
* them explicitly, via unused output variables.
* (EAX and EBP is not listed because EBP is saved/restored
* explicitly for wchan access and EAX is the return value of
* __switch_to())
*/
unsigned long ebx, ecx, edx, esi, edi;
asm volatile(
"pushfl\n\t" // 保存当前进程flags
"pushl %%ebp\n\t" // 当前进程堆栈基址压栈
"movl %%esp,%[prev_sp]\n\t" // 保存ESP,将当前堆栈栈顶保存起来
"movl %[next_sp],%%esp\n\t" // 更新ESP,将下一栈顶保存到ESP中
// 完成内核堆栈的切换
"movl $1f,%[prev_ip]\n\t" // 保存当前进程的EIP
"pushl %[next_ip]\n\t" // 将next进程起点压入堆栈,即next进程的栈顶为起点,next_ip一般为$1f,对于新创建的子进程是ret_from_fork
__switch_canary
"jmp __switch_to\n" // prve进程中,设置next进程堆栈,jmp与call不同,是通过寄存器传递参数(call通过堆栈),所以ret时弹出的是之前压入栈顶的next进程起点
// 完成EIP的切换
"1:\t" // next进程开始执行
"popl %%ebp\n\t" // restore EBP
"popfl\n" // restore flags
// 输出量
: [prev_sp] "=m" (prev->thread.sp), // 保存当前进程的esp
[prev_ip] "=m" (prev->thread.ip), // 保存当前进仓的eip
"=a" (last),
// 要破坏的寄存器
"=b" (ebx), "=c" (ecx), "=d" (edx),
"=S" (esi), "=D" (edi)
__switch_canary_oparam
// 输入量
: [next_sp] "m" (next->thread.sp), // next进程的内核堆栈栈顶地址,即esp
[next_ip] "m" (next->thread.ip), // next进程的eip
// regparm parameters for __switch_to():
[prev] "a" (prev),
[next] "d" (next)
__switch_canary_iparam
: // 重新加载段寄存器
"memory");
} while (0)
하드웨어 컨텍스트 스위칭 switch_to 매크로 호출 주로 인라인 어셈블리 코드 context_switch
IV 요약
우리는 매크로 pick_next_task () 함수는 프로세스 스케줄링 알고리즘을 캡슐화하는 것을 특징으로 컨텍스트 스위치에 switch_to () 키를 호출, 컨텍스트 스위칭을위한 기능이 실행에 새로운 프로세스를 선택하는 데 사용됩니다 실험적 일정 ()를 발견하고, context_switch 호출 (). need_resched 호출 일정 ()에있어서, 상기 직접 호출 스케줄 (), 또는 사용자 모드로 복귀 (클록 인터럽트, I / O 인터럽트, 시스템 콜 및 예외를 포함), 인터럽트 처리를 마킹, 커널 스레드 ()는 스위칭 프로세스의 직접 예약을 호출 할 또한 클래스 발의 프로세스 스케줄링을 수있는 특별한 커널 스레드를 말을하는 것입니다 인터럽트 처리 일정에서 수행 할 수 있습니다, 일정이 수동적이 될 수 있으며, 사용자 모드 프로세스가 활성 일정을 달성 할 수없는, 그것은 단지 커널 모드 중 하나에 의해 체포 될 수있다 인터럽트 처리 예정된 시점을 스케쥴링.