목표

• 리눅스 프로세스 관리 디버깅 환경 구축
• 최초 프로세스 생성 + 첫 번째 시스템 콜 디버깅

qemu를 이용한 커널 디버깅

• vmware와 같은 가상 머신
• 리눅스 커널 디버깅
• 우리는 JTAG 장비가 없으니..
• 앞으로 리눅스 프로세스 분석은 qemu 이용.
• 디바이스 드라이버 초반부

Buildroot 이용

• 전체 시스템 빌드용
• 자세한 내용은 디바이스 드라이버 시간에 설명, 프로세스 관리 시간에는 설명 안함.
• 요약: system boot, kernel, rootfs, toolchain
• 최종 디스크 이미지 생성(파티션 정보 + 부트로더 + 커널 + 루트 파일 시스템)
• Yocto(자동차)나 android(전화기)를 많이 사용
• 빌드 시간 많이 걸림 -> Native Linux 사용 권장
• native linux도 4시간 이상
• Vmware 사용 중이면 취침 전 빌드
• Buildroot에 대한 설명은 디바이스 드라이버 시간에 진행
• 장점: 가벼움, 단점: 부족한 기능(예: OTA)
• 부족한 부분이 많기 때문에, 큰 프로젝트 BAD, 적은 인력이 필요한 프로젝트 GOOD
• 교육용으로는 적합(시간 부족)

설치

# 패키지 설치
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib lib32ncurses5-dev x11proto-core-dev libx11-dev libgl1-mesa-dev libxml2-utils xsltproc unzip php texinfo srecord libssl-dev
# 소스코드 다운로드
git clone https://github.com/raspberrypi/buildroot
# 특정 브랜치로 이동
cd buildroot
git reset  39a2ff16f92a61a3e8593c394d211c18d01de8d4 --hard
# 다운로드 받은 패치 적용
cp ~/Downloads/0001-kdt-RPI-5.15.patch ./
git am 0001-kdt-RPI-5.15.patch
# 빌드 설정
make raspberrypi4_64_defconfig
# 빌드 전 강의 자료에 있는 커널 + rootfs  설정 작업
# 빌드 : 4시간 이상 걸림 *** 중요 ***
make
# qemu 설치
sudo apt install qemu-system-aarch64
# arm64용 gdb 설치
sudo apt install gdb-multiarch
# qemu linux 실행, gdb 연결을 기다림
qemu-system-aarch64 -M raspi4 -machine virt -machine type=virt -cpu cortex-a72 -kernel output/build/linux-custom/arch/arm64/boot/Image -nographic -append "console=ttyAMA0 nokaslr" -m 512 -initrd output/images/rootfs.cpio -smp 1  -s -S
# 다른 터미널 창에서 gdb 또는 vscode 디버깅
작전 1. gdb에서 설정 및 breakpoint 설정 + 실행
## 커널 디렉토리로 이동 후 커널 디버깅
cd output/build/linux-custom/
gdb-multiarch vmlinux
(gdb)set architecture aarch64
(gdb)target remote :1234
(gdb)b start_kernel
(gdb)c
작전 2. vscode로 커널 디버깅
## vscode 설정 파일 복사 
cp -a vscode/.vscode output/build/linux-custom/
cd output/build/linux-custom
code .
디버깅

최초 프로세스

• 전원 On하면 부트로더(PC는 BIOS)에서 커널 진입 후 장치 초기

• 그리고 리눅스 커널은 아래 실행파일을 최초 프로세스로 실행
• /sbin/init (이 위치는 시스템마다 다름)
• 우리 시스템의 init 프로세스는 busybox에 있는 init
• busybox는 유틸리티를 통합한 실행 파일

코드: 최초 프로세스 생성 - address

space
• 격리(Isolation)를 위해서 리눅스는 자신만 동작한다는 환상 만들어야 함.
• 이를 위해서, 리눅스는 부팅 시 개인적인 메모리 주소 공간을 제공
• 흔히 프로세스 address space라는 것을 가장 처음 생성함
• 리눅스는 mm_struct + vm_area_struct + page table을 통해 관리
• 최초 프로세스 생성 디버깅
• address space 생성
• breakpoint
arch/arm64/kernel/setup.c
setup_arch()

코드: 최초 프로세스 생성

• 커널 -> 유저 응용프로그램
• Init/main.c
• 함수 rest_init()

코드: 최초 시스템 콜: exec

• 우리는 커널이 어떻게 Isolation을 제공하는지 감을 잡는 중
• 지금까지는 커널 영역에서 동작
• 이제 커널 레벨에서 유저 레벨로 진입이 문제.
• 어떻게?
• exec 시스템 콜을 활용
• exec을 이용해 새로운 파일 디스크립터와, 프로세스 메모리를 재구성
• 커널 부모 프로세스에는 영향 없음
• 이제부터는 init 프로세스의 세상
• 물론 시스템 콜과 인터럽트로 인해 커널로 진입

0개의 댓글