1부. 임베디드 리눅스의 요소1장. 시작__리눅스 선택하기 __리눅스를 선택하지 말아야 할 때 __참여 단체들 __프로젝트 생명주기 ____임베디드 리눅스의 4요소 __오픈소스 __라이선스 __임베디드 리눅스를 위한 하드웨어 선택하기 __이 책에서 사용하는 하드웨어 ____라즈베리 파이 4 ____비글본 블랙 ____QEMU __개발 환경 __요약 2장. 툴체인을 배우자__기술적 요구 사항 __툴체인 소개 ____툴체인의 종류 ____CPU 아키텍처 ____C 라이브러리 고르기 __툴체인 찾기 __crosstool-NG를 이용해 툴체인 빌드하기 ____crosstool-NG 설치 ____비글본 블랙용 툴체인 빌드 ____QEMU용 툴체인 빌드 __툴체인의 구조 ____크로스 컴파일러를 알아보자 ____sysroot, 라이브러리, 헤더 파일 ____툴체인 안의 다른 도구들 ____C 라이브러리의 요소를 살펴보자 __라이브러리와 링크하기: 정적 링크와 동적 링크 ____정적 라이브러리 ____공유 라이브러리 __크로스 컴파일 기술 ____단순 makefile ____Autotools ____패키지 구성 ____크로스 컴파일 관련 문제 ____CMake __요약 __추가 자료 3장. 부트로더에 대한 모든 것__기술적 요구 사항 __부트로더는 무슨 일을 하는가? __부트 순서 ____1단계: 롬 코드 ____2단계: SPL ____3단계: TPL __부트로더에서 커널로 이동 __장치 트리 소개 ____장치 트리 기초 ____reg 프로퍼티 ____레이블과 인터럽트 ____장치 트리 인클루드 파일 ____장치 트리 컴파일하기 __U-Boot ____U-Boot 빌드하기 ____U-Boot 설치하기 ____U-Boot 사용하기 ____리눅스 부팅 ____U-Boot를 새로운 보드에 이식하기 ____빌드와 테스트 ____팔콘 모드 __요약 4장. 커널 구성과 빌드__기술적 요구 사항 __커널은 무엇을 하는가? __커널 선택하기 ____커널 개발 주기 ____안정적 장기 지원 릴리스 __커널 빌드하기 ____소스 구하기 ____커널 구성 이해하기: Kconfig ____LOCALVERSION을 이용해 커널 식별하기 ____언제 커널 모듈을 사용하는가? __컴파일하기: Kbuild ____어떤 커널 이미지를 컴파일할지 알아내기 ____빌드 아티팩트 ____장치 트리 컴파일하기 ____모듈 컴파일하기 ____커널 소스 청소하기 ____라즈베리 파이 4용 64비트 커널 빌드하기 ____비글본 블랙용 커널 빌드하기 ____QEMU용 커널 빌드하기 __커널 부팅하기 ____라즈베리 파이 4 부팅하기 ____비글본 블랙 부팅하기 ____QEMU 부팅하기 ____커널 패닉 ____초기 사용자 공간 ____커널 메시지 ____커널 명령줄 __리눅스를 새 보드에 이식하기 ____새로운 장치 트리 ____보드의 compatible 프로퍼티 설정하기 __요약 __추가 자료 5장. 루트 파일시스템 만들기__기술적 요구 사항 __루트 파일시스템에는 무엇이 있어야 하는가? ____디렉터리 레이아웃 ____스테이징 디렉터리 ____POSIX 파일 접근 권한 ____스테이징 디렉터리의 파일 소유권과 권한 ____루트 파일시스템용 프로그램 ____루트 파일시스템용 라이브러리 ____장치 노드 ____proc과 sysfs 파일시스템 ____커널 모듈 __루트 파일시스템을 타깃으로 전송하기 __부트 initramfs 만들기 ____단독형 initramfs ____initramfs 부팅하기 ____QEMU로 부팅하기 ____비글본 블랙 부팅하기 ____initramfs를 커널 이미지에 넣기 ____장치 테이블을 이용해 initramfs 빌드하기 ____오래된 initrd 형식 __init 프로그램 ____데몬 프로세스 시작하기 __사용자 계정 구성하기 ____루트 파일시스템에 사용자 계정 추가하기 __장치 노드를 관리하는 더 좋은 방법 ____devtmpfs를 사용하는 예 ____mdev를 사용하는 예 ____결국 정적 장치 노드는 그렇게 나쁜 것인가? __네트워크 구성하기 ____glibc용 네트워크 요소 __장치 테이블을 이용해 파일시스템 이미지 만들기 ____비글본 블랙 부팅하기 ____NFS를 이용해 루트 파일시스템 마운트하기 ____QEMU로 테스트하기 __비글본 블랙으로 테스트하기 __파일 권한 문제 __TFTP를 이용해 커널 로드하기 __요약 __추가 자료 6장. 빌드 시스템 선택하기__기술적 요구 사항 __빌드 시스템 비교 __바이너리 배포 __Buildroot 소개 ____배경 ____안정 버전 릴리스 및 장기간 지원 버전 ____설치 ____구성 ____실행 ____실제 하드웨어에 타기팅 ____커스텀 BSP 생성 ____자신의 코드 추가 ____라이선스 준수 __Yocto 프로젝트 소개 ____배경 ____안정적인 릴리스와 지원 ____Yocto 프로젝트 설치 ____설정 ____빌드 ____QEMU 타킷 실행 ____레이어 ____local.conf를 통한 이미지 커스터마이징 ____이미지 레시피 쓰기 ____SDK생성 ____라이선스 검사 __요약 __추가 자료 7장. Yocto를 이용한 개발__기술적 요구 사항 __기존 BSP 위에서 빌드 ____기존 BSP를 빌드 ____Wi-Fi 제어 ____블루투스 제어 ____커스텀 레이어 추가 __devtool로 변경 사항 캡처 ____개발 워크플로 ____새로운 레시피 생성 ____레시피로 빌드된 소스 수정 ____레시피를 최신 버전으로 업그레이드 __나만의 배포판 빌드 ____할 때와 하지 말아야 할 때 ____새로운 배포 레이어 생성 ____배포판 환경 설정 ____배포판에 더 많은 레시피 추가 ____런터임 패키지 관리 __원격 패키지 서버 프로비저닝 __요약 __추가 자료 8장. Yocto의 내부를 살펴보자__기술적 요구 사항 __Yocto의 아키텍처와 워크플로 분석 ____메타데이터 ____빌드 태스크 ____이미지 생성 __메타데이터를 레이어로 분리 __빌드 실패에 대한 문제 해결 ____오류 격리하기 ____환경 설정 덤프 ____태스크 로그 읽기 ____더 많은 로깅 추가 ____devshell에서 명령 실행 ____의존성 그래프 작성 __BitBake 구문과 의미 이해 ____태스크 ____의존성 ____변수 ____함수 ____RDEPENDS 재확인 __요약 __추가 자료 2부. 시스템 아키텍처와 설계 결정9장. 저장소 전략 수립__기술적 요구 사항 __저장소 옵션 ____NOR 플래시 ____NAND 플래시 __부트로더에서 플래시 메모리 접근하기 ____U-Boot와 NOR 플래시 ____U-Boot와 NAND 플래시 ____U-Boot와 MMC, SD, eMMC __리눅스에서 플래시 메모리 접근 ____MTD ____MMC 블록 드라이버 __플래시 메모리를 위한 파일시스템 ____플래시 변환 레이어 __NOR와 NAND 플래시 메모리를 위한 파일시스템 ____JFFS2 ____YAFFS2 ____UBI와 UBIFS __컨트롤러가 내장된 플래시를 위한 파일시스템 ____플래시벤치 ____Discard와 TRIM ____ext4 ____F2FS ____FAT16/32 __읽기 전용 압축 파일시스템 ____SquashFS __임시 파일시스템 __읽기 전용 루트 파일시스템 만들기 __파일시스템 선택 __요약 __추가 자료 10장. 소프트웨어 업데이트__기술적 요구 사항 __업데이트는 어디에서 시작하는가? __무엇을 업데이트해야 하는가? ____부트로더 ____커널 ____루트 파일시스템 ____시스템 애플리케이션 ____장치별 데이터 ____업데이트가 필요한 컴포넌트 __소프트웨어 업데이트의 기본 ____견고한 업데이트 ____안전한 업데이트 ____업데이트 보안 __업데이트 메커니즘 유형 ____시메트릭 이미지 업데이트 ____어시메트릭 이미지 업데이트 ____원자 파일 업데이트 __OTA 업데이트 __로컬 업데이트 시 Mender 사용하기 ____Mender 클라이언트 빌드하기 __업데이트 설치하기 __OTA 업데이트 시 Mender 사용하기 __로컬 업데이트 시 balena 사용하기 ____계정 생성하기 ____애플리케이션 생성하기 ____장치 추가하기 ____CLI 설치하기 ____프로젝트 푸시하기 __요약 11장. 장치 드라이버 인터페이스__기술적 요구 사항 __장치 드라이버의 역할 __문자 장치 __블록 장치 __네트워크 장치 __실행 시 드라이버 찾기 ____Sysfs에서 정보 가져오기 __적합한 장치 드라이버 찾기 __사용자 공간의 장치 드라이버 ____GPIO ____LED ____I2C ____SPI __커널 장치 드라이버 작성 ____캐릭터 드라이버 인터페이스 설계 ____장치 드라이버의 구조 ____커널 모듈 컴파일하기 ____커널 모듈 로딩 __하드웨어 구성 정보 찾기 ____장치 트리 ____플랫폼 데이터 ____장치 드라이버와 하드웨어의 연동 __요약 __추가 자료 12장. 브레이크아웃 보드를 이용한 프로토타이핑__기술적 요구 사항 __장치 트리의 소스에 회로도 매핑하기 ____회로도와 데이터 시트 읽기 ____비글본 블랙에 데비안 설치하기 ____spidev 활성화하기 ____장치 트리 커스터마이징하기 __브레이크아웃 보드를 이용한 프로토타이핑 ____SPI 점퍼 닫기 ____GNSS 안테나 부착하기 ____SPI 헤더 부착하기 ____SPI 점퍼 와이어 연결하기 __로직 분석기로 SPI 신호 프로빙하기 __SPI를 통해 NMEA 메시지 수신하기 __요약 __추가 자료 13장. 시스템 구동: init 프로그램__기술적 요구 사항 __커널 구동 이후 __init 프로그램의 소개 __BusyBox init ____Buildroot init 스크립트 __System V init ____inittab ____init.d 스크립트 ____새로운 데몬 추가 ____서비스 시작과 종료 __systemd ____Yocto 프로젝트와 Buildroot에서 system 빌드하기 ____타깃, 서비스, 유닛의 소개 ____Systemd로 시스템을 구동하는 방법 ____직접 만든 서비스 추가 ____워치독 추가 ____임베디드 리눅스에서 중요한 점 __요약 __추가 자료 14장. BusyBox runit__기술적 요구 사항 __BusyBox runit 가져오기 __서비스 디렉터리와 파일 만들기 ____서비스 디렉터리 레이아웃 ____서비스 구성 __서비스 관리 ____서비스 제어하기 __다른 서비스에 대한 의존성 ____시작 의존성 ____커스텀 시작 의존성 ____모두 합치기 __전용 서비스 로깅 ____어떻게 동작하는가? ____서비스에 전용 로깅 추가하기 ____로그 회전 __서비스에 시그널 보내기 __요약 __추가 자료 15장. 전원 관리__기술적 요구 사항 __전력 사용량 측정 __클럭 주파수 스케일링 ____CPUFreq 드라이버 ____CPUFreq 사용 __최적의 idle 상태 선택하기 ____CPUIdle 드라이버 ____틱리스 작업 __주변 기기 전원 끄기 __시스템을 절전 모드로 전환하기 ____전력 상태 ____웨이크업 이벤트 ____실시간 클럭의 시간 지정 웨이크업 __요약 __추가 자료 3부. 임베디드 애플리케이션 작성하기16장. 파이썬 패키징하기__기술적 요구 사항 ____도커 설치하기 __파이썬 패키징의 기원 추적 ____distutils ____setuptools ____setup.py __pip로 파이썬 패키지 설치하기 ____requirements.txt __venv를 이용해 파이썬 가상 환경 관리하기 __conda를 이용해 미리 컴파일된 바이너리 설치하기 ____환경 관리 ____패키지 관리 __도커를 사용해 파이썬 애플리케이션 배포하기 ____도커파일 해부 ____도커 이미지 빌드하기 ____도커 이미지 실행하기 ____도커 이미지 가져오기 ____도커 이미지 게시하기 ____뒷정리 __요약 __추가 자료 17장. 프로세스와 스레드__기술적 요구 사항 __프로세스와 스레드 __프로세스 ____새로운 프로세스 만들기 ____프로세스 종료하기 ____다른 프로그램 실행하기 ____데몬 ____프로세스 간 통신 __스레드 ____새로운 스레드 만들기 ____스레드 종료하기 ____스레드를 사용하는 프로그램 컴파일하기 ____스레드 간 통신 ____상호 배제 ____조건 바꾸기 ____문제 나누기 __ZeroMQ ____pyzmq 받기 ____프로세스 간 메시징 ____프로세스 내 메시징 __스케줄링 ____공평성 대 결정성 ____시분할 정책 ____실시간 정책 ____정책 선택하기 ____실시간 우선순위 선택하기 __요약 __추가 자료 18장. 메모리 관리__기술적 요구 사항 __가상 메모리 기초 __커널 공간 메모리 레이아웃 __커널이 얼마나 많은 메모리를 사용하는가? __사용자 공간 메모리 레이아웃 __프로세스 메모리 맵 __스와핑 ____압축 메모리(zram)로 스왑 __mmap으로 메모리 매핑 ____mmap을 사용해 독립된 메모리 할당 ____mmap을 사용해 메모리 공유 ____mmap을 사용해 장치 메모리에 액세스 __애플리케이션에서 메모리를 얼마나 사용하고 있는가? __프로세스별 메모리 사용량 ____top과 ps 사용 ____smem 사용 ____고려할 만한 다른 도구 __메모리 누수 식별하기 ____mtrace ____Valgrind __메모리 부족 __요약 __추가 자료 4부 - 디버깅과 성능 최적화19장. GDB로 디버깅하기__기술적 요구 사항 __GNU 디버거 __디버깅 준비하기 __애플리케이션 디버깅 ____gdbserver를 이용한 원격 디버깅 ____원격 디버깅을 위한 Yocto 프로젝트 셋업하기 ____원격 디버깅을 위한 Buildroot 셋업하기 ____디버깅 시작하기 ____네이티브 디버깅 __JIT 디버깅 __디버깅 포크와 스레드 __코어 파일 ____GDB를 이용해 코어 파일 살펴보기 __GDB 사용자 인터페이스 ____터미널 사용자 인터페이스 ____데이터 디스플레이 디버거 ____비주얼 스튜디오 코드 __커널 코드 디버깅 ____kgdb를 사용한 커널 코드 디버깅 ____디버그 세션 샘플 ____얼리 코드 디버깅 ____디버깅 모듈 ____kdb를 사용한 커널 코드 디버깅 ____웁스 메시지 살펴보기 ____웁스 메시지의 보존 __요약 __추가 자료 20장. 프로파일링과 추적__기술적 요구 사항 __관찰자 효과 ____심볼 테이블과 컴파일 플래그 __프로파일링 시작하기 __top을 이용한 프로파일링 __가난한 사람의 프로파일러 __perf ____perf를 위한 커널 구성 ____Yocto 프로젝트를 이용해 perf 빌드하기 ____Buildroot를 이용해 perf 빌드하기 ____perf를 이용해 프로파일링하기 ____호출 그래프 ____perf annotate __이벤트 추적 __Ftrace ____Ftrace를 사용하기 위한 준비 ____Ftrace 사용하기 ____동적 Ftrace와 트레이스 필터 ____트레이스 이벤트 __LTTng 사용하기 ____LTTng와 Yocto 프로젝트 ____LTTng와 Buildroot ____LTTng를 사용해 커널 추적하기 __BPF 사용하기 ____BPF를 위한 커널 구성 ____Buildroot를 이용해 BCC 툴킷 빌드하기 ____BPF 추적 도구 사용하기 __Valgrind 사용하기 ____Callgrind ____Helgrind __strace 사용하기 __요약 __추가 자료 21장. 실시간 프로그래밍__기술적 요구 사항 __실시간이란 무엇인가? __비결정성의 원인 식별하기 __스케줄링 지연 이해하기 __커널 선점 ____실시간 리눅스 커널(PREEMPT_RT) ____스레드 인터럽트 핸들러 __선점 가능한 커널 잠금 ____PREEMPT_RT 패치 가져오기 ____Yocto 프로젝트와 PREEMPT_RT __고해상도 타이머 __페이지 폴트 피하기 __인터럽트 쉴딩 __스케줄링 지연 측정하기 ____cyclictest ____Ftrace ____cyclictest와 Ftrace를 함께 사용하기 __요약 __추가 자료