ARM_core 기반 리눅스 BSP 개발/Raspberry_PI Kernel build

[Raspberry_PI]_QEMU

juniha 2025. 6. 23. 19:44

 

QEMU_(Quick_Emulator)

  • 하드웨어(프로세서, 메모리 등)를 가상화하거나 Emulation하는 오픈 소스 소프트웨어이다.
  • 무료, 공개 소스,  x86, ARM, PowerPC, RISC-V
  • Emulator : 상이한 프로세러를 동작을 모사하여 작동하는 시스템
  • 다른 아키텍처의 CPU까지 소프트웨어적으로 모사 가능

 

바이너리 설치 프로그램
https://qemu.weilnetz.de/w64/

 

QEMU for Windows – Installers (64 bit)

QEMU Binaries for Windows (64 bit) Here you get QEMU related binaries for 64 bit versions of Microsoft Windows. Name Last modified Size Description Parent Directory - 2011/ 2016-04-15 10:48 - experimental QEMU for Windows 2012/ 2016-04-15 10:48 - experimen

qemu.weilnetz.de

소스 코드 및 make

qemu-w64-setup-20250422.exe


virsion 10.0.0

 

 

수작업으로  PATH 설정

C:\Program Files\qemu

 

설치 버전 확인

qemu-system-arm --version

// arm 32 bit
qemu-system arm 

// arm 64 bit
qemu-system-aarch64 

// 지원되는 프로세서의 목록 확인
-cpu help

// 지원되는 보드의 목록 확인
- machine help

 

raspberrypi.com  에서  pi os 64 lite 다운로드

WSL Ubuntu로 접속

 

압축 풀기

unxz 2025-05-13-raspios-bookworm-arm64-lite.img.xz

 

파티션 확인

fdisk -l 2025-05-13-raspios-bookworm-arm64-lite.img

 

img Mount

mount된 drive

mkdir pi_img
fdisk -l 2025-05-13-raspios-bookworm-arm64-lite.img pi_img

mount된 드라이브에서 커널 복사, 디바이스트리(dtb)

cp kernel8.img bcm2710-rpi-3-b.dtb ..
cd ..

mount 해제

sudo umount pi_img

 

PowerShell에서 작업

qemu-img resize -f raw 2025-05-13raspios-bookwowm-arm64.img 4G

 

실행

qemu-system-aarch64 -machine raspi3b -cpu cortex-a53 -smp 4 -m 1G -kernel kernel8.img -dtb bcm2710-rpi-3-b.dtb -sd 2025-05-13-raspios-bookworm-arm64-lite.img -append "root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4" -usbdevice keyboard -usbdevice mouse -device usb-net,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2022-:22rootfstype=ext4" -usbdevice keyboard -usbdevice mouse -device usb-net,netdev=net0 -netdev user,id-net,hostfwd=tcp::2022-:22

 

 

sudo raspi-config로 ssh활성

powershell에서 ssh pi@127.0.0.1 -p 2022

 

WSL Ubuntu 로 사용하기

WSL ip config

 

로그인 후 사용 시작

 

새로운 폴더 생성

cd c_project
mkdir led_kernel
cd led_kernel

 

Raspberry Pi 리눅스 커널에 맞는 헤더 파일

 sudo apt-get install -y build-essential raspberrypi-kernel-headers git

 

코드 작성

  • nano 사용시 -l 을 포함하면 코드 번호 ON

led_blink.c 코드

#include <linux/module.h>      // 커널 모듈 관련 API
#include <linux/gpio.h>        // GPIO 제어 관련 API (현재 코드에서는 GPIO는 직접 제어하지 않음)
#include <linux/delay.h>       // msleep 등 지연 함수
#include <linux/kthread.h>     // 커널 스레드 생성/제어 API
#include <linux/sched.h>       // 스케줄링 관련 API (스레드 상태 확인 등)

// 커널 스레드를 위한 task_struct 포인터
static struct task_struct *blink_thread;

// 스레드에서 주기적으로 실행되는 함수
// 매 3초마다 "HELLO Kernel" 메시지를 커널 로그에 출력
static int blink_function(void *data) {
    while (!kthread_should_stop()) {         // 스레드 종료 요청이 들어올 때까지 반복
        printk(KERN_INFO "HELLO Kernel\n");  // 커널 로그에 메시지 출력
        msleep(3000);                        // 3초 동안 스레드 sleep
    }
    return 0;                                // 스레드 종료 시 0 반환
}

// 모듈 로드 시 호출되는 초기화 함수
static int __init led_blink_init(void) {
    int ret;

    printk(KERN_INFO "LED Blink Module Init\n");    // 모듈 초기화 로그

    // blink_function을 실행하는 커널 스레드 생성
    blink_thread = kthread_run(blink_function, NULL, "blink_thread");

    // 스레드 생성 실패 시 에러 처리
    if (IS_ERR(blink_thread)) {
        printk(KERN_ERR "Failed to create thread\n");
        return PTR_ERR(blink_thread);
    }

    return 0;   // 초기화 성공
}

// 모듈 제거 시 호출되는 정리 함수
static void __exit led_blink_exit(void) {
    printk(KERN_INFO "LED Blink Module Exit\n");    // 모듈 제거 로그

    // 스레드가 실행 중이면 스레드 종료 요청
    if (blink_thread)
        kthread_stop(blink_thread);
}

// 모듈 초기화, 제거 함수 지정
module_init(led_blink_init);
module_exit(led_blink_exit);

// 모듈 메타 정보
MODULE_LICENSE("GPL");                  // 라이선스 (GPL 필수, 상업적 사용 가능)
MODULE_AUTHOR("iot");                   // 작성자 정보
MODULE_DESCRIPTION("Blink LED on GPIO 17");  // 모듈 설명 (실제로는 GPIO 17 제어 코드 없음)

Makefile 코드 설정

// led_blink.c 파일을 컴파일하여 led_blink.ko 모듈을 만든다는 의미
obj-m += led_blink.o

// 현재 커널의 빌드 디렉토리 경로 지정
KDIR := /lib/modules/$(shell uname -r)/build

// 현재 작업 디렉토리 (모듈 소스 파일이 있는 디렉토리)
PWD := $(shell pwd)

// 'make' 실행 시 호출되는 기본 빌드 규칙
all:
	// 커널 빌드 시스템을 호출하여 현재 디렉토리(PWD)에 있는 모듈을 빌드
	$(MAKE) -C $(KDIR) M=$(PWD) modules

// 'make clean' 시 호출되는 규칙 (빌드 파일들 정리)
clean:
	// 커널 빌드 시스템을 호출하여 생성된 모듈 파일, 중간 파일 삭제
	$(MAKE) -C $(KDIR) M=$(PWD) clean

 

실행

sudo insmod led_blink.ko
// led_blink.ko 커널 모듈을 커널에 삽입 (로드)
// 커널 공간에 모듈 코드를 올리고 init 함수 실행

dmesg | tail
// 최근 커널 로그의 마지막 10줄 출력
// 모듈 로드 시 printk로 출력된 초기화 메시지나 상태 확인

sudo rmmod led_blink.ko
// led_blink.ko 커널 모듈을 커널에서 제거 (언로드)
// 모듈의 exit 함수가 호출되고 리소스 정리

dmesg | tail
// 최근 커널 로그의 마지막 10줄 출력
// 모듈 제거 시 출력된 메시지나 상태 확인

 

실행 확인