Linux/モダーンリナックス

2.Linux Kernel

YOOANT 2026. 4. 25. 19:49

1.리눅스 아키텍쳐

・하드웨어 계층

CPU와 메인 메모리부터 디스크 드라이브, 네트워크 인터페이스는 물론 키보드나 모니터 같은 주변 디바이스까지 모두 일컫는다.

 

・커널 계층

운영체제의 가장 하부이자 핵심 계층으로, 컴퓨터의 자원(CPU, 메모리, 장치 등)을 실제로 관리하고 통제하는 구역이다. 사용자가 사용하는 응용 프로그램(User Space)과 물리적인 기계(Hardware) 사이에서 다리 역할을 수행한다.

 

・사용자 영역계층

shell같은 운영체제 구성요소, ps나 ssh같은 유틸리티, X윈도우 시스템 기반 데스크톱 같은 그래픽 사용자 인터페이스를 비롯해 대부분의 앱이 실행되는 곳을 일컫는다.

 

커널과 사용자 영역 사이에는 System Call이라는 인터페이스가 있다.

하드웨어와 커널 사이의 인터페이스는 System Call과 달리 단일 인터페이스가 아니라 일반적으로 하드웨어별로 그룹화된 개별 인터페이스 모음으로 구성된다.

 

그림에서도 보듯이 shell이나 grep,find.ping 같은 유틸리티처럼 일반적으로 리눅스 운영체제의 일부로 여기는 많은 것이 실제로는 커널의 일부가 아니라 사용자 영역의 일부이다.

 

일반적으로 커널 모드는 추상화를 제한함으로써 빠르게 실행함을 의미하는 반면, 사용자 모드는 상대적으로 느리지만 더 안전하고 편리한 추상화를 의미한다. 모든 앱이 사용자 영역에서 실행되기 때문에 커널 개발자가 아닌 이상 거의 항상 커널 모드를 무시할 수 있다.

・커널 모드: "추상화를 제한 = 날것의 속도"

커널 모드에서는 거치는 단계(Layer)가 거의 없고, 하드웨어에 직접 명령을 내릴 수 있는 권한이 있기 때문이다.

  • 추상화를 제한함: "친절한 설명이나 방어막"을 다 걷어내고, 기계와 직접 소통하는 방식이다.
  • 빠르게 실행: 중간에 검사하거나 복잡하게 변환하는 과정이 생략되니 처리 속도가 압도적으로 빠르다.
  • 비유: 숙련된 정비사가 보닛을 열고 엔진 부품을 직접 손으로 조절하는 것과 같다. 군더더기 없이 빠르지만, 실수하면 차가 폭발할 수 있다.

・사용자 모드: "안전하고 편리한 추상화 = 느리지만 안정적"

우리가 쓰는 일반 앱(브라우저, 게임 등)이 작동하는 구역이다.

  • 상대적으로 느림: 하드웨어를 직접 건드리지 못하게 커널이 감시하고, 여러 보안 검사를 거친다. 또한, 복잡한 기계어 대신 사람이 이해하기 쉬운 API(추상화)를 거치느라 단계가 추가된다.
  • 더 안전함: 프로그램이 오류를 일으켜도 OS 전체가 뻗지 않는다. 커널이 "너 선 넘었어"라며 해당 앱만 강제 종료시키기 때문이다.
  • 비유: 운전자가 **운전석 핸들과 페달(추상화)**만 조작하는 것과 같다. 직접 엔진을 만지는 것보다 반응은 미세하게 느릴 수 있지만, 훨씬 안전하고 편리하다.

1-2.CPU 아키텍쳐

리눅스가 인기 있는 이유 중 하나는 리눅스가 다양한 CPU 아키텍쳐에서 실행된다는 점 때문이다.

제너릭 코드와 드라이버는 물론이고, 리눅스 커널은 아키텍처별 코드도 포함하고 있다. 이러한 코드 분리 덕분에 리눅스를 새 하드웨어에 이식하고 빠르게 사용하는 것이 가능하다.

1-2-1.x86아키텍쳐

인텔에서 개발했으며 나중에 AMD에도 라이선스된 명령어 세트 제품군이다. 커널 내에서 x64는 인텔 64비트 프로세서를 나타내고 x86은인텔 32비트를 뜻하며, amd64는 AMD 64비트 프로세서를 말한다.

x86 CPU제품군은 데스크톱과 노트북에서 주로 볼 수 있지만 서버에서도 널리 사용된다.

특히 퍼블릭 클라우드의 기반으로 강력하고 널리 사용 가능한 아키텍처지만 에너지 효율은 높지 않다.

