Linux kernel
리눅스 커널에 대해서 정리합니다.
kernel이란
커널(kernel)이란 운영체제에서 가장 중요한 프로그램 중 하나이며, 하드웨어라는 자원을 관리하는 관리자이다. 즉, 어떤 프로그램이 작동할 수 있도록 CPU, 메모리, 디스크와 같은 물리적 장치들을 배분하는 것이 커널이다. 리눅스 강의에서 들었던 좋은 예시를 가져왔다. 아래 그림을 보자

위 그림은 커널의 역할을 도서관의 사서와 비교한 것이다. 컴퓨터에서 어떤 프로그램을 시작하려고 하면 특정한 양의 하드웨어 재료들이 필요하다. 이 재료들을 요구한만큼 찾아서 빌려주고 또 돌려받아서 관리하는 것이 커널이다. 마치 학생이 과제를 하기 위해 사서에게 과제에 필요한 책이나 영상, 신문들을 빌려가는 것과 같다. 또한 사서는 단순히 빌려주기만 하는 것이 아니라 자료들의 상태를 관리하고 빌려주기로 한 기간이 지나면 돌려받기도 한다. 이런 일들도 컴퓨터에서 커널이 동일하게 담당한다.
kernel의 역할
커널은 크게 4가지의 역할을 가진다.
- 메모리 관리: 메모리 사용량과 잔여량 등을 체크하고, 건강에 문제 없는지 체크한다.
- 프로세스 관리: CPU의 건강을 체크하고, 각 프로세스의 진행상황들을 관리한다.
- 장치 드라이버: 하드웨어와 프로세스를 연결한다.
- 시스템 호출 및 보안: 프로그램이 요구하는 커널의 재료들을 사용할 수 있도록 한다. (print, read, open, write 등)
kernel version
커널의 버전을 확인하고 싶다면 아래의 코드를 입력하자.
1 |
|
위 명령어를 입력하면 "Linux Kernel Version 4.15.0"와 같은 단어가 보일 것이다. 첫번째 숫자인 4가 커널 버전이다. 만약 커널의 소스코드를 보고 싶다면 해당 링크에서 찾아볼 수 있다.
kernel space & user space
컴퓨터 시스템은 크게 2가지로 구분된다. 바로 커널 스페이스와 유저 스페이스이다. 각각의 스페이스에 들어갈 수 있는 구성은 다음과 같다.
- kernel space: kernel code, kernel extention, device driver
- user space: C, java, python로 만들어진 어플리케이션이나 프로그램
위 예시에서 알 수 있듯이 커널 스페이스는 하드웨어와 직접적으로 접근 가능하며, 하드웨어 자원들을 관리 및 통제한다. 그렇기 때문에 만약 프로그램에서 커널 스페이스에 접근할 수 있다면 디스크에 있는 정보를 훔쳐가거나 할 수 있다. 따라서 보안 상의 문제를 방지하기 위해 일반적인 프로그램들은 커널 스페이스에 직접적으로 접근할 수 없다. 만약 하드웨어에 있는 데이터가 필요하다면 무조건 커널 스페이스에 요청해야 한다. 해당 과정을 세부적으로 살펴보면 다음과 같다.

