시스템 콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어, CPU에게 실행시켜야한다.
시스템 콜 실제 코드
eax 레지스터에 시스템 콜 번호를 넣고,
ebx 레지스터에는 시스템 콜에 해당하는 인자값(함수의 인자 값 포함)을 넣고,
소프트웨어 인터럽트 명령을 호출하면서 0x80값을 넘겨줌
mov eax,1// 1 = 시스템콜번호
mov ebx,0// 0 = 인자int0x80// 무조건 마지막에는 CPU에서 제공하는 OP code(인스트럭션 코드)가 들어가며, intel에서 제공하는 것 중에는 int가 있다.// 0x80 = 인터럽트 번호, 시스템 콜은 0x80으로 정해져 있다.
1 = 시스템콜번호
0 = 인자
int 0x80 : 무조건 마지막에는 CPU에서 제공하는 OP code(인스트럭션 코드)가 들어가며, intel에서 제공하는 것 중에는 int가 있다.
0x80 = 인터럽트 번호, 시스템 콜은 0x80으로 정해져 있다.
💎 인터럽트와 시스템 콜(고급)
시스템콜 인터럽트 명령을 호출하면서 0x80값을 넘겨줌
CPU는 사용자 모드를 커널모드로 바꿔줌
IDT(Interrupt Descriptor Table)에서 0x80에 해당하는 주소(함수)를 찾아서 실행함
인터럽트 번호 (0x80) : 주소,코드(system_call()) => 인터럽트 번호를 통해 코드를 실행.
system_call()함수에서 eax로부터 시스템콜 번호를 찾아서, 해당 번호에 맞는 시스템콜 함수로 이동
인터럽트번호에 의해 호출된 인터럽트 함수가 시스템콜 번호를 이용하여, 시스템콜 함수를 호출하게 됨.
해당 시스템 콜 함수 실행 후, 다시 커널 모드에서 사용자 모드로 변경하고, 다시 해당 프로세스 다음 코드 진행
사용자/커널 모드와 프로세스, 인터럽트
시간축을 기준으로, PA가 실행되다가 시스템 콜을 호출
Timer interrupt에 따라 process scheduler가 process를 실행되게 함.
중요한 것은 interrupt는 시스템 콜에 의해 호출되므로 커널 모드로 변경된다는 것!!
인터럽트와 IDT
인터럽트는 미리 정의되어 각각 번호와 실행 코드를 가리키는 주소가 기록되어 있음
어디에? IDT(Interrupt Descriptor Table)에 기록(이벤트 번호에 맞는 운영체 내부의 코드 실행)
언제? 컴퓨터 부팅시에 가장 먼저 운영체제가 기록
어떤 코드? 운영체제 내부의 코드 (커널 모드/커널 영역)
다시 예를 보면,
항상 인트럽트 발생시, IDT를 확인
시스템 콜 인터럽트 명령은 0x80 번호가 미리 정의
인터럽트 0x80에 해당하는 운영체제 코드는 system_call()이라는 함수
즉, IDT에는 0x80 -> system_call()와 같은 정보가 기록되어 있음
리눅스의 예
0~31 : 예와상황 인터럽트(내부/소프트웨어 인터럽트 , 일부는 정의 안된채로 남겨져 있음)
32~47 : 하드웨어 인터럽트(주변장치 종류/갯수에 따라 변경가능)
128 : 시스템콜(0x80)
인터럽트와 프로세스의 관계
프로세스 실행 중 인터럽트 발생시
현 프로세스 실행 중단
IDT에서 해당하수 찾아 인터럽트 처리 함수 실행(운영체제)
현 프로세스 재 실행
인터럽트와 스케쥴러의 관계
선점형 스케쥴러 구현 예 - 수시로 타이머 인터럽트 발생 - 운영체제가 타이머 인터럽트 발생 횟수를 기억해서 5번 타이머 인터럽트 발생하면, 현재 프로세스를 다른 프로세스로 바꿔준다.