기본적인 컴퓨터 구조와 부팅
✔️ 폰노이만 구조
오늘 날의 컴퓨터는 대부분 폰노이만 구조를 따릅니다.
폰노이만 구조는 CPU, 메모리, 입출력장치, 저장장치가 버스로 연결되어 있는 구조를 말합니다.
이 구조가 등장하기 이전에는 하드와이어링 형태로 전선 연결을 계속 바꾸는 형태였습니다.
폰노이만 구조에서 가장 중요한 특징은 '모든 프로그램은 메모리에 올라와야 실행할 수 있다'는 것입니다.
저장장치에 있는 프로그램이 있다고 해서 실행되는 것이 아니라 메모리에 올라와야 실행할 수 있는 것입니다.
✔️ CPU의 기본 구성
CPU는 명령어를 해석하여 실행하는 장치로 산술논리 연산장치(ALU), 제어장치(Control Unit), 레지스터로 구성됩니다.
- 산술논리 연산장치(ALU)
CPU에서 데이터를 연산하는 장치입니다.
데이터의 덧셈, 뺄셈, 곱셈, 나눗셈 같은 산술 연산이나 AND, OR 같은 논리 연산을 수행합니다.
- 제어장치(Control Unit)
CPU에서 작업을 지시하는 부분입니다.
- 레지스터
CPU 내에서 사용할 데이터를 임시 보관하는 곳입니다.
저장 장치의 속도 순서대로 레지스터 > 메모리 > 하드디스크지만 용량은 정반대입니다.
📌 CPU의 명령어 처리 과정
int sum;
int a = 2, b =3;
sum = a + b;
위 코드를 어셈블러로 변환한 다음 기계어로 바꾸어야 기계가 인식할 수 있습니다.
LOAD mem(100), register 2;
LOAD mem(120), register 3;
ADD register 5, register 2, register 3;
MOVE register 5, mem(160);
LOAD로 메모리 100번지에 있는 값을 레지스터 2로 가져온다는 의미입니다.
메모리 100번지에는 변수 a의 값인 2가 있다고 하고 120번지에는 변수 b의 값인 3이 있다고 하면
ADD를 통해 register 2, 3의 값을 더하고 register 5에 저장합니다.
MOVE 명령어를 통해 register 5의 값을 메모리 160번지(sum)로 옮깁니다.
CPU가 연산을 하려면 필요한 데이터를 CPU로 가져와 임시로 보관해야 하고 이 때 사용하는 장소가 레지스터입니다.
제어장치는 명령어를 해석하여 제어 신호를 보내고 CPU 내의 데이터 흐름을 조절하는 역할을 합니다.
위 예제에서 제어신호는 '메모리에서 데이터를 가져와라', '덧셈을 실행하라', '덧셈한 결과를 메모리에 옮겨놔라'입니다.
📌 레지스터의 종류
CPU는 필요한 데이터를 메모리에서 가져와 레지스터에 저장하고 산술논리 연산장치를 이용하여 연산한 후 그 결과를 레지스터에 저장했다가 다시 메모리로 옮깁니다. 이 때 사용되는 레지스터는 데이터 레지스터와 주소 레지스터입니다.
- 사용자 가시 레지스터
- 데이터 레지스터(DR) : 메모리에서 가져온 데이터를 임시로 보관 (범용 레지스터or일반 레지스터라고 부름)
- 주소 레지스터(AR) : 데이터 또는 명령어가 가져온 메모리의 주소가 저장
- 사용자 불가시 레지스터
- 프로그램 카운터(PC) : 다음 실행할 명령어의 주소를 가리킴 (명령어 포인터라고도 한다)
- 명령어 레지스터(IR) : 현재 실행중인 명령어를 저장함
- 메모리 주소 레지스터(MAR) : 메모리에서 데이터를 가져오거나 메모리로 데이터를 보낼 때 주소를 저장
- 메모리 버퍼 레지스터(MBR) : 메모리로부터 가지고 온 데이터나 메모리로 옮겨갈 데이터를 임시 저장
- 프로그램 상태 레지스터(PSR) : 연산결과(양수, 음수, 0이 아닌지, 자리 올림 유무 등)을 저장
📌 레지스터 예시
LOAD mem(100), register 2;
1. 프로그램 카운터에는 실행 중인 코드의 행 번호(주소)가 저장되고 이 번호는 제어장치에 전송됩니다.
2. 명령어 레지스터에는 명령어를 저장해야 하므로, 'LOAD'가 탑재됩니다.
3. 제어장치가 명령어 레지스터에 있는 명령어를 해석하여 메모리에 있는 데이터 'mem(100)'을 가져오라는 제어 신호를 보냅니다.
4. 메모리 주소 레지스터에는 메모리 주소 '100'이 저장되고 메모리 관리자는 메모리 100번지에 저장된 값을 메모리 버퍼 레지스터로 가져옵니다.
5. 제어장치는 메모리 버퍼 레지스터에 저장된 값을 레지스터 2로 옮깁니다.
📌 메모리 보호
메모리에는 프로세스들이 적재되어 실행되기 때문에 작업이 진행 중인 메모리에 벗어나는 주소를 침범하는 것은 다른 프로세스에 접귾나느 것이기 때문에 실행에 오류를 일으킵니다.
따라서 OS는 경계 레지스터와 한계 레지스터를 지정하여 메모리를 보호합니다.
- 경계 레지스터 : 현재 진행 중인 작업의 첫번째 주소
- 한계 레지스터 : 현재 진행 중인 작업이 차지하고 있는 메모리 크기
다음과 같이 경계 레지스터 140 + 한계 레지스터의 주소만 접근이 가능합니다.
만약 두 레지스터의 값을 벗어난다면 메모리 오류를 일으켜 모든 작업을 중단시킵니다.
✔️ 버스
버스는 CPU, 메모리, 주변 장치 간에 데이터를 주고 받을 때 사용합니다.
버스에서는 다음 작업을 지시하는 제어신호, 메모리 위치 정보를 알려주는 주소, 처리할 데이터가 오고 가며 각각 제어버스, 주소버스, 데이터버스에 실립니다.
- 제어 버스
제어장치와 연결된 버스로 CPU가 메모리와 주변 장치에 제어 신호를 보내기 위해 사용합니다.
마찬가지로 메모리와 주변 장치도 작업 완료되거나 오류 발생 시에 CPU에게 보내기 위해 양방향입니다.
- 주소 버스
메모리 주소 레지스터와 연결된 버스로 메모리나 주변 장치에 데이터를 읽거나 쓸 때 위치 정보를 보내기 위해 사용하며 단방향입니다. (메모리 주소를 확인하는 용도)
- 데이터 버스
메모리 버퍼 레지스터와 연결된 버스로 데이터 이동이 양방향으로 이뤄집니다.
✔️ 부팅(Booting)
응용 프로그램은 운영체제가 메모리에 올려서 실행합니다. 그렇다면 운영체제는 누가 메모리에 올려서 실행할까요?
컴퓨터를 켰을 때 운영체제를 메모리에 올리는 과정을 '부팅'이라고 합니다.
컴퓨터의 구조를 단순히 하면 위의 그림과 같습니다.
Processor는 일반적으로 CPU를 말하고 Main Memory는 RAM과 ROM으로 나누어져 있습니다.
- RAM : 휘발성으로 메모리의 대부분을 차지하며 실제 프로그램이 할당되는 곳
- ROM : 비휘발성으로 메모리에서 극히 일부분을 차지한다
ROM은 하드디스크와 같이 비휘발성으로 전원이 꺼져도 그 안의 내용은 계속 유지됩니다.
RAM은 휘발성이므로 전원이 꺼지면 메모리 안의 모든 내용이 지워집니다.
사용자가 컴퓨터의 전원을 켜면 CPU가 ROM에 저장된 BIOS를 실행시킵니다.
BIOS는 POST(Power-On Self-Test)와 부트 로더(Boot loader)를 실행합니다.
- POST : CPU, 메모리, 키보드 등과 같은 주요 하드웨어가 제대로 작동하는지 확인하는 것
- Boot loader : 1차 부트로더인 MBR에서 운영체제를 찾아 RAM으로 가져오는 것
📌 부트 로더(Boot loader)
1차 부트로더는 용량이 512Byte 밖에 되지 않기 때문에 윈도우 같은 복잡한 운영체제의 커널을 로드하기에 부족합니다.
그렇기 때문에 1차 부트로더를 통해 커널을 로드하듯이 로드한 뒤 2차 부트로드 통해 커널을 로드합니다.
- 1차 부트로더 : MBR(Master Boot Record), PBR(Partition Boot Record)
- 2차 부트로더 : GRUB(리눅스, 윈도우), SYSLINUX(리눅스), LILO(리눅스), BOOTMGR(윈도우), NTLDR(윈도우)
📄 참고
https://math-coding.tistory.com/83?category=805874