Be myself :: Be myself

달력

42024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

5. 보호

컴퓨터구조&OS/OS 2014. 5. 5. 21:23

1 개요

CPU는 때때로 커널과 함께 명령어들을 체크해 문제가 일어나지 않도록 검사한다. 합당한 명령어만 실행시키고 그렇지 않으면 커널이나 유저프로그램 자신이 이 에러를 다시 조정하도록 한다. 이 때, 체크하는 것으로는 다음과 같은 것이 있다.
1.프로그램 또는 프로세스가 세그먼트 외의 메모리 위치를 지정하지 못하게 하는 Limit Check
2.읽기, 쓰기 등의 속성에 맞게 접근되었는지 확인하는 type검사
3.접근 가능한 곳에 접근하는지 확인하는 특권레벨 체크,
4.명령어 세트 체크

위의 4가지를 검사하는데, 우리는 특권레벨과 관련된 내용을 공부할 것이다.

2 특권레벨

특권레벨과 관련된 용어를 설명하고, 특권레벨이 낮은 계층에서 레벨이 높은 계층으로 접근하는 방법들과 그 때의 스택의 변화를 알아볼 것이다.

2-1 용어 설명

-CPL(Current Privilege Level)
: CPL은 현재 실행되고 있는 특권레벨이다. CS, SS셀렉터 레지스터의 0,1번째 비트에 있는 수이다.

-DPL(Description Privilege Level)
: 디스크립터에 기재된 DPL값이고 2비트로 표현된다. 디스크립터를 통한 세그먼트 영역으로의 모든 접근에서 항상 CPL과 DPL의 관계가 체크된다.

-RPL(Requested Privilege Level)
: 콜게이트(낮은 특권레벨에서 높은 특권레벨의 루틴을 사용할 수 있게 하는 관문)를 통해 레벨이 낮은 프로세스가 높은 프로세스에 접근하는 일이 생기는데, 이를 악용할 소지를 없애기 위해 어느 레벨에서 요청했는지 적어놓는 역할을 한다.

-콜게이트
: 다른 세그먼트 디스크립터와 함께 GDT테이블에 디스크립터로써 포함되며, 또 하나의 세그먼트 정의라 셍각하여도 좋다. 유저 프로그램은 코드 셀렉터의 사용법과 마찬가지로 이 디스크립터를 셀렉터로 설정하여 Jmp나 Call명령을 내린다.

<콜게이트 디스크립터>

 

2-2 특권계층 변경

특권계층이 변경되는 상황을 알아 보겠다.
예외가 발생했을 때. (0으로 나눈다던지, Limit크기를 넘어 가는 접근을 한다던지 등)
하드웨어 인터럽트가 발생 했을 때
소프트웨어 인터럽트가 발생 했을 때(int 0x80 명령어로 트랩 게이트이용)
콜게이트 이용—Jmp, Call

이 중, 1번과 2번은 프로그래머의 의지와는 상관 없이 레벨변경이 일어나는 상황이므로, 우리가 관심을 가져야 할 부분은 3번과 4번이다. 3번의 경우, eax, ebx, ecx등의 레지스터를 이용해 인수를 정하고, int 0x80명령어로 인터럽트하는 수순으로 이루어 진다. 보통 셸코드 작성시 많이 사용하는 방법이다.

콜게이트를 이용해 계층을 변경하는 방식으론 Jmp와 Call이 있는데 원칙적으론, Jmp명령을 사용하여 계층변경은 불가능하지만 콜게이트를 이용해 가능하게 된 것이고, Call 명령은 낮은 특권계층에서 높은 특권계층으로의 접근을, RET는 높은 계층에서 낮은 계층으로의 전환을 담당한다.

Call 명령을 통해 계층변환이 이루어 지는 방식은 레벨3에서 call 명령으로 레벨0 루틴을 불러 내면 CS셀렉터의 0,1의 비트에 00 이 들어가고, 이때의 CPL은 0이다. 루틴이 끝난 후 RET로 레벨3으로 돌아가게 되는데 이때는 CS셀렉터의 0,1비트에 11(십진수 3)이 들어가고 CPL은 3이된다.

 

