Skip to content

태그: Kernel

CPU Load Average
kernel
리눅스 커널에서는 CPU Load을 평균으로 산출하여 스케쥴링 알고리즘과 CPU 로드 밸런싱등에 사용한다. 여기서 산출하는 CPU Load 평균은 해당 CPU 실행큐에 대해서 전역적(global)으로 걸리는 부하 평균이다. 이동평균(Moving Average) 리눅스 커널에서는 CPU 부하 평균(Load Average)을 “이동평균” 방식으로 산출한다. 이동평균(Moving Average)은 선택한 범위(날짜 혹은 시간)안에서 발생한 수치들의 평균이다. 예를들어 정리하면 다음과 같다. 1일 이동평균은 1일동안 발생한 수치들의 평균. 5일 이동평균은 5일동안 발생한 수치들의 평균. 15일 이동평균은 15일동안 발생한 수치들의 평균. 1분 이동평균은 1분동안 발생한 수치들의 평균. 5분 이동평균은 5분동안
디버깅
kernel
커널 디버깅에는 세 가지 요소가 필요하다. 버그가 처음 등장한 커널 버전을 파악할 수 있는가? 버그를 재현할 수 있는가? 커널 코드에 관한 지식을 갖추고 있는가? 버그를 명확하게 정의하고 안정적으로 재현할 수 있다면 성공적인 디버깅에 절반 이상 달성한 것이다. ​ 출력을 이용한 디버깅 printk()와 웁스(oops) 커널 출력 함수인 printk()는 C 라이브러리의 printf() 함수와 거의 동일하다. 주요 차이점은 로그수준(Loglevel)을 지정할 수 있다는 점이다. 가장 낮은 수준인 KERN_DEBUG 부터 가장 높은 수준인 KERN_EMERG 까지 7단계로 설정할 수 있다. printk()의 장점은 커널의 어느 곳에서도 언제든지 호출할 수 있다는 점이다. 인터럽트 컨텍스트, 프
메모리 관리와 캐시
kernel
1. 페이지 (Page) &x26; 구역 (Zone) 프로세서가 메모리에 접근할 때 가장 작은 단위는 byte 또는 word지만, MMU와 커널은 메모리 관리를 페이지 단위로 처리한다. 페이지 크기는 아키텍처 별로 다르며 보통 32-bit 시스템에선 4KB, 64-bit 시스템에선 8KB다. 커널은 하나의 페이지를 여러 구역(zone)으로 나눠 관리한다. (&x3C;linux/mmzone.h>에 정의) ZONE_DMA: DMA를 수행할 수 있는 메모리 구역 ZONE_DMA32: 32-bit 장치들만 DMA를 수행할 수 있는 메모리 구역 ZONE_NORMAL: 통상적인 페이지가 할당되는 메모리 구역 ZONE_HIGHMEM: 커널 주소 공간에 포함되지 않는 ‘상위 메모리’ 구역 메모리 구역의 실제 사용
모듈과 장치 관리
kernel
1. 정의 모듈: 커널 관련 하위 함수, 데이터, 바이너리 이미지를 포함해 동적으로 불러 올 수 있는 커널 객체를 의미한다. 장치: 리눅스 커널은 장치를 블록 장치, 캐릭터 장치, 네트워크 장치 3가지로 분류한다. 모든 장치 드라이버가 물리장치를 표현하는 것은 아니며 커널 난수 생성기, 메모리 장치처럼 가상 장치도 표현한다. 2. 모듈 사용하기 모듈 만들기 모듈 개발은 새로운 프로그램을 짜는 것과 비슷하다. 각 모듈은 소스파일 내에 자신의 시작위치(module_init())와 종료위치(module_exit())가 있다. 아래는 ‘hello, world’를 출력하는 간단한 모듈의 코드이다. include &x3C;linux/init.h>include &x3C;linux/module.h>inclu
시스템 콜과 인터럽트
kernel
커널은 시스템콜의 일관성, 유연성, 이식성​ 3가지를 확보하는 것을 최우선 사항으로 생각하고 있다. 따라서 커널은 POSIX 표준에 따라 표준 C 라이브러리 형태로 시스템콜을 제공한다. 리눅스 커널에서 시스템콜은 네 가지 역할을 수행한다. 사용자 공간에 HW 인터페이스를 추상화된 형태로 제공한다. 시스템에 보안성 및 안정성을 제공한다. 인터럽트(및 트랩)와 함께 커널에 접근할 수 있는 유일한 수단이다. 사용자 공간과 기타 공간을 분리해 프로세스별 가상환경(가상메모리, 멀티태스킹 등)을 제공한다. 리눅스의 시스템콜은 다른 OS보다 상대적으로 갯수가 적고 수행속도가 빠르다. 리눅스는 시스템콜 핸들러 호출 흐름이 간단하기 때문이다. 리눅스는 context switching 속도가 빠르기 때문이
유저모드와 커널모드
kernel
커널은 중요한 자원을 관리하기 때문에, 사용자가 그 자원에 쉽게 접근하지 못하도록 모드를 2가지로 나눈다. 커널모드 운영체제 내부에서 실제로 하드웨어를 제어할 수 있다. 모든 자원(드라이버, 메모리, CPU 등)에 접근, 명령을 할 수 있다. 커널 모드에서 실행되는 모든 코드는 단일 가상 주소 공간을 공유한다. 따라서 커널 모드 드라이버는 다른 드라이버 및 운영 체제 자체와 격리되지 않는다. 유저모드 접근할 수 있는 영역이 제한적이어서 프로그램의 자원에 함부로 침범하지 못하는 모드이다. 여기서 코드를 작성하고, 프로세스를 실행하는 등의 행동을 할 수 있다. 사용자 모드에서 모든 프로세스는 별도의 가상 주소 공간을 할당받는다. Mode bit CPU 내부에 Mode bit 을 두어 kern
이식성
kernel
이식성이란, 특정 시스템 아키텍처의 코드가 (가능하다면) 얼마나 쉽게 다른 아키텍처로 이동할 수 있는지를 의미한다. 이 장에서는 핵심 커널 코드나 디바이스 드라이버를 개발할 때 이식성 있는 코드를 작성하는 방법에 대해서 알아본다. 리눅스는 인터페이스와 핵심 코드는 아키텍처 독립적인 C로 작성됐고, 성능이 중요한 커널 기능은 각 아키텍처에 특화된 어셈블리로 작성해 최적화시켰다. 좋은 예로 스케줄러가 있다. 스케줄러 기능의 대부분은 &x3C;kernel/sched.c> 파일에 아키텍처 독립적으로 구현돼있다. 하지만, 스케줄링의 세부 과정인 context switching과 memory management를 책임지는 switch_to(), switch_mm() 함수는 아키텍처별로 따로따로 구현돼있다.​
커널 모듈
kernel
모듈은 요청 시 커널에 로드 및 언로드할 수 있는 코드 조각이다. 시스템을 재부팅할 필요 없이 커널의 기능을 확장한다. 예를 들어, 한 가지 유형의 모듈은 커널이 시스템에 연결된 하드웨어에 액세스할 수 있도록 하는 디바이스 드라이버이다. 모듈이 없으면 모놀리식 커널을 빌드하고 커널 이미지에 직접 새로운 기능을 추가해야 하고, 새로운 기능을 원할 때마다 커널을 다시 빌드 및 재부팅해야 한다는 단점이 있다. 따라서 모듈을 이용하면 커널 컴파일 시간을 단축할 수 있다. 로드 가능한 커널 모듈(LKM, Loadable Kernel Module)은 런타임에 Linux 커널에 코드를 추가하거나 제거하는 메커니즘이다. 모듈 없이 Linux 커널에 코드를 추가하려는 경우 가장 기본적인 방법은 커널 소스 트
타이머
kernel
커널은 &x3C;asm/param.h> 헤더파일에 시스템 타이머의 진동수를 HZ라는 값에 저장한다. 일반적으로 HZ 값은 100 또는 1000으로 설정돼있고, 커널 2.5 버전부터 ​기본값이 1000으로 상향됐다. 장점: 타이머 인터럽트의 해상도와 정확도가 향상돼 더 정확한 프로세스 선점이 가능해졌다. 단점: 타이머 인터럽트 처리에 더 많은 시간을 소모하고, 전력 소모가 늘어난다. 실험결과 시스템 타이머를 1,000Hz로 변경해도 성능을 크게 해치지 않는다는 결론이 났다. &x3C;linux/jiffies.h>에 jiffies 라는 전역변수에는 시스템 시작 이후 발생한 틱 횟수가 저장된다. 타이머 인터럽트가 초당 HZ회 발생하므로 jiffies는 1초에 HZ만큼 증가한다. 따라서 시스템
파일시스템
kernel
VFS(Virtual FileSystem)는 시스템콜이 파일시스템이나 물리적 매체 종류에 상관없이 공통적으로 동작할 수 있도록 해주는 인터페이스다. 파일시스템 추상화 계층은 모든 파일시스템이 지원하는 기본 인터페이스와 자료구조를 선언한 것이다. VFS는 슈퍼블록(superblock), 아이노드(inode), 덴트리(dentry), 파일(file) 4가지 객체로 구성돼있다. 슈퍼블록: 파일시스템을 기술하는 정보(+ file_system_type, vfsmount 구조체)를 저장한다. 아이노드: 파일이나 디렉토리를 관리하는 데 필요한 모든 정보를 저장한다. 덴트리: 디렉토리 경로명 속 각 항목의 유효성 정보 등을 저장한다. 파일: 메모리 상에 로드 된 열려있는 파일에 대한 정보를 저장한다. 한 파일
프로세스 관리
kernel
1. 프로세스와 구조체 프로세스는 프로그램 코드를 실행하면서 생기는 모든 결과물이다. 일반적인 의미: 실행 중인 프로그램 포괄적인 의미: 사용 중인 파일, 대기 중인 시그널, 커널 내부 데이터, 프로세서 상태, 메모리 주소 공간, 실행 중인 하나 이상의 스레드 정보 등 프로세스는 fork() 호출 시 생성되고, 기능을 수행한 뒤, exit()를 호출해 종료된다. 부모 프로세스는 wait() 호출로 자식 프로세스 종료 상태를 확인할 수 있다. 스레드는 프로세스 내부에서 동작하는 객체이고, 개별적인 PC, Stack, Register(context)를 가지고 있다. 리눅스 커널은 프로세스와 스레드를 구분하지 않는다. 리눅스 커널에 대한 접근은 오직 시스템 콜과 ISR로만 가능하다. 커널
프로세스 스케줄러
kernel
1. 정의 및 역사 스케줄러는 어떤 프로세스를 어떤 순서로 얼마나 오랫동안 실행할 것인지 정책에 따라 결정한다. 스케줄러는 시스템의 최대 사용률을 끌어내 사용자에게 여러 프로세스가 동시에 실행되고 있는 듯한 느낌을 제공해야 한다. 스케줄러는 비선점형 스케줄러와 선점형 스케줄러로 나뉜다. 선점형 스케줄러는 일정한 timeslice 동안 전적으로 프로세서 자원을 사용할 수 있고, 시간이 지나면 다음으로 우선순위가 높은 프로세스에 선점된다. 1991년 리눅스 첫 버전부터 2.4 버전까지는 단순한 스케줄러를 제공했다. 2.5 버전부터 대대적인 스케줄러 개선작업을 통해 O(1) 스케줄러라는 이름의 새로운 스케줄러를 구현했다. Timeslice 동적 계산이 O(1)에 수행되며 프로세서마다 별도의 wait qu