프로그램은 데이터를 가져오기 위해서 시스템 콜을 통해 커널 스페이스에 데이터를 요청하고 커널 스페이스 내부에 있는 디바이스 드라이버가 직접 하드웨어에 접근하여 데이터를 가져온다.
하드웨어와의 관계
커널은 컴퓨터의 하드웨어와 직접적으로 소통한다. 그 말은 리눅스 터미널에서 하드웨어의 상태를 확인할 수 있다는 의미도 포함한다. 지금부터 해당 명령어들을 확인해보자.
dmesg
명령어 dmesg
는 커널의 로그를 출력한다. 커널의 로그는 컴퓨터를 처음 켠 순간부터 연결 장치들의 부팅까지 모든 정보를 포함하기 때문에, 해당 로그를 통해서 하드웨어 연결의 문제들을 진단할 수 있다. 하지만 터미널에 dmesg
만 입력하면 모든 커널로그들이 출력되기에 오류를 찾기는 쉽지 않다. 따라서 여러 옵션들을 추가하여 필요한 특정 커널 로그들만 출력할 수 있다. 사용할 수 있는 옵션들은 다음과 같다.
1 |
|
dmesg --level
위의 수많은 옵션 중에서 오류를 나타내는 커널 로그만 확인하고 싶다면 무엇을 사용해야 할까? 정답은 -l
, --level
이다. (여기서 -
는 문자가 하나일 때는 1개를 사용하고 문자가 여러개 이어질 때는 --
를 사용한다) --level
은 뒤에 추가 값을 받아서 해당 옵션에 속하는 커널 로그만 출력한다. 추가 옵션 값들은 다음과 같다.
1 |
|
위에서 대략 파악했을 수 있지만 로그들은 몇 가지의 종류로 분류된다. 보통 오류를 파악하기 위해서는 err
, crit
들을 출력하여 확인한다.
lspci
lspci
는 pci의 리스트를 출력한다. pci(Peripheral Component Interconnect)는 컴퓨터 내부에서 주변 장치들을 연결하는 연결선(local bus)라고 볼 수 있다. 따라서 해당 명령어를 입력하면 장비 리스트를 볼 수 있어서 각 하드웨어의 설정 정보를 확인할 수 있다.
아래의 예시는 vmware 가상 머신의 pci 리스트 일부이다.
1 |
|
lsblk
lsblk
는 블럭들의 구조를 보여준다. 보통 스카시(SCSI)로 연결된 하드 디스크 장치를 sd
라고 표현하고 갯수에 따라 뒤에 a
,b
알파벳이 붙는다. 즉, 스카시(SCSI)로 연결된 하드 디스크 장치 2개가 연결되어 있다면 리스트에는 sda
, sdb
이렇게 나타날 것이다. 또한 해당 하드 디스크를 파티셔닝하여 블럭 단위로 사용하기 때문에 각 블럭들은 하드 디스크 이름에 숫자가 붙어서 나타난다. 예시로 본다면 하드디스크 sda
를 파티셔닝한 블럭들은 sda1
, sda2
의 이름으로 출력된다. 아래의 예시를 확인해보자.
1 |
|
위의 예시는 물리적인 하드디스크는 sda
1개이고, 이를 블럭 2개로 파티셔닝하였다. 블럭 sda1
은 헤당 서버 부트 시스템만 들어가 있고, sda2
에 나머지 스토리지 여분이 전부 할당되어 있다. 또 sda2
는 내부에서 root
와 swap
으로 나눠졌다. swap
은 리눅스에서 메모리가 부족한 경우, 메모리처럼 사용하기 위한 여분이다. swap
에 대한 자세한 정보는 다음에 살펴볼 것이다. 위에서 MAJ:MIN
을 확인할 수 있는데, MAJ
는 디스크 넘버이고 MIN
은 파티셔닝 넘버이다.
lscpu
lscpu
는 해당 서버의 CPU 정보를 출력한다. 아래 예시에서 중요한 몇 가지만 살펴보자.
1 |
|
먼저 CPU op-mode
은 연산할 수 있는 비트 갯수를 나타내며 32-bit, 64-bit 두 가지 종류가 있다. 32-bit는 연산 비트 수가 \(2^{32}\)인 것을 의미하고 대략 4GB까지 처리할 수 있으며, 64-bit는 연산 비트 수가 \(2^{64}\)인 것을 의미하고 대략 18EB(엑사바이트)까지 처리할 수 있다. 64-bit 기반의 전자기기는 32-bit 기반으로 만들어진 어플리케이션도 작동시킬 수 있지만, 그 반대는 안된다. 다음으로 Socket
, Thread(s) per core
, Core(s) per socket
이다. 이를 이해하기 위해서는 실제 CPU가 어떻게 생겼는지를 알아야 한다. 아래의 그림을 보자

보통 CPU는 소켓 안에 코어가 들어가 있으며, 또 코어는 내부에 쓰레드로 나눠진다. CPU는 이 모든 것들을 통칭한다. 결론적으로 해당 서버의 CPU 갯수는 Socket
x Thread(s) per core
x Core(s) per socket
이다. 위의 예시에서 총 CPU 갯수를 확인하면 8 x 1 x 1
임을 알 수 있다.
lsmem
lsmem
은 메모리 사용량을 보여준다. 아래의 예시를 확인해보자.
1 |
|
해당 정보는 물리적인 메모리 장치의 블럭들을 사용하고 있는지의 여부를 보여준다. 위 예시는 리스트의 일부만을 가져온 것이며, 실제로는 훨씬 더 길다. 해당 결과는 사람이 보기에는 어렵다. 사람도 보기 좋은 형태로 메모리 남은 양을 확인해보자.
lsmem --summary
바로 옵션 --summary
를 붙여주는 것이다. 해당 옵션을 붙여주면 출력되는 결과는 다음과 같다.
1 |
|
위 예시를 보면 메모리 블럭의 단위는 128 MiB(메비바이트)이며, 현재 16 GiB(기비바이트)의 양을 사용하고 있는 것이다. 즉, 128개의 메모리 블럭을 사용중이라고 볼 수 있다.
NOTE lsmem
과 free
의 차이점은 무엇인가?
lsmem
은 메모리 블럭을 단위로 책정하여 사용중인 총량을 확인할 수 있으며, /sys/devices/system/memory
에 위치한 정보를 읽어온다. 이와 달리 free
는 실제 시스템에서 사용할 수 있는 메모리의 량을 보여주며, /proc/meminfo
에서 정보를 읽어온다.
1 |
|