2-3 특권레벨 변동시 스택의 변화

일단 설명을 먼저 한 후 그림을 통해 정리하드록 하겠다.

<Call 명령이 내려졌을 때>

CPU는 이 태스크의 TSS영역에 있는 SS0와 ESP0값을 참조하여 커널모드 스택에 현재 유저태스크가 사용하고 있는 SS,ESP,CS,EIP를 차례로 PUSH한다. 그리고 SS와 ESP레지스터에 SS0와 ESP0의 값을 넣는다
콜게이트에 지정된 커널모드의 루틴주소로 점프하고 실행
RET명령시 스택에 저장된 EIP, ESP등을 pop하여 원레 레지스터 값으로 복원한다.
*인자가 있을 시 콜게이트 디스크립터에 입력된 인자의 갯수 만큼을 준수한다.

<인터럽트 예외가 발생 했을 때>

이 때는 EFLAGS가 ESP와 CS사이에 추가된 것만 빼면 콜게이트와 다를 것이 없다. 단지 특권계층 0 에서 인터럽트가 발생하면 ESP와 SS는 PUSH될 필요가 없다는 것만 주의하면 된다.

'컴퓨터구조&OS > OS' 카테고리의 다른 글

7. 페이징  (0) 2014.05.05
6. 유저모드 Task switching  (0) 2014.05.05
4. Task switching  (0) 2014.05.05
3. 인터럽트 처리  (0) 2014.05.05
2. Protected 모드로의 전환  (0) 2014.05.05
Posted by flack3r
|

1 개요

이제 OS의 핵심적인 역할이라 볼 수 있는(필자의 생각에..ㅎㅎ) 멀티 태스킹이 어떻게 구현되는지 살펴보겠다. 일단, 커널단 에서의 멀티 태스킹을 살펴보고, 다음 장에서 세그먼트 보호의 개념을 다룬 후 유저영역에서의 멀티 태스킹을 살펴볼 예정이다. CPU에서 지원하는 멀티 태스킹 기술은 2가지가 있다. Call과 Jmp를 이용한 방법이 그것이다. 각 방법들을 하나하나 살펴보자.

2 태스크 스위칭과 tss

참고로 Real mode에선 멀티 태스킹이 지원이 되지 않는다. 따라서 멀티 태스킹은 protected mode에서 작동되고 인텔 80286이상에서 태스크 스위칭을 cpu레벨에서 지원한다.
여기서 멀티 태스킹이 무엇인지 짚어보고 가자. 말 그대로 음악을 들으면서 문서작업을 하거나 영화를 보면서 인터넷을 하거나 등의 여러 가지 일을 동시에 하는 것을 나타낸다. 하나의 프로그램을 실행시켰을 때, 하나의 '프로세스'가 생성되는데, cpu는 동시에 같은 프로세스를 처리 할 수 없다. 그렇다면 어떻게 멀티 태스킹이 된단 말인가?
이는 컨텍스트 스위칭 이라는 마술적인 기법을 사용하기 때문이다. 일정한 시간이 되거나, 어떠한 조건이 만족되면, OS의 스케줄러는 실행되고 있는 프로세스관련 메모리를 어떠한 메모리 영역에 저장을 하고 새로 시작되는 프로세스의 메모리들을 로드시켜 연산을 하는 것이다.
그렇다면 어떠한 메모리 영역에 저장을 시켜야 할까? 그것이 바로 TSS(Task state segment)이다.

TSS를 등록하기 위해선 TSS디스크립터를 GDT에 지정시켜 둔다.일단, TSS의 생김새부터 보고 가자.

그림의 설명을 보면 이해가 될 것이다.

그 다음 TSS를 선택하는 TSS세그먼트 디스크립터를 볼 순서인데, GDT의 생김새와 별 차이가 없고 Limit부분이 항상 0x67이상이어야 한다는 점과, Type에 B비트가 있는데, 이 부분은 이 태스크가 실행 중인지 혹은 실행을 기다리고 있는지를 나타내는 점이 다를 뿐이다. 따라서 별도의 그림은 생략한다.

2-1 JMP를 이용한 스위칭

