아마추어들은 도구에 집착하고, 전문가들은 숙련에 집착한다

얼마 전, GeekNews를 통해 읽은 글(GN⁺: 아마추어들은 도구에 집착하고, 전문가들은 숙련에 집착한다)이 저에게 큰 울림을 줬습니다. 이를 계기로 언젠가부터 다양한 오픈소스를 경험해본다는 핑계로 여러 도구의 설정과 사용에 익숙해지는 것에 집착해왔던 자신을 발견하게 됐습니다. 기술과 마인드를 점검하고 다시 쌓아가야겠다는 생각이 들어 실천의 일환으로 최근 구매한 “모던 리눅스 교과서”부터 읽어나가기로 결심했습니다. 본 글에서는 워밍업으로 용어도 다시 정리할 겸 리눅스 커널의 개요에 대해서 정리했습니다. 책의 흐름을 따라가며 실무와 엮어서 정리하는 시리즈 글이 될 수도 있겠네요.(매끄럽게 진행된다면..?)

리눅스 아키텍처 개요

  • 하드웨어 계층 : CPU와 메인 메모리부터 디스크 드라이브, 네트워크 인터페이스는 물론 키보드나 모니터 같은 주변 디바이스까지 모두를 일컫습니다.
    • 하드웨어와 커널 사이의 인터페이스는 그룹화된(프로세스, 메모리, 네트워킹, 파일시스템, 디바이스) 개별 인터페이스 모음으로 구성됩니다.
  • 커널 계층 : 커널과 사용자 영역 사이의 init 시스템과 시스템 서비스(네트워킹 등)와 같은 구성요소
    • 시스템 콜(system call) : 커널과 사용자 영역 사이의 인터페이스(리눅스 운영체제 패키지의 일부)
  • 사용자 영역(user land) 계층 : 셸(shell)과 같은 운영체제 구성요소, ps나 ssh 같은 유틸리티, 데스크톱 같은 GUI를 비롯해 대부분의 앱이 실행되는 곳입니다.

커널 구성요소

프로세스 관리

커널에는 인터럽트 같은 CPU 아키텍처 관련 사항 처리와 프로그램 실행 및 스케줄링에 관련된 부분이 있습니다.

  • 세션 : 하나 이상의 프로세스 그룹을 포함하고 선택적으로 tty가 연결된 상위 수준의 사용자 대면 유닛을 나타냄. 커널은 세션 ID(SID)라는 번호를 통해 세션을 식별.
  • 프로세스 그룹 : 하나 이상의 프로세스가 포함돼 있으며 한 세션에는 포어그라운드(foreground) 프로세스 그룹이 둘 이상일 수 없음. 커널은 프로세스 그룹 ID(PGID)라는 숫자를 통해 식별.
  • 프로세스 : 여러 리소스(주소 공간, 스레드, 소켓 등)를 그룹으로 추상화한 것이며, 커널은 /proc/self를 통해 현재 프로세스를 사용자에게 노출함. 커널은 프로세스 ID(PID)라는 숫자를 통해 식별.
  • 스레드 : 커널에 의해 프로세스로 구현된 유닛. 커널은 스레드 ID(TID)와 스레드 그룹 ID(TGID)를 통해 스레드를 식별하며, 공유된 TGID 값은 멀티스레드 프로세스를 의미.
  • 태스크 : 커널에는 sched.h에 정의된 task_struct라는 데이터 구조가 있으며, 이는 프로세스와 스레드 구현의 기반을 형성함. 간단히 말해, 모든 유닛은 태스크에서 파생되며 고정됨. 커널 외부에 그대로 노출되는 일은 없음.

메모리 관리

가상 메모리는 시스템이 물리적으로 갖고 있는 것보다 더 많은 메모리를 갖고 있는 것처럼 보이게 합니다.

모든 프로세스는 많은 (가상) 메모리를 얻음. 물리 메모리와 가상 메모르는 모두 페이지라고 부르는 고정 길이의 청크로 나뉩니다.

프로세스의 페이지 테이블은 가상 페이지를 주 메모리(RAM)의 물리적 페이지에 매핑합니다. 페이지 테이블을 통해 여러 가상 페이지가 동일한 물리적 페이지를 가리킬 수 있습니다. (기존 공간을 최적으로 사용하면서 각 프로세스에 그들의 페이지가 실제로 RAM에 존재한다는 환상을 효과적으로 일으키는 방법)

/proc/meminfo 인터페이스는 메모리 관련 정보를 파악할 때 매우 유용한 도구입니다.

네트워킹

  • 소켓 : 추상화 커뮤니케이션을 위해 필요
  • TCP/UDP : 연결형 통신과 비연결형 통신용 프로토콜
  • 인터넷 프로토콜(IP) : 기기의 주소 지정을 위해 필요

위 작업은 커널이 처리하는 모든 것이고, HTTP나 SSH 같은 애플리케이션 계층 프로토콜은 주로 사용자 영역에 구현됩니다.

파일시스템

리눅스는 파일시스템을 사용해 HDD, SSD, 플래시 메모리 같은 저장 디바이스의 파일과 디렉터리를 구성합니다. ext4, btrfs, NTFS 같은 다양한 유형의 파일시스템이 있으며 동일한 파일시스템의 인스턴스도 여러개 사용할 수 있습니다.

디바이스 드라이버

드라이버는 커널에서 실행되는 코드입니다. 그 역할은 키보드, 마우스, 하드 디스크 드라이브 같은 실제 하드웨어 디바이스나 /dev/pts/ 아래의 의사 터미널 같은 의사 디바이스(pseudo-device)를 관리하는 것입니다.

드라이버는 커널에 정적으로 빌드될 수도 있고, 필요할 때 동적으로 로드될 수 있도록 커널 모듈로 빌드될 수도 있습니다.

시스템 콜

커널이 노출하는 서비스 인터페이스와 해당 사용자 영역의 엔티티 호출은 시스템 호출의 모음이라 하며, 시스템 콜이라 부릅니다. 리눅스에는 수백 개의 시스템 콜이 있지만 우리 프로그램은 일반적으로 시스템 콜을 직접 호출하지 않고 C 표준 라이브러리를 통해 호출합니다.

특정 명령을 실행할 때 어떤 시스템 콜이 관련돼 있는지 궁금하면 strace를 사용하면 됩니다. strace는 사용자 영역과 커널 사이에 이벤트 이벤트 라이브 스트림을 가로채는 방식으로 어떤 시스템 호출이 어떤 순서로 어떤 인수를 사용해 호출되었는지 정확하게 파악하기 위해 유용합니다.

참고 자료

모던 리눅스 교과서(책만, 마이클 하우센블라스 지음, 송지연 옮김, 2023년)

GN⁺: 아마추어들은 도구에 집착하고, 전문가들은 숙련에 집착한다

Amateurs obsess over tools, pros over mastery

About the author

배움을 멈추지 않고, 언젠가 넓고 깊은 지식을 갖게 되기를 꿈꾸고 있습니다! 🚀
또한 누군가에게 선한 영향력을 미칠 수 있는 사람이 되기를 소망합니다 🌟

Loading script...