부분적으로 비순차적 실행에 대한 의존도가 높기 때문에 멜트다운 같은 보안 문제와 관련해 최근에 많은 관심을 받았다.


・명령어 세트 (Instruction Set)

CPU가 이해할 수 있는 단어장이라고 생각하면 됩니다.

  • 컴퓨터는 0과 1만 알지만, "더해라", "저장해라" 같은 명령어를 약속된 번호로 정해두었습니다.
  • x86은 아주 오래전 인텔이 만든 8086 프로세서에서 유래된 이 단어장(명령어 세트)의 '가문 이름'입니다.

・32비트(x86) vs 64비트(x64 / amd64)

비트(bit)는 CPU가 한 번에 처리할 수 있는 데이터의 양입니다.

  • x86 (32비트): 한 번에 32개씩 처리합니다. 인식할 수 있는 메모리(RAM)가 최대 4GB로 제한되어 있어 요즘 서버에서는 거의 퇴출당했습니다.
  • x64 / amd64 (64비트): 한 번에 64개씩 처리합니다. 엄청나게 큰 메모리를 쓸 수 있는 현대의 표준입니다.

・왜 이름이 여러 개일까? (인텔 vs AMD)

  • x86: 인텔이 만든 32비트 표준.
  • amd64: 64비트 시대로 넘어올 때, 인텔보다 AMD가 먼저 표준을 성공시켰습니다. 그래서 리눅스 커널이나 오픈소스 진영에서는 64비트 표준 기술을 존중의 의미로 amd64라고 부릅니다.
  • x64 / Intel 64: 나중에 인텔이 AMD의 방식을 받아들여서 만든 64비트 기술입니다. 사실상 amd64와 똑같습니다.
용어 실제 의미 비고
x86 32비트 인텔 방식 옛날 방식 (느림, 메모리 제한)
amd64 64비트 표준 (AMD가 개발) 현대 서버의 표준. 리눅스에서 주로 씀
x64 / Intel 64 64비트 표준 (인텔 방식) amd64와 기술적으로 거의 동일

 

・비순차적 실행(out-of-order execution)

CPU가 명령어를 들어온 순서대로 처리하지 않고, '준비된 것부터 먼저' 처리해서 노는 시간을 줄이는 기법이다.

인텔이나 AMD의 x86 CPU는 이 기술을 매우 공격적으로 사용한다. 덕분에 우리는 코드를 대충 짜도 CPU가 알아서 성능을 쥐어짜 준다.

  • 장점: CPU의 놀고 있는 유닛들을 최대한 활용해 처리 속도가 빨라집니다.
  • 단점: 회로가 복잡해지고 전력을 더 많이 소비합니다.

・멜트다운

CPU가 '미리 실행'해본 데이터가 흔적(캐시)으로 남는 것을 악용한 사례이다.

사용자 영역에서 운영체제의 시스템 메모리에 접근할 수 있다.


1-2-2.ARM아키텍쳐

ARM은 RISC(Reduced Instruction Set Computing) 아키텍쳐 제품군이다. RISC는 일반적으로 더 빠르게 실행할 수 있는 작은 명령어 세트와 많은 일반 CPU레지스터로 구성된다.

최소한의 전력 소비에 중점을 뒀기 때문에 아이폰 같은 수많은 휴대용 디바이스에서 사용되고 있다. x86칩보다 빠르고 저렴하며 발열량이 적기 때문에 데이터 센터에서 점점 더 많이 발견되고 있다. 또한 x86보다 간단하지만 스펙터같은 취약점에 영향을 받지 않는다.

1-2-3.RISC-V아키텍쳐

새롭게 떠오르고 있다. UC버클리에서 개발한 개방형 RISC표준이다. 비교적 새롭고 아직 널리 사용되지 않는 CPU 제품군이다.


1-3.Kernel구성요소

리눅스 커널은 모놀리식 커널이지만, 코드베이스에는 특정 역할을 식별하고 부여할 수 있는 기능 영역이 나뉘어 있다.

 


놀리식 커널 (Monolithic Kernel) 이란?

**"통째로 하나로 된 덩어리"**라는 뜻입니다. 앞서 배운 커널의 핵심 기능들(프로세스 관리, 메모리 관리, 파일 시스템, 네트워크 등)이 하나의 커다란 프로그램 안에 다 들어있고, 이들이 같은 메모리 공간을 공유하며 실행됩니다.

  • 장점: 내부 통신 비용이 거의 없어 성능이 압도적으로 빠릅니다.
  • 단점: 코드 한 곳에서 치명적인 오류가 나면 커널 전체(OS 전체)가 뻗어버릴 수 있습니다.

