사막의 여우
Loading...
2016. 2. 18. 20:52

[OS 개발 17] 태스크 스위칭과 보호 (2) - CALL 스위칭

1. CALL 스위칭으로 변경하기 앞서 포스팅에서 현재 태스크에서 다음 태스크로 넘어갈 때, jmp나 Call을 사용한다고 했습니다. 이번에는 앞에서 봤던 코드를 활용하여 CALL 방식으로 프로세스를 불러들이도록 하겠습니다. 따라서 코드를 변경해야 하는데, 지난 코드에서 일부만 수정해 보았습니다. jmp TSS2Selector:0 --> CALL TSSSelector:0 ; CALL 명령으로 태스크 스위칭 한다. jmp $ --> iret ; 이전 태스크로 다시 돌아간다. 2. CALL 스위칭 CALL과 jmp의 가장 큰 차이는 jmp는 다음 태스크를 실행 후, 다시 돌아올 때에도 jmp를 통해 돌아오는 반면, CALL 명령은 iret 명령을 통해 돌아온다는 점입니다. 그리고 CALL 명령은 EFLAGS..

2016. 2. 16. 17:14

[OS 개발 16] 태스크 스위칭과 보호 (1)

1. 태스크의 개념 이번 포스팅에서는 태스크 스위칭에 대해 포스팅하겠습니다. CPU는 작동하는 과정에서 많은 프로세스들을 동시에 실행하고 이를 처리합니다. 여기에서 프로세스가 태스크(Task, 작업)를 가리키는 하나의 유닛으로 볼 수 있습니다. 즉, 태스크는 CPU가 처리하는 일련의 작업들의 각 개체라고 보시면 되겠습니다. 이러한 태스크는 커널에서 관리하고 처리해주는 메커니즘을 적절하게 구현해줘야 합니다. 왜냐하면, 무수히 많은 태스크들이 앞으로 운영체제에서 작동해야 할텐데, 이를 어떤 순서로 어떻게 호출하고 실행할 것인가에 대한 명시가 없다면, 태스크 처리상에 문제가 발생할 것이기 때문입니다. 우리가 다루는 윈도우나 리눅스도 멀티 태스킹 작업을 하면서 보기에는 동시에 프로세스가 처리되는 것처럼 보이지만..

2016. 2. 16. 15:27

[OS 개발 15] 무한 재부팅에 대한 개인적 견해

