1. 시스템 프로그래밍의 정의
시스템 프로그래밍은 운영체제의 커널 및 핵심 시스템 라이브러리를 직접 사용하면서 하위 레벨에서 동작하는 기술을 의미합니다.
특히 리눅스 시스템 프로그래밍은 리눅스 커널이 제공하는 기능을 이용하여 프로그램을 개발하는 과정으로, 커널과 직접 상호작용하는 프로그래밍 방식입니다.
시스템 프로그래밍은 하드웨어와 소프트웨어의 경계에서 작업하는 핵심 기술이며, 제한된 리소스 환경에서 효율적인 코드를 작성하는 데 필수적인 지식입니다.
2. 커널
커널은 운영체제의 핵심 요소로, 응용 프로그램의 동작 환경을 제공하고 컴퓨터의 모든 자원을 관리합니다.
부팅 시 메모리에 적재되어 다양한 기능을 제공합니다:
- 프로세스 관리: 생성 및 소멸, 프로세스간 통신, CPU 스케줄링, 동기화
- 메모리 관리: 가상 메모리 관리기법, 메모리 하드웨어의 효율적 관리
- 파일 시스템: 가상 파일 시스템을 통한 다양한 파일 시스템 지원
- 디바이스 드라이버: 입출력 요청 검증, 입출력 작업 스케줄링
- 네트워크: 통신 프로토콜 구현(TCP/UDP, IP 등)
커널 모듈을 통해 필요한 기능을 동적으로 적재하거나 삭제할 수 있어 개발 시간 단축과 자원의 효율적 이용이 가능합니다.
※ 커널 모드와 사용자 모드
시스템 프로그래밍을 이해하기 위해서는 커널 모드와 사용자 모드의 차이를 아는 것이 중요합니다:
- 커널 모드(kernel mode): 하드웨어나 시스템을 요청할 때 사용되는 모드로, 모든 자원(디바이스, 메모리, 프로세서 등)에 접근 및 명령이 가능합니다.
- 사용자 모드(user mode): 일반적인 사용자 프로세스가 처리되는 동작 모드로, 접근할 수 있는 영역이 제한되어 있습니다.
이러한 모드 구분이 시스템 안정성과 보안에 중요한 역할을 합니다.
3. POSIX
POSIX(Portable Operating System Interface)는 서로 다른 운영체제 간의 호환성을 보장하기 위한 IEEE 표준입니다. 이 표준은 다양한 운영체제에서 일관된 API를 제공하여 애플리케이션의 이식성을 높이는 것을 목표로 합니다.
POSIX 표준은 다음과 같은 영역을 포함합니다:
- 프로세스 관리
- 파일 및 디렉토리 조작
- 파이프와 FIFO
- 터미널 제어
- 스레드 및 동기화
- 네트워크 통신
4. 시스템 콜(System Call)
시스템 콜은 운영체제에 리소스나 서비스를 요청하기 위해 사용자 영역에서 커널 내부로 들어가는 함수 호출 인터페이스입니다.
사용자 프로그램이 커널의 보호된 자원에 접근할 수 있게 해주는 통로 역할을 합니다.
시스템 콜의 주요 특징:
- 사용자 영역에서 커널 영역으로 직접 들어가는 것은 불가능하기 때문, 애플리케이션이 시스템 콜을 실행하려 한다는 '시그널'을 커널로 보내 커널이 허용한 코드를 실행합니다.
- 리눅스 시스템 프로그래밍의 주춧돌 중 하나로, C 라이브러리와 C 컴파일러와 함께 핵심 요소를 구성합니다.
시스템 콜은 하드웨어 자원에 효율적으로 접근하기 위한 필수 요소입니다. 특히 제한된 리소스 환경에서는 시스템 콜의 오버헤드를 최소화하고 적절히 활용하는 것이 성능 최적화의 핵심입니다.
5. 시그널(Signal)
시그널은 소프트웨어 인터럽트로, 프로세스에 어떤 이벤트가 발생했음을 알리는 짧은 메시지를 비동기적으로 전달하는 메커니즘입니다. 시그널은 다음과 같은 특징을 가집니다:
- 예외상황과 인터럽트를 커널에서 추상화한 개념
- 프로세스 간 통신의 한 방법
- 서로 다른 시그널들은 정수 아이디로 구분
- 비동기적으로 발생하며, 유닉스 운영체제가 프로세스에 전달
시그널의 발생 원인
- 0으로 나누기나 자식 프로세스 종료 같은 시스템 이벤트 감지 시
- 다른 프로세스로부터 kill 시스템 콜 요청 수신 시
- 사용자 입력(예: Ctrl+C는 SIGINT, Ctrl+Z는 SIGSTP)
시그널 처리 방법
프로세스가 시그널을 받으면 다음 세 가지 반응 중 하나를 선택할 수 있습니다:
- 무시: 시그널을 무시하고 아무 동작도 하지 않음
- 종료: 대상 프로세스를 종료
- 핸들러 실행: 시그널 핸들러라고 부르는 사용자 정의 함수를 실행하여 시그널을 처리
시그널은 하드웨어 이벤트 처리와 프로세스 간 통신에 중요한 역할을 합니다. 특히 제한된 리소스 환경에서 효율적인 이벤트 처리 메커니즘으로 활용됩니다.
6. 파이프(Pipe)
파이프는 두 프로세스 간에 통신할 수 있도록 해주는 특수 파일입니다. 파이프는 다음과 같은 특징을 가집니다:
- 단방향 통신: 기본적으로 한 방향으로만 데이터가 흐름
- FIFO(First In First Out) 방식으로 데이터 전송
- 파이프는 익명 파이프와 이름 있는 파이프(named pipe 또는 FIFO)로 구분
익명 파이프(Anonymous Pipe)
- 부모-자식 프로세스 간에만 통신 가능
- 프로세스 생성 시 파일 디스크립터를 상속받아 사용
- 파이프 생성은 pipe() 또는 popen() 시스템 콜 사용
파이프 통신 과정
- pipe() 함수를 호출하여 파이프로 사용할 파일 디스크립터 2개 생성
- fork() 함수로 자식 프로세스 생성 (파이프도 자식 프로세스로 복사)
- 통신 방향 결정 (읽기 또는 쓰기)
이름 있는 파이프(Named Pipe)
- 부모-자식 관계가 아닌 독립적인 프로세스 간 통신 가능
- 파일 시스템에 특수 파일로 존재
- mkfifo() 또는 mknod() 함수로 생성
파이프 사용 시 주의사항
- 파이프의 쓰기 부분이 닫혀 있다면, 읽기 시도 시 0이나 EOF 반환
- 파이프의 읽기 부분이 닫혀 있다면, 쓰기 시도 시 SIGPIPE 시그널 발생
파이프는 프로세스 간 데이터 전송에 효율적인 메커니즘을 제공하며, 특히 명령어 실행 결과를 다른 프로세스에 전달하는 등의 작업에 유용합니다.
'임베디드SW 기초' 카테고리의 다른 글
| 리눅스 네트워크프로그래밍(1) - 워치독 타이머(WDT) (0) | 2025.03.07 |
|---|---|
| 시스템 프로그래밍(4) - 시그널 관련 시스템 콜 (0) | 2025.02.26 |
| 시스템 프로그래밍(3) - 프로세스 관련 시스템 콜 (0) | 2025.02.26 |
| 시스템 프로그래밍(2) - 파일 및 디렉토리 관련 시스템 콜 (0) | 2025.02.26 |
| 리눅스 기초 (0) | 2025.02.12 |