Zephyr v3.7.0 · 호스트 실행과 검증 경계

native_sim: Linux에서 돌린 Zephyr는 무엇을 증명하나?

호스트에서 빨리 재현되는 버그와 실물에서만 드러나는 버그는 다릅니다. native_sim은 Zephyr 앱과 커널을 함께 실행해 기능을 살피는 보드 대상이지만, 특정 MCU의 명령어·메모리맵·타이밍을 재현하는 장치는 아닙니다.

본문 기준: Zephyr 3.7.0 LTS3 · 이후 유지보수 패치는 별도입니다.

기준은 Zephyr v3.7.0 문서와 같은 릴리스의 보드 동작이다. 아래 명령과 그림은 재현 절차 및 구조 설명이며 Zephyr 바이너리를 직접 빌드·실행한 기록은 아니다. 특히 native_sim의 POSIX 아키텍처 포트는 앱에 POSIX API를 제공하는 POSIX OS abstraction과 다른 층이다.

1. 호스트 프로세스 안에도 Zephyr 커널이 있다

native_sim 대상으로 빌드하면 애플리케이션, 선택한 Zephyr 커널·라이브러리, POSIX 아키텍처와 가상 SoC 계층, native simulator 실행기·HW 모델이 하나의 Linux 실행 파일을 이룬다. 앱을 Linux API만 쓰도록 다시 작성하는 방식이 아니다. Zephyr 스레드는 호스트 pthread에 대응되지만, 포트는 동시에 하나의 소프트웨어 스레드만 실행하도록 제어해 단일 가상 CPU를 나타낸다. 호스트 스택을 쓰므로 실물 대상의 스택 사용과 보호 기능까지 같지는 않다.

그림 1. zephyr.exe 안에 포개지는 네 역할

↔ 각 상자는 같은 호스트 실행 파일로 이어집니다. 좁은 화면에서는 좌우로 이동하세요.

① 앱 + Zephyr 커널원래 Zephyr API와 선택한 서브시스템을 빌드호스트 앱으로 API를 치환한 단위 테스트가 아님
② POSIX arch + 가상 SoCZephyr 스레드를 pthread로 대응시키고 실행권을 전환POSIX API 호환 shim과 구별
③ native simulator가상 CPU의 수면·깨움, 인터럽트·타이머 및 선택한 HW 모델을 진행특정 칩의 레지스터·명령어 모델은 아님
④ Linux 실행 파일build/zephyr/zephyr.exe를 보통 프로세스처럼 실행·디버깅GDB·Valgrind 등 호스트 도구 이용

근거: native_sim 개요, POSIX arch와 POSIX API shim의 구별, 스레드·HW 모델 실행 구조.

2. 빌드 대상과 디버깅 도구를 따로 선택한다

3.7.0 문서의 최소 예시는 west build -b native_sim samples/hello_world다. 기본 native_sim은 32비트 ILP32 ABI를 쓰므로 64비트 Linux 호스트에는 32비트 라이브러리와 multilib 지원이 필요하다. 그 환경을 갖추기 어렵다면 native_sim/native/64 대상이 64비트 LP64 ABI로 빌드한다. 포인터 크기에 따라 드러나는 결함이 다르므로 64비트 대상의 통과를 32비트 대상 통과로 바꿔 읽지 않는다.

west build -b native_sim samples/hello_world ./build/zephyr/zephyr.exe --help ./build/zephyr/zephyr.exe # 64비트 ABI가 필요할 때는 보드 대상을 native_sim/native/64로 선택

생성된 프로그램은 디버그 정보가 있는 호스트 실행 파일이어서 GDB로 중단점을 걸거나 Valgrind로 살필 수 있다. CONFIG_NO_OPTIMIZATIONS는 소스 단계 디버깅을 쉽게 하고, CONFIG_ASAN·CONFIG_UBSAN은 해당 호스트 런타임이 준비된 경우 검사 옵션이다. 앱 main()이 돌아왔다고 프로세스가 자동 종료되지는 않는다. 일반 앱은 커널 idle 상태가 지속될 수 있으며, Ztest는 테스트가 끝나면 종료되는 별도 경우다.