"기능 영역이 나뉘어 있다"의 의미

덩어리는 하나지만, 그 안의 소스 코드는 역할별로 엄격하게 구분되어 있다는 뜻입니다. 이를 **모듈화(Modularity)**라고 부릅니다.

마치 대기업 한 건물(모놀리식) 안에 **인사팀, 개발팀, 회계팀(기능 영역)**이 층별로 나뉘어 각자의 일을 전문적으로 수행하는 것과 같습니다.

대표적인 기능 영역 (Functional Areas)

리눅스 커널 코드베이스는 보통 다음과 같은 영역으로 깔끔하게 분리되어 관리됩니다.

  1. 프로세스 관리: 실행 파일을 기반으로 프로세스를 시작함
  2. 메모리 관리: 프로세스에 메모리를 할당하거나 파일을 메모리에 매핑함
  3. 파일시스템: 파일 관리를 제공하고, 파일 생성과 삭제를 지원함
  4. 네트워킹: 네트워크 인터페이스 관리나 네트워크 스택 제공함
  5. 캐릭터 디바이스와 디바이스 드라이버 관리

※이러한 기능 구성요소는 상호 의존성이 있을 때가 많아서 커널의 개발자 모토'커널은 사용자 영역을 손상시키지 않는다.'를 실제로 확실히 지키면서 작업하기는 정말 어렵다.

 

왜 이렇게 설계했나?

전체를 하나로 합쳐서 성능은 챙기되(모놀리식), 개발과 유지보수를 할 때는 "네트워크 담당자는 네트워크 코드만 봐라"라고 할 수 있게 기능적으로 나눈 것입니다. 또한, 필요할 때 특정 기능(드라이버 등)을 껐다 켰다 할 수 있는 LKM(Linux Kernel Module) 기술을 통해 유연성도 챙겼습니다.


1-3-1.프로세스 관리

커널에는 프로세스 관리와 관련된 부분이 여럿 있다. 그중 일부는 인터럽트 같은 CPU 아키텍쳐 관련사항을 처리하고, 다른 부분은 프로그램 실행과 스케쥴링에 중점을 둔다.


・인터럽트의 정의

인터럽트는 "방해하다", "가로막다"라는 뜻 그대로, CPU에 비상벨을 울리는 것입니다. 하드웨어나 소프트웨어가 CPU에게 "지금 당장 처리해야 할 급한 일이 생겼어!"라고 보고하는 메커니즘입니다.

・왜 필요한가? (예시)

만약 인터럽트가 없다면, CPU는 키보드가 눌렸는지, 마우스가 움직였는지 확인하기 위해 하루 종일 하드웨어를 감시해야 합니다. (이를 **폴링(Polling)**이라고 하는데, 엄청난 자원 낭비입니다.)

인터럽트가 있으면 CPU는 자기 할 일(계산 등)을 하다가, 키보드가 눌리는 순간에만 "잠깐!" 하고 멈춰서 그 값을 처리하고 다시 돌아옵니다.


1-3-1-1.세션

하나 이상의 프로세스 그룹을 포함, 선택적으로 tty가 연결된 상위 수준의 사용자 대면 유닛을 나타냄. 세션ID라는 번호를 통해 세션을 식별한다.


1. 프로세스 그룹 (Process Group)의 정의

프로세스 그룹은 특정한 목적을 위해 연관된 프로세스들을 하나로 묶은 **'팀'**입니다. 커널은 이 팀을 관리하기 위해 팀장 격인 프로세스의 번호를 따서 **PGID (Process Group ID)**를 부여합니다.

2. 왜 그룹으로 묶을까? (핵심 이유)

**"한 번에 신호를 보내기 위해서"**입니다.

가장 흔한 예시는 **파이프(|)**를 사용한 명령어입니다.

  • 예: cat large_log.txt | grep "ERROR" | awk '{print $1}'
  • 위 명령을 내리면 3개의 프로세스(cat, grep, awk)가 동시에 생성됩니다.
  • 커널은 이 3개를 하나의 프로세스 그룹으로 묶습니다.
  • 만약 로그가 너무 길어서 중간에 중단하고 싶어 Ctrl + C를 누르면, 커널은 이 그룹 전체에 종료 신호를 보냅니다. 그룹이 없다면 일일이 프로세스 번호를 찾아 3번이나 종료시켜야 했을 겁니다.