지금까지 기본 배경지식을 알아 보았고 JMP를 이용한 스위칭 과정이 어떻게 되는지 그림을 통해 설명하겠다.

1. 프로그램이 Protected mode로 넘어오고 LTR명령으로 TSS영역을 저장한 후에 JMP TSS selector명령을 한다.
2. CPU내부의 TR레지스터와 GDTR레지스터를 참조하여 GDT에 있는 TSS selector를 찾는다.
3. TSS selector의 base Address를 참조하여 tss1영역을 찾는다.
4. Tss1영역에 현재 CPU레지스터값 저장
5. GDT에서 Tss2 디스크립터를 찾는다. 이 때, TR레지스터에 Tss 2 selector가 들어간다.
6. Tss 2 selector의 base Address를 참조하여 tss2 영역을 찾는다.
7. Tss2영역의 값 복원
8. 프로그램 실행.

2-2 Call명령을 이용한 스위칭

Call방식이 Jmp방식과 다른 점은 명령어 상에서 Jmp대신 Call을 한다는 점과 이전 태스크로 돌아가는 부분이 IRET로 바뀌는 것 뿐이다. 여기서 주의할 것은 IRET명령어가 인터럽트의 끝을 알리는 명령어와 동일하기 때문에 이를 구별하기 위해 TSS디스크립터의 B비트와 EFLAGS의 NT비트를 이용한다.

또 다른 차이점은 Call명령의 경우 비선점형 방식이라 실행되는 태스크에서 다른 태스크로 전환하는 명령을 수동으로 해 주어야 하는 반면 Jmp명령어는 컨텍스트 스위칭이 자유롭긴 하지만 유저모드의 태스크를 스위칭 하는데에는 약간의 문제점을 가지고 있다.

그럼, Call명령을 사용한 스위칭의 과정이 어떻게 이루어 지는지 그림을 통해 정리하고 끝을 내겠다.

 

'컴퓨터구조&OS > OS' 카테고리의 다른 글

6. 유저모드 Task switching  (0) 2014.05.05
5. 보호  (0) 2014.05.05
3. 인터럽트 처리  (0) 2014.05.05
2. Protected 모드로의 전환  (0) 2014.05.05
메모리 구조  (0) 2014.05.04
Posted by flack3r
|

1 개요

인터럽트는 일반적인 의미로는 무엇인가를 방해한다는 뜻이다. 하지만 컴퓨터에선 방해한다는 의미보단, 우선순위가 높은 일을 먼저 처리하라고 알려주는 의미가 더 강하다. 인터럽트에 의해 우리는 마우스의 움직임, 키보드의 입력 등을 처리할 수 있는 것이다. 그렇다면 이러한 인터럽트를 어떻게 커널에서 처리하는지 그림으로 대략적인 개념을 잡고 가겠다.

 

 

 

 

 

 

 

 

 

 

 

 

 

2 PIC란??

인터럽트의 처리루틴을 가진 테이블(IDT)를 알아보기 전에 PIC의 개념을 잡고 가자. PC는 모든 외부로부터의 인터럽트(모니터, 마우스, 프린터, 스피커 등)을 8259A라는 칩을 통하여 입력 받는다. 이 8259A를 보통 PIC라 부른다. 여기까지만 말하면 PIC와 IDT가 무슨 연관인지 궁금해 질 것이다. 인터럽트가 처리되는 과정은, PIC에서 IRQ(인터럽트 처리 요청)을 받아 CPU의 INT포트에게 신호를 보내고, CPU에선 이 IRQ 번호를 이용해 IDT테이블에서 어떤 핸들러를 실행 시킬지 선택한 후, 인터럽트를 처리시킨다. 좀더 자세한 과정을 그림을 통해 알아보자.

Master PIC와 Slave PIC 각각의 작동순서를 살펴보면서 큰 흐름을 잡자. 일단 하인(?) 은 주인(?)의 IRQ 2번에 연결되어 있다. (왜 2번인지는 IBM의 고객센터에 따지자.) 그리고 각 장치들에서 IRQ요청이 왔다는 가정을 하자.

2-1. Master PIC동작 순서