무한 재부팅에 대하여 어느덧 OS 개발에 대한 15번째 포스트 입니다. IDT에 대한 포스팅까지 마친 시점에서 이번 포스팅에서는 잠시 무한 재부팅 문제에 대해 좀 살펴보기로 하겠습니다. 그 동안 OS를 만들고자 했던 많은 분들이 겪어왔던 고충 중 하나가 바로 무한 재부팅 문제입니다. 이전 포스팅에서도 무한 재부팅에 대해 한번 언급한 걸로 기억하는데, 사실 저 역시 OS 개발진행 과정에서 무한 재부팅 현상을 빈번하게 겪었습니다. 이를 해결하기 위해 수 없이 구글링 해 보았지만 무한 재부팅 문제에 대해 깊이 있게 설명하거나 다루는 글이 생각보다 많지 않습니다. 대부분 글을 보시면 아시겠지만 명확한 결론이 없습니다. 물론 저도 분명한 해결책을 제시하기 위해 이 글을 쓰는 것은 아닙니다(워낙 그 경우가 다양하기..

2016. 2. 12. 22:16

[OS 개발 14] 인터럽트와 예외처리(4) 예외처리 구현하기

1. 예외처리 코드 예외 처리 코드는 이전 인터럽트 코드에서 일부를 추가하였습니다. 특히 Boot.asm은 지난 포스팅에서 사용했던 Boot.asm을 사용하면 되겠습니다. 단, 코드에서 다음과 같이 2섹터를 사용하기 위해 al에 넣을 값을 2로 바꿔주기만 했습니다. Boot.asm 커널부분에서는 일부 내용이 추가되었는데, 대부분 이전 포스팅을 참고하면 해석 가능합니다. 바뀐 부분 중에서 일부 설명이 필요한 부분만 흰색으로 구역을 설정했고, 이에 대한 내용은 그 아래 설명에서 확인하면 될 것 같습니다. Kernel.asm 2. 코드 분석 설명1 이 부분도 이전에 설명했던 인터럽트 코드와 비슷하게 해석하면 되겠지만, 0으로 나누는 divide 예외는 IRQ 0번이므로 0값을 edi에 넘겼습니다. 설명2 여기..

2016. 2. 12. 19:24

[OS 개발 13] 인터럽트와 예외처리(3) PIC와 인터럽트 구현하기

1. 코드 실행하기 앞서 두 포스팅에 걸쳐서 IDT에 대해 알아보았습니다. IDT와 PIC, 예외의 개념들을 토대로 다음과 같이 어셈블리 코드로 구현해 보았습니다. (init.inc는 이전 파일과 내용은 그대로이며, 이름만 바뀌었습니다.) 2. 코드 분석 Boot.asm 분석 설명1. 플로피 디스크 드라이브의 모터를 끄는 부분인데, 0x3F2번지에 out I/O명령을 사용하여 XOR 연산을 통해 프로그램 실행 도중에는 모터가 멈추도록 합니다. 설명2. 이 부분이 앞서 포스팅에서 다뤘던 PIC를 직접 설정해주는 부분입니다. 하드웨어 인터럽트를 지정해주기 위해 마스터와 슬래이브 PIC를 구현하였습니다. PIC 포스팅을 살펴보면서 코드를 이해하면 좋을 듯 합니다. 2016/02/12 - [분석연구소/운영체제]..

2016. 2. 12. 13:58

[OS 개발 12] 인터럽트와 예외처리(2) PIC와 예외처리

1. PIC의 개념 인터럽트는 소프트웨어 인터럽트와 하드웨어 인터럽트로 분류할 수 있습니다. 그런데 키보드 입력, 디스크 제어 등은 하드웨어 단에서 인터럽트가 걸려야 하기 때문에, 구현할 때 PIC에 대해 어느 정도 알고있어야 합니다. PIC는 Programmable Interrupt Controler의 약자로, 하드웨어 인터럽트를 처리하는 역할을 담당합니다. 대부분의 PC는 서로 다른 주소에 위치한 두 PIC를 갖습니다. 이 중 하나는 개별적 IRQ라인들 15개 중에서 각각 0~7, 8~15번째의 IRQ를 가지고 있습니다. 아래의 그림을 참고하시기 바랍니다. PIC는 크게 master –slave 구조로 구성되어 있습니다. 그리고 각 PIC에는 8개의 핀(마스터-0~7핀, 슬레이브-8~15핀)이 붙어있..

2016. 2. 11. 11:11

[OS 개발 11] 인터럽트와 예외처리(1) IDT의 개념

1. IDT의 개념 이제 GDT를 끝내고 IDT 개념에 대해 다룰 순서입니다. IDT는 Inturrupt Descriptor Table의 약자로, 위키피디아는 다음과 같이 정의하고 있습니다. 인터럽트 벡터 테이블을 구현하기 위해 x86 아키텍처에서 사용되는 데이터 구조체이다. IDT는 프로세서가 인터럽트와 예외에 대한 정확한 반응을 결정하기 위해 사용된다. 컴퓨터가 동작할 때, 많은 행위들이 일어나는데, 이 행위에 대해서 CPU에게 알려줘야 할 필요가 있습니다. 그래야 다른 행동과의 충돌을 피할 수 있을 것입니다. 이러한 차원에서 IDT의 개념이 생겼으며, GDT와 비슷하게 IDT 역시 인터럽트에 대한 정보가 저장된 디스크립터를 테이블 양식으로 저장하고 있습니다. 인터럽트 디스크립터의 세부 정보는 아래 ..

2016. 2. 10. 21:56

[OS 개발 10] 32비트 커널 로더(4) - 커널 구현과 분석

1. 부트로더에서 커널 구현부로의 점프 앞서 언급한대로, 부트로더에서 커널 구현부로 넘어가는 부분을 우선 구현해야할 것입니다. 다음 코드를 보시죠. 위 코드는 부트로더를 확장하여 작성한 코드입니다. 일부 앞서 포스팅에서 언급했던 내용은 해당 포스팅에서 설명을 참고하도록 하고, 추가된 흰색 구역을 위주로 설명하고자 합니다. 설명1 보호 모드에 진입하겠다는 것을 0번 컨트롤 레지스터(CR0)를 통해 CPU에 알려줘야 합니다. 컨트롤 레지스터에 대해서는 나중에 별도의 포스팅을 통해 제대로 설명해보도록 하겠습니다. 일단, CR0 레지스터를 통해 앞으로 32비트 단위로 보호모드를 사용하겠다는 것을 알린다는 것만 알면 될 것 같습니다. 그런데 or연산을 하는 이유는? 비트중에서 값이 바뀌는 비트 외의 비트 값은 변..

2016. 2. 6. 15:32

[OS 개발 9] 32비트 커널 로더(3) - GDT의 개념과 적용

1. GDT의 개념 이전 포스팅을 마치면서 잠깐 GDT에 대해 언급하였습니다. 16비트 리얼 모드에서 32비트 보호 모드로 운영 모드를 바꿔야 하며, 이를 위해 GDT를 사용한다고 했는데요,. 본 포스트에서는 GDT 에 대해 알아보도록 하겠습니다. GDT를 풀어쓰자면 글로벌 디스크립터 테이블(Global Descriptor Table, GDT)이며, 말 그대로 무언가에 대한 기술서를 테이블 형식으로 한데 모아둔 형태를 의미합니다. 여기에서 무언가는 각 세그먼트 영역을 나타냅니다. 즉, 세그먼트 영역에 대한 데이터를 일정한 디스크립터 형식으로 기술하고 이를 하나의 테이블에 모아두고자 하는 것이 GDT를 사용하는 목적이죠. 그렇다면 이 디스크립터라는 녀석은 도대체 어떤 형식을 갖추고 있는 걸까요? 다음 그림..

2016. 2. 5. 15:30

[OS 개발 8] 32비트 커널 로더(2) - 리얼 모드와 보호 모드

32비트 보호모드로의 전환 전 포스팅에서 마지막에 16비트 모드에서 32비트의 전송 체계로 바꿔줘야 한다고 했습니다. 이게 무슨 의미 일까요? 부트로더의 개념 및 제작, 실행, 분석 포스팅에서 제작했던 부트 로더 프로그램은 사실 16비트 단위로 데이터가 처리되는 리얼 모드(Real Mode)에서 동작되고 있었습니다. 리얼 모드는 80286 이후의 x86 호환 CPU의 운영 방식입니다. 그런데 리얼 모드의 여러가지 한계, 혹은 문제로 인해 우리는 이후 커널 프로그램을 구동할 때에는 운영 모드를 바꿔줘야 합니다. 여기에서 우리는 32비트 보호 모드(Protected Mode)로 운영 모드를 전환할 것이다. 이렇게 운영 모드를 전환해줘야 하는 이유에는 여러가지가 있습니다. 1. 앞서 레지스터 세그먼트와 오프셋..