3. 세션 (Session): "사용자의 한 번의 로그인 활동"

세션은 프로세스 그룹보다 더 큰 '회사' 같은 개념입니다.

  • 사용자가 터미널을 열고 로그인해서 로그아웃할 때까지 발생하는 모든 활동(여러 개의 프로세스 그룹)을 하나로 묶은 것입니다.
  • 커널은 이를 **SID (Session ID)**라는 번호로 관리합니다.

4. "선택적으로 tty가 연결된 상위 수준의 유닛"

이 문구 때문에 많이 헷갈리셨을 텐데, 용어를 쪼개면 쉽습니다.

  • tty (Teletypewriter): 쉽게 말해 **'터미널 화면'**입니다.
  • 선택적으로 연결됨: * 우리가 보통 터미널을 열고 작업할 때는 세션에 터미널(tty)이 연결되어 있습니다.
    • 하지만 서버에서 배경(Background)으로 돌아가는 서비스(데몬)들은 터미널 화면이 필요 없죠? 그래서 터미널 연결 없이 세션만 존재하기도 합니다. 그래서 **'선택적'**이라고 표현하는 것입니다.
  • 상위 수준의 사용자 대면 유닛: 사용자가 "로그인해서 나갈 때까지의 전체 덩어리"를 뜻하는 가장 큰 단위라는 말입니다.

1-3-1-2.프로세스 그룹

하나 이상의 프로세스가 포함돼 있으며 한 세션에는 포어그라운드 프로세스 그룹이 둘 이상일 수 없다. 프로세스 그룹ID라는 숫자를 통해 프로세스 그룹을 식별한다.

 


1. 포어그라운드(Foreground) 프로세스 그룹이란?

터미널(tty)과 직접 연결되어 사용자의 입력을 실시간으로 받아먹고 출력물을 화면에 보여주는 '주인공' 그룹입니다.

  • 독점 구조: 터미널은 한 번에 하나의 프로세스 그룹하고만 소통할 수 있습니다. 그래서 문장에서 **"둘 이상일 수 없다"**고 말하는 것입니다. (주인공은 오직 한 명뿐이어야 헷갈리지 않으니까요.)

2. 백그라운드(Background) 프로세스 그룹

주인공 뒤에서 묵묵히 자기 일을 하는 '조연' 그룹들입니다.

  • 세션 안에는 여러 개의 백그라운드 그룹이 존재할 수 있습니다.
  • 이들은 터미널에서 키보드 입력을 직접 받을 수 없습니다. 만약 백그라운드 그룹이 입력을 받으려 하면 커널이 강제로 정지시키기도 합니다.

3. 실무 비유: "마이크를 잡은 사람"

하나의 세션을 **'회의실'**이라고 가정해 봅시다.

  • 세션: 회의실 전체.
  • 프로세스 그룹: 각 부서 팀원들.
  • 포어그라운드 그룹: 현재 마이크를 잡고 말하는 팀. 회의실에 팀은 많을 수 있지만, 마이크는 하나뿐이라 동시에 두 팀이 마이크를 잡고 떠들 수는 없습니다.
  • 백그라운드 그룹: 마이크 없이 구석에서 자기들끼리 자료 정리 중인 팀들.

4. 왜 "둘 이상일 수 없다"고 할까?

만약 포어그라운드 그룹이 두 개라면, 여러분이 키보드로 A를 쳤을 때 어느 프로그램에 전달해야 할까요?

  • A 프로그램? B 프로그램? 이런 혼란을 막기 위해 커널은 단 하나의 프로세스 그룹에만 터미널 제어권을 부여합니다.

1-3-1-3.프로세스

여러 리소스(주소 공간,하나 이상의 스레드, 소켓 등)를 그룹으로 추상화한 것이며, 커널은 /proc/self를 통해 현재 프로세스를 사용자에게 노출한다. 커널은 프로세스 ID라는 숫자를 통해 프로세스를 식별한다.

1-3-1-4.스레드

커널에 의해 프로세스로 구현된 유닛이다. 즉 스레드를 나타내는 전용 데이터 구조는 없다. 오히려 스레드는 특정 리소스를 다른 프로세스와 공유하는 프로세스다. 커널은 TID와 TGID를 통해 스레드를 식별하며, 공유된 TGID값은 멀티스레드 프로세를 의미한다.

1-3-1-5.태스크

커널에는 sched.h에 정의된 task_struct라는 데이터 구조가 있으며, 이는 프로세스와 스레드 구현의 기반을 형성한다. 이 데이터 구조는 스케줄링 관련 정보,식별자,시그널 처리기, 성능이나 보안과 관련된 기타 정보를 수집한다.


