Linux ioctl, 디바이스를 제어하는 전용 채널
·
Dev/Linux
`read()`/`write()`로는 데이터를 주고받을 수 있지만, "이 센서의 샘플링 레이트를 변경해줘" 같은 제어 명령은 어떻게 전달할까요?그 답이 `ioctl`입니다.1. ioctl이 왜 필요한가?Linux에서 디바이스와 통신하는 기본 방법은 `read()`와 `write()`입니다.그런데 이 두 가지로 표현하기 어려운 명령들이 있습니다."샘플링 레이트를 1000Hz로 설정해줘""현재 온도를 읽어줘""버퍼를 초기화해줘""카운터 값을 99로 교환하고 기존 값을 돌려줘"이런 디바이스 고유의 제어 명령을 전달하는 시스템 콜이 `ioctl`(Input/Output Control)입니다./* 유저스페이스에서 호출하는 방식 */int ioctl(int fd, unsigned long request, void ..
Linux/proc 파일시스템, 커널과 대화하기
·
Dev/Linux
`cat /proc/cpuinfo`,`cat /proc/meminfo` - 써본 적 있으신가요?이 파일들은 디스크에 없습니다. 커널이 즉석에서 만들어냅니다. 오늘은 그 원리를 직접 구현해 봅니다. 1. /proc 파일시스템이란?터미널에서 이런 명령을 써본 적 있을 겁니다.$ cat /proc/cpuinfo # CPU 정보$ cat /proc/meminfo # 메모리 사용량$ cat /proc/uptime # 부팅 후 경과 시간 이 파일들은 실제로 디스크에 존재하지 않습니다. `/proc`은 가상 파일 시스템(virtual File System)입니다.커널이 메모리 위에 만들어 놓은 인터페이스로, `cat`으로 읽으면 커널 함수가 호출되어 데이터를 즉석에서 생성합니다. 디스크..
Linux Kernel Module Parameters
·
Dev/Linux
1. Module Parameter가 왜 필요한가요?이전 글에서 만든 Hello 모듈은 동작이 고정되어 있었습니다.인사 횟수를 바꾸거나 이름을 바꾸려면 코드를 수정하고 다시 빌드해야 했죠. 실제 드라이버에서는 이런 상황이 자주 생깁니다.GPIO 핀 번호를 하드코딩하지 않고 로드 시 지정하고 싶다.디버그 로그를 켜고 끄고 싶다디바이스 개수나 버퍼 크기를 유연하게 조정하고 싶다이럴 때 Module Parameter를 씁니다.# 파라미터 없이 로드 - 기본값 사용sudo insmode params.ko# 파라미터 지정해서 로드sudo insmode params.ko count=3 name="Hoon" debug=1코드 수정 없이 동작을 바꿀 수 있습니다.2. module_param() 기본 문법module_p..
Linux Kernel Module 개발 입문 - Hello World 부터 시작하기
·
Dev/Linux
1. 커널 모듈이란?Linux 커널은 하나의 거대한 프로그램입니다. 그런데 모든 드라이버를 커널에 정적으로 포함시키면 커널 크기가 엄청나게 커지고, 새 드라이버를 추가할 때마다 커널을 다시 컴파일해야 합니다.이 문제를 해결하는 것이 Kernel Module(커널 모듈) 입니다.커널 모듈 = 실행 중인 커널에 동적으로 추가하거나 제거할 수 있는 코드 조각USB를 꽂으면 드라이버가 자동으로 로드되고, 뽑으면 언로드되는 것이 바로 커널 모듈 덕분입니다.Linux 커널 (실행 중)┌─────────────────────────────────────┐│ Core Kernel ││ ┌──────────┐ ┌──────────┐ ││ │ Module A │ │..
[IPC] Shared Memory - 가장 빠른 프로세스 간 통신
·
Dev/System Programming
들어가며지난 글에서 FIFO (Named Pipe)를 다뤘는데, 실습하면서 한 가지 아쉬운 점이 있었습니다. 바로 속도였죠. 간단한 메시지 주고받기에는 충분했지만, 큰 데이터를 전송하려니 느렸습니다.왜 느릴까요? FIFO는 Kernel을 거쳐서 데이터를 복사하기 때문입니다.FIFO 방식:Writer → [User Space] ↓ (복사!) [Kernel Space] ↓ (또 복사!) [User Space] → Reader→ 2번 복사! 느림!"메모리를 그냥 공유하면 안 되나?" 라는 생각이 들었습니다. 그게 바로 오늘 다룰 Shared Memory (공유 메모리)입니다.Shared Memory란?개념Shared Memory는 여러 프로세스가 같은 메모리 영역을 공유하는..
FIFO (Named Pipe) : 프로세스 간 통신의 기본
·
Dev/System Programming
들어가며프로세스 간 통신(IPC)을 공부하다 보면 가장 먼저 만나는 개념이 Pipe입니다.그런데 Pipe는 부모-자식 프로세스처럼 혈연관계가 있는 프로세스들끼리만 통신할 수 있다는 제약이 있죠. 만약 완전히 독립적인 두 프로그램이 통신하려면 어떻게 해야 할까요?바로 여기서 FIFO(Named Pipe)가 등장합니다. 이 글에서 FIFO의 개념부터 실제 구현까지, 직접 코드를 작성하며 겪은 문제들과 해결 과정을 공유하겠습니다.FIFO란?FIFO = First In First OutFIFO는 "First In First Out"의 약자로, 먼저 들어간 데이터가 먼저 나오는 자료구조입니다.마치 은행 대기줄처럼 선착순으로 처리되죠. 입구 → [A][B][C][D] → 출구 ↑ ..
싱글톤 패턴(singleton pattern) - C++
·
Dev/Design Pattern
1. 개념 이해싱글톤 패턴이란?프로그램 전체에서 인스턴스가 단 하나만 존재하도록 보장하는 디자인 패턴 하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있지만, 그렇게 하지 않고 하나의 클래스를 기반으로 단 하나의 인스턴스를 만들어 이를 기반으로 로직을 만드는데 쓰이며, 하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에 인스턴스를 생성할 때 드는 비용이 줄어드는 장점이 있다. 따라서 보통 싱글톤 패턴이 적용된 객체가 필요한 경우는 그 객체가 리소스를 많이 차지하는 역할을 하는무거운 클래스일 때 적합하다. 대표적으로 보통 설정(Config) 관리자, 로그(Logger) 시스템, DB 커넥션 풀, 네트워크 소켓 매니저, 데이터 베이스 연결 모듈에 많이 사용된..
Scop 구현기 5편: 행렬과 사용 점
·
Dev/Grapics
이전 글에서는 Model 클래스에서 OBJ 파일을 파싱하고 정점 데이터를 처리하는 흐름을 살펴보았습니다.이번 글에서는 그 정점들이 실제로 화면에 어떻게 그려지는지를 결정짓는 핵심 요소, 바로 "행렬(Matrix)"에 대해 깊이 있게 분석합니다.3D 그래픽스에서 행렬은 단순한 계산 도구가 아니라, '시점', '위치', '존재'를 결정하는 철학적 도구입니다.1. 왜 행렬이 필요한가?3D 그래픽스에서 모델을 불러온다고 해서 곧바로 화면에 보이는 건 아닙니다.그 이유는 모델의 정점(Vertex)들이 여전히 '자기 내부(Local Space)'에 존재하기 때문입니다. 예를 들어, 정점이 (0, 0, 0)이라고 하면, 이는 오브젝트 기준의 원점을 의미하지 화면 기준의 원점은 아닙니다.우리는 화면(스크린)이라는 2차..
Scop 구현기 4편: Model 클래스
·
Dev/Grapics
전 편에서 Shader코드들을 분리해 클래스로 따로 만들었다이제는 기본. obj 파일을 파싱 해서 VAO와 VBO 그리고 정점들에 대한 데이터 들을 클래스 단위로 분리해 보자! Scop에서 가장 중요한 클래스가 아닐까 싶다1. 왜 Model 클래스를 도입했나?삼각형 그리기를 생각해 본다면 VAO, VBO, 위치 데이터, 셰이더 정보 등이 전부 흩어져 있다 이걸 하나로 묶지 않으면각 객체마다 VAO/VBO를 일일이 관리해야 하고draw 호출마다 셰이더 바인딩도 반복하고좌표, 색상, 메시 정보를 통합적으로 다루기 어렵다그래서 이 모든 "하나의 그릴 대상"을 감싸는 클래스를 만들게 된 것이다.2. Model 클래스는 어떤 책임을 가져야 할까?처음에는 단순히 "정점 데이터를 갖는 그릇" 정도로만 생각했다하지만 ..
Scop 구현기 3편: 셰이더 클래스를 만들기로 했다
·
Dev/Grapics
OpenGL 셰이더를 매번 glCreateShader → glCompileShader → glLinkProgram 반복하는 게너무 지저분하고 비효율적이라는 생각이 들었다.심지어 하나만 있을 땐 모르겠는데, 앞으로 이게 10개, 20개 넘어가면… 말 다했지 뭐.그래서 아예 셰이더 클래스를 하나 짜기로 했다.헤더부터 깔끔하게 작성했다.class Shader {public: Shader(const char* vsPath, const char* fsPath); ~Shader(); void Use(); GLuint GetId(); void SetBool(const std::string& name, bool value) const; void SetInt(const std::string& name, int value..