자신의 INT핀에 신호를 실어 CPU의 INT피에 신호를 준다.
CPU는 이 신호를 받아 EFLAGS의 레지스터의 IE비트가 1로 세팅되어 인터럽트를 받을 수 있는 상황이라면 /INTA를 통해 마스터 PIC에 인터럽트를 잘 받았다는 신호를 보낸다.
마스터 PIC는 /INTA신호를 받고 몇 번째 IRQ에 연결된 장치에서 인터럽트 신호를 받았는지 숫자로 데이터 어드레스로 CPU에 전달한다.
CPU는 Protected Mode로 실행 중 이라면, 이 값을 리맵핑하여(IRQ번호를 바꿈) IDT에서 그 번호에 맞는 디스크립터를 찾아 처리한다.

여기서 리맵핑을 하는 이유는, 하드웨어 인터럽트와 예외상황 에서의 인터럽트를 구분하기 위해서 이다. CPU는 프로그래머가 시스템에 크거나 작은 충격이나 오류를 줄 수 있는 명령어를 실행시키는 것을 방지하기 위하여 예외처리를 하는데, 이 때 IRQ의 번호가 0번부터 시작해 PIC에서 받은 IRQ번호와 충돌이 일어 난다. 따라서, PIC에서 받은 IRQ번호를 리맵핑 한다.

2-2. Slave PIC동작 순서

자신의 INT핀에 신호를 실어 마스터 PIC의 IRQ2번핀에 인터럽트 신호를 보낸다.
마스터 PIC는 자신의 INT번호에 신호를 실어 CPU에게 전달한다.
그 이후는 마스터PIC의 처리 순서와 동일하다.

2-3. PIC초기화

PIC를 제대로 동작시키게 하기 위해선, PIC를 초기화시킬 필요가 있다. 각 PIC가 자신이 마스터인지 슬레이브인지 알아야 하고, 어떤 모드로 움직일지 등을 설정해야 하기 때문이다. 초기화 명령 프로그램의 구성은 ICW1, ICW2, ICW3, ICW4로 구성되는데 ICW는 하나의 명령어로 생각하자.

ICW1.

ICW2

ICW2는 PIC가 인터럽트를 받았을 때, IRQ번호에 얼마를 더해 CPU에게 알려줄지 지정한다. 즉 IRQ번호 리맵핑의 역할을 한다.

ICW3
PIC의 마스터, 슬레이브로서의 연결방법을 나타낸다. (마스터PIC)
S0~S7은 마스터 PIC의 각 IRQ선을 나타낸다. 각 비트에 0을 넣으면 그 IRQ선은 하드웨어 장치에 연결되어 있다는 것을 뜻하고, 비트에 1이 있으면, 그 IRQ선은 슬레이브 PIC가 연결되어 있다는 것을 나타낸다. (슬레이브 PIC)
3~7비트는 0으로 해두고 ID0~ID2는 Slave PIC가 Master PIC의 몇 째 IRQ에 연결되어 있는지 나타내는데 마스터 PIC에선 1로 나타내는 반면 여기선 숫자로 나타낸다.

ICW4

3 idt의 동작

PIC에서 인터럽트가 와 이를 CPU에서 어떤 순서로 처리하는지 등을 알아 보겠다.

3-1. Idt등록

동작 순서를 알아 보기 전에 IDT(Interrupt Descriptor Table)이 어떻게 생겼는지 알아 보자.

P는 페이지와 관련되어 있는데 항상 1이다 DPL은 핸들러가 실행될 특권레벨을 나타내고, D는 0이면 16비트, 1이면 32비트임을 나타낸다.

이러한 IDT를 IDTR레지스터에 등록하여 참조될 수 있도록 한다.

3-2 IDT동작 순서

그림으로 정리하고 이번 장을 마치겠다.

'컴퓨터구조&OS > OS' 카테고리의 다른 글

5. 보호  (0) 2014.05.05
4. Task switching  (0) 2014.05.05
2. Protected 모드로의 전환  (0) 2014.05.05
메모리 구조  (0) 2014.05.04
1.OS의 시작  (0) 2014.05.04
Posted by flack3r
|