1. sched.h란? (헤더 파일)

리눅스 커널은 C언어로 만들어져 있습니다. C언어에서 .h로 끝나는 파일은 '헤더 파일'이라고 부르는데, 쉽게 말해 "우리 시스템에서 쓸 중요한 설계도나 규칙을 미리 정의해둔 문서"입니다.

  • 왜 sched인가?: 'Scheduling'의 약자입니다. 커널이 "어떤 일꾼(태스크)에게 CPU를 줄까?"를 결정하는 게 스케줄링인데, 그와 관련된 가장 근본적인 규칙들이 이 파일에 적혀 있습니다.

2. task_struct란? (만능 신분증)

커널이 관리하는 모든 일꾼(프로세스, 스레드)은 이 task_struct라는 똑같은 양식의 신분증을 가슴에 달고 있습니다.

커널은 "얘가 프로세스인가? 스레드인가?"를 고민하지 않습니다. 그냥 이 신분증에 적힌 내용을 보고 일을 시킵니다.


1-3-1-6.메모리 관리

 프로세스 수준의 페이지 테이블을 통해 여러 가상 페이지가 동일한 물리적 페이지를 가리킬 수 있다. 어떤 의미에서 메모리 관리의 핵심인데, 즉 기존 공간을 최적으로 사용하면서 각 프로세스에 그들의 페이지가 실제로 RAM에 존재한다는 환상을 효과적으로 일으키는 방법니다.


1. 왜 '프로세스 수준'인가요?

리눅스 시스템에 유닛 1(카카오톡), 유닛 2(유튜브)가 떠 있다고 칩시다.

  • 유닛 1의 입장: "내 가상 주소 100번지에 중요한 사진 데이터를 저장할 거야."
  • 유닛 2의 입장: "내 가상 주소 100번지에 동영상 데이터를 저장할 거야."

보시다시피 두 유닛 모두 똑같이 '100번지'라는 주소를 쓰고 싶어 합니다. 만약 페이지 테이블이 서버에 딱 하나뿐이라면 주소가 충돌해서 난리가 나겠죠? 그래서 커널은 각 프로세스마다 자기만의 전용 페이지 테이블을 만들어 줍니다.

  • 유닛 1의 페이지 테이블: "내 100번지는 실제 RAM의 500번 프레임이야."
  • 유닛 2의 페이지 테이블: "내 100번지는 실제 RAM의 800번 프레임이야."

이처럼 각 유닛이 독립적으로(프로세스 수준에서) 장부를 관리하기 때문에 서로 주소가 겹쳐도 실제 RAM에서는 안 싸우고 평화롭게 지낼 수 있는 겁니다.


1-3-1-7.네트워킹

커널의 중요한 기능 중 하나는 네트워킹 기능이다. 웹을 검색하거나 원격 시스템에 데이터를 복사하려면 네트워크에 의존해야 한다. 리눅스의 네트워크 스택은 계층화된 아키텍처를 따른다.


1. 계층화 아키텍처의 비유: "국제 택배"

미국에 있는 친구에게 선물을 보낸다고 생각해보세요.

  • 내 역할 (응용 계층): 선물을 고르고 박스에 넣은 뒤 주소를 적습니다. (HTTP, FTP 등)
  • 우체국 역할 (전송 계층): 이 물건을 배로 보낼지, 비행기로 보낼지 결정하고 송장을 붙입니다. (TCP, UDP)
  • 물류 허브 역할 (네트워크 계층): 주소를 보고 어느 나라, 어느 도시로 보낼지 경로를 정합니다. (IP)
  • 운송 수단 역할 (링크 계층): 실제 비행기나 배에 실어서 물리적으로 이동시킵니다. (Ethernet, Wi-Fi)

  • 소켓 (Socket): 프로세스가 커널에게 데이터를 전달하는 접점(창구)입니다.
  • TCP/UDP 계층: 데이터가 잘 도착했는지 확인하거나(TCP), 그냥 빠르게 보내기만 할지(UDP) 결정합니다.
  • IP 계층: 패킷에 도착지 IP 주소를 붙이고 어디로 보낼지 길을 찾습니다(Routing).

1-3-1-8.파일시스템

 

'Linux > モダーンリナックス' 카테고리의 다른 글

アクセス制御  (0) 2026.05.17
シェルおよびスクリプト  (0) 2026.05.16
1.Linux  (1) 2026.04.25

日本語