표 1. 같은 앱, 다른 검증 조건
선택확인하는 성질빠지기 쉬운 경계
native_sim32비트 ILP32의 포인터·long 크기호스트의 32비트 개발·실행 라이브러리 필요
native_sim/native/6464비트 LP64의 호스트 실행 경로32비트 크기 의존 결함을 가릴 수 있음
GDB·Valgrind·sanitizer호스트 바이너리의 제어 흐름·메모리 오류 관찰실물 SoC 타이밍·레지스터 동작 검증은 아님

근거: 3.7.0 빌드·실행·디버깅, 32/64비트 ABI, ASan과 UBSan 선택.

3. 호스트 시간이 흐른다고 가상 시간도 흐르지는 않는다

일반 설정에서 native_sim의 가상 시간은 호스트 벽시계와 분리되고, 모델이 다음 이벤트까지 시간을 진행한다. Zephyr 코드가 CPU에서 실행되는 동안에는 가상 시간이 흐르지 않는다고 가정한다. CPU가 잠들면 HW 모델이 다음 이벤트를 처리하고, 인터럽트가 가상 CPU를 깨우는 순서다. 일반적인 재실행은 결정적이지만, 호스트 주변장치나 외부 입출력을 사용하면 같은 입력·같은 결과라는 가정이 깨질 수 있다.

그림 2. 실행 중 0, 잠든 동안 전진하는 가상 시간

↔ 이 흐름은 실행 모델이며 실제 밀리초를 측정한 그래프가 아닙니다.

① SW 실행Zephyr 스레드가 호스트 CPU에서 명령 실행. 이 동안 가상 시간은 진행하지 않음.
② CPU 수면실행 가능한 일이 없어 가상 CPU가 잠듦. HW 모델의 이벤트를 처리할 차례.
③ 이벤트 전진다음 타이머·HW 이벤트 시점까지 가상 시간을 옮겨 모델 함수를 호출.
④ IRQ와 재개모델이 인터럽트를 올리면 SW 스레드를 다시 실행. SW ↔ 모델 교대 반복.

그래서 다른 스레드나 인터럽트가 바꿀 값을 while (condition) { }으로 계속 기다리면 가상 CPU를 내주지 못해 멈출 수 있다. k_busy_wait()에는 이 포트의 특수 타이머 경로가 있지만, 임의의 빈 반복문이 같은 동작을 한다는 뜻은 아니다. --rt는 시뮬레이션을 호스트 실시간에 맞추도록 지연시키는 선택일 뿐, MCU의 명령별 실행 시간이나 하드웨어 경합을 재현하지 않는다.

근거: 가상 시간과 --rt, 빈 대기 반복문의 한계, SW/HW 실행권 교대.

4. 주변장치는 구현 또는 호스트 연결의 범위에서만 보인다

native_sim은 특정 보드의 모든 레지스터를 흉내 내지 않는다. 대신 선택한 드라이버·에뮬레이터가 UART, 네트워크, 플래시 등의 API를 제공한다. 호스트 파일이나 네트워크 장치에 연결되는 백엔드를 쓰면 앱 경로의 기능은 시험할 수 있지만, 실제 칩의 DMA·전기적 신호·메모리맵을 통과했다는 증거는 아니다. 드라이버에 선택 기능이 빠져 있을 수도 있다.

표 2. 모델을 지나도 남는 실물 검증
3.7.0 제공 예시호스트에서 시험 가능한 경로이 결과만으로 증명 못 하는 것
UART pseudo-terminalZephyr UART와 Linux stdin/stdout 또는 PTY의 문자 교환실제 UART 컨트롤러의 모든 interrupt·async 모드
Flash simulatorRAM 또는 호스트 파일에 저장되는 플래시 API 사용 흐름실제 flash erase 시간·수명·전원 차단 상태
TAP Ethernet / offloaded socket가상 인터페이스 또는 Linux socket을 이용한 통신offloaded socket 경로에서 Zephyr L2 계층 검증

호스트 주변장치를 이용한 결과는 입력과 외부 상태에 의존한다. 특히 offloaded socket 백엔드는 Linux 소켓을 쓰므로 Zephyr L2 네트워크 경로를 지나지 않는다. 드라이버별 지원 범위와 선택한 C 라이브러리의 호환성도 별도로 확인해야 한다.

근거: UART·Flash·네트워크 모델, backend별 libc 호환성, POSIX arch의 미지원 기능.

5. native_sim, QEMU, 실물, Twister는 서로 다른 질문에 답한다

native_sim은 보드 대상이다. QEMU용 보드는 더 가까운 타깃 ISA와 메모리 배치를 에뮬레이션하는 선택이다. 실물 보드는 전원·인터럽트·장치 연결의 실제 동작을 확인한다. Twister는 이 중 어느 플랫폼에서 어떤 테스트를 빌드·실행할지 정리하고 결과를 수집하는 러너이므로 native_sim의 대체 보드가 아니다. 어떤 Twister 행이 build_only였는지도 실행 검증을 해석할 때 분리해야 한다.

그림 3. 질문에 따라 달라지는 검증 경로

각 카드의 “남는 질문”을 함께 읽으세요. 좁은 화면에서는 카드가 세로로 이어집니다.

native_sim · 기능을 빨리 반복앱 + Zephyr 커널을 호스트 CPU에서 실행GDB·sanitizer로 제어 흐름과 메모리 오류 관찰남는 질문타깃 레지스터·사용자 모드·HW/SW 타이밍은 맞는가?
QEMU · 타깃 구성을 가까이선택한 QEMU 보드의 ISA·메모리 배치를 에뮬레이션제공된 주변장치 모델 범위에서 펌웨어 동작 확인남는 질문실제 실리콘과 주변장치의 모든 시간·전기적 특성도 맞는가?
실물 보드 · 실제 연결 확인드라이버와 물리 장치의 부팅·인터럽트·입출력 관찰보드별 전원·주변 환경에서 재현 시험남는 질문재현·계측 조건을 통제해 원인을 좁혔는가?
표 3. 도구 이름과 결과 이름을 섞지 않기
이름역할결과 해석
native_sim호스트에서 실행되는 Zephyr 보드 대상앱·커널 기능과 선택한 모델의 경로
QEMU 보드타깃 ISA·메모리 배치를 포함한 에뮬레이션 대상그 QEMU 보드가 제공하는 모델 범위
실물 보드물리 하드웨어에서 실행측정한 보드·설정·조건 범위
Twister플랫폼별 테스트 선택·빌드·실행·보고각 행이 실제 실행됐는지 먼저 확인

근거: 3.7.0 POSIX arch와 QEMU 비교, native_sim의 HW 비특정 범위, Twister의 플랫폼 실행·build only.

6. 통과와 실패를 다음 실험으로 바꾸는 점검표

표 4. 결과에 붙여 둘 조건
보인 현상먼저 확인할 것다음 단계
빈 반복문에서 정지가상 CPU가 수면할 기회 없이 인터럽트를 기다리는가동기화 원시 함수 또는 포트의 대기 API로 바꾸고 재현
64비트 대상만 통과포인터·long 크기에 의존하는 코드가 있는가ILP32 대상 및 실제 타깃 ABI에서 다시 확인
호스트 장치 경로만 통과드라이버가 Linux 파일·socket·PTY에 기대는가QEMU 모델 또는 실물 드라이버에서 별도 확인
Twister PASS 또는 build only해당 테스트가 실제로 실행됐는가플랫폼·harness·로그와 제외 이유를 기록

이 글의 그림은 3.7.0 문서의 제어 모델을 설명한다. 벤치마크 수치나 특정 장치에서의 실측 결과로 읽지 않는다.

7. 고정 버전 근거와 이어 읽기

기준은 Zephyr 3.7.0 native_sim 보드 문서와 그 v3.7.0 소스 원문, 같은 버전 POSIX 아키텍처 문서, Twister 문서다. 보드 사용법·제약·시뮬레이션 시간을 고정 버전에서 읽었으며, 이후 릴리스의 장치 목록이나 명령을 이 버전의 사실로 소급하지 않았다.