2017년 1월 22일 일요일

Atmel SAM-ICE를 이용한 u-boot & linux kernel debugging

이번 post에서는 Atmel SAM-ICE JTAG emulator를 이용하여 SAMA5D3 Xplained board 상에서 u-boot 및 linux kernel을 debugging하는 방법을 소개해 보고자 한다.

SAM-ICE JTAG emulator + SAMA5D3 Xplained board + Eclipse + U-Boot or Linux kernel

 

JTAG을 활용한 debugging이 필요한 경우는, 두말할 것 없이 초기 board를 살리고자 하는 경우(예: u-boot을 수정해서 돌렸는데, console 상으로 아무런 message도 출력되지 않는 경우)나, 전혀 예상치 못한 곳에서 system이 뻗어 버리는 경우(예: chip vendor가 제공한 코드에서 가뭄에 콩나듯 한번씩 죽는 상황) 등을 해결하기 위해서일 것이다(그 밖의 경우는 직접 code를 보는게 답일 수 있다. Debugger가 모든 걸 해결해 주지는 않는다). 
JTAG debugger로는 Trace32ARM DS-5와 같은 값 비싼 tool도 생각해 볼 수 있겠으나, 현실적으로 접하는데 어려움이 있을 수 있으니, (개인적으로 사용하기에도)저렴하면서도 충분한 효과를 볼 수 있는 방법을 고민해 볼 필요가 있어 보인다.

<저렴하고, 효율적인 JTAG debugger>
a) Segger J-Link EDU + Eclipse(gdb)
  => 일반적인 ARM Cortex board에 적용 가능 
b) OpenOCD 기반 JTAG emulator + Eclipse(gdb)
  => open source임.
...


<목차>
1. Atmel SAM-ICE 소개
2. Eclipse Debugging 환경 구축하기
  => ARM cross toolchain, JLink GDB server, Eclipse & plug-ins
3. JTAG을 이용한 AT91Bootstrap Loader Debugging 절차 소개
4. JTAG을 이용한 U-Boot Debugging 절차 소개
5. JTAG을 이용한 Kernel Debugging 절차 소개
6. KGDB를 이용한 Kernel Debugging 방법 소개


1. Atmel SAM-ICE 소개
SAME-ICE(Atmel 장비 전용)는 Segger 사에서 만든 J-Link를 기반으로 만든(OEM) JTAG emulator로, SAM-ICE를 사용하기 위해서는 J-Link website로 부터 관련 s/w를 내려 받아 설치해야만 한다.

그림 1.1 Atmel SAM-ICE JTAG emulator 외관 

그림 1.2 Atmel SAM-ICE pinout 

SAM-ICE의 주요 특징을 열거해 보면 다음과 같다.

아래 그림 1.3은  SAMA5D3 Xplained board의 주요 device를 그림으로 표현한 것으로, 좌측 하단에 20 pin JTAG port가 있음을 알 수 있다.

그림 1.3 SAMA5D3 Xplained board - 좌측 하단  JTAG interface(20 pin)

그림 1.4 SAMA5D3 Xplained board JTAG 회로도(출처 - 참고문헌 [4])

참고) JTAG과 관련한 사항(debugging 관련 기법 포함)은 필자가 오래전에 작성해 둔 아래 문서를 참고하기 바란다.

Atmel SAM-ICE(AT91SAM-ICE)는 아래 site에서 150$에 구매가 가능하다.


2. Eclipse Debugging 환경 구축하기 
이번 절에서는 SAM-ICE(J-Link)와 Eclipse를 이용하여, ARM target board에서 bootloader & kernel을 debugging하기 위해 필요한 환경 설정에 관하여 정리해 보고자 한다. 아래 그림 2.1은 Host PC(GDB, GDB Server)와 JTAG emulator(J-Link) 및 ARM target board로 구성된 전체 디버깅 환경을 하나의 그림으로 표현해 본 것이다. 이 그림에서 GDB Server는 GDB 명령을 JTAG emulator(= J-Link)가 알아볼 수 있는 형태로 전환하여 전달하는 역할을 담당한다.

Eclipse -> GDB -> (tcp/ip) -> GDB Server -> JTAG emulator -> JTAG -> Target ARM CPU

그림 2.1 JTAG을 이용한 Cross Platform Debugging 환경 개요(출처 - 참고문헌[3])

참고) 위의 구성에서 Eclipse가 필요한 이유는 사용자 친화적인 debugging 환경을 제공해 주기 때문이다.

이번 절에서 구체적으로 설명할 내용을 정리해 보면 다음과 같다.
a) cross toolchain(gdb) 설치 방법 소개
b) SAM-ICE 장치 연결(to SAMA5D3 Xplained board) 방법 소개
c) JLink GDB server 설치 방법 소개
d) Eclipse 및 Eclipse GNU ARM plug-in 및 CDT plug-in 설치 방법 소개 

2.1 ARM Cross Toolchain 설치하기
본 blog에서는 buildroot 환경을 토대로 debugging을 시도할 예정이다. 따라서, toolchain은 아래의 것을 활용하기로 한다. 물론 다른 toolchain을 사용해도 무방하다.
buildroot/output/host/usr/bin/arm-linux-*

위의 toolchain 파일 중, 실제로 debugging을 위해 필요한 파일은 arm-linux-gdb인데, buildroot에서는 이 cross gdb가 기본적으로 disable되어 있으므로, 아래와 같이 Toolchain 메뉴에서 먼저 enable 시켜 주어야만 한다.

그림 2.2 Buildroot cross gdb 선택 화면

$ make
$ cd output/host/usr/bin
$ ls -l arm-linux-gdb
  => arm-linux-gdb가 생성었는지를 확인해 본다.

참고) 이 절에서 만든 arm-linux-gdb 파일은 Eclipse에서 사용하게 될 것이다.

2.2 SAMA5D3 Xplained board에 SAM-ICE 연결하기
SAM-ICE 장치를 아래 그림과 같이 SAMA5D3 Xplained board에 연결하도록 하자.

그림 2.3 SAM-ICE를 SAMA5D3 Xplained board에 연결한 모습

그림 2.4 SAMA5D3 Xplained board의 JTAG port(20 pins)

주의) 케이블 연결시에는 🔺 모양이 표시된 부분이 반드시 JTAG port의 1번 pin에 연결될 수 있도록 주의하여야 한다. 연결 후에는 JLink tool(얘: JLinkExe)을 사용하여 제대로 연결되었는지를 확인해 볼 수 있다.

2.3 JLink GDB server 설치하기
이미 1절에서도 언급했다시피, Atmel SAM-ICE JTAG emulator는 Segger사의 JLink를 기반으로 만들어졌다. 따라서 관련 S/W(J-Link Software and Documentation Pack)Segger website에서 download 받아 사용해야 한다.

그림 2.5 J-Link Software and Documentation Pack 다운로드

아래 내용은 64bit Linux Host PC(x86_64)용 S/W를 내려 받아 설치하는 과정을 정리한 것이다(Windows 사용자라면 Windows용 version을 내려 받아 설치하면 된다).

$ tar xvzf ./JLink_Linux_V612f_x86_64.tgz
$ cd JLink_Linux_V612f_x86_64
$ tar cvf 1.tar ./libjlinkarm.so*
$ sudo tar xvf 1.tar -C /usr/lib; rm 1.tar
$ sudo cp ./99-jlink.rules /etc/udev/rules.d/
  => PC(Linux)를 재부팅해 주어야 한다.

PC를 재부팅한 후, SAM-ICE 장비가 제대로 인식되는지를 확인하기 위해서는 아래와 같이 JLinkExe 명령을 실행해 보면 된다.

그림 2.6 JLinkExe 실행 모습

또한, 아래와 같이 앞으로 실제로 사용하게 될 JLink GDB server가 제대로 구동되는지도 확인해 보도록 하자.

$ cd JLink_Linux_V612f_x86_64
./JLinkGDBServer -device ATSAMA5D36

그림 2.7 JLinkGDBServer 실행 모습

참고) JLinkGDBServer 명령 실행 시, device를 지정해 주지 않았더니, JLinkGDBServer가 죽어 버리는 문제가 있었다. JLinkGDBServer에서 사용 가능한 option으로는 아래와 같은 내용을 생각해 볼 수 있겠다. 관련해서는 참고 문헌 [3]을 참조하기 바란다.
./JLinkGDBServer -if JTAG -endian little -device ATSAMA5D36 -select USB -noir -noreset

그림 2.7을 보면 알 수 있듯이, JLinkGDBServer는 GDB와의 통신을 위해 2331 port를 사용하고 있다. 이 값은 나중에 eclipse 설정 시 필요한 정보이니, 잘 기억해 둘 필요가 있겠다.

2.4 Eclipse & Plug-in 설치하기
먼저 Eclipse website로 부터 "Eclipse IDE for C/C++ Developers for Linux"를 내려 받아 설치를 진행하도록 한다. Eclipse 설치와 관련해서는 인터넷에 관련 내용이 많이 알려져 있는 만큼, 여기서는 별도로 설명을 하지는 않겠다(참고로 필자는 Eclipse Neon.2, 4.6.2 version을 설치했음).

 Eclipse가 정상적으로 설치된 경우, 아래와 같이 eclipse 명령을 실행하도록 하자(주의: 아래와 같이 앞 부분에 option을 준 이유는 Eclipse menu가 정상 출력되도록 하기 위해서임).

chyi@earth:~/eclipse/cpp-neon/eclipse$ UBUNTU_MENUPROXY= ./eclipse

다음으로 해야할 일은 GNU ARM Eclipse plug-in을 설치하는 일인데, 이와 관련해서는 아래 site 내용을 참조하기 바란다.

그림 2.8 GNU ARM Plug-in 설치 방법 관련 site 내용

위의 site 내용을 간단히 요약해 보면, Eclipse Menu 중 Help -> Eclipse Marketplace를 선택한 상태에서, 위의 site의 "Install" 버튼을 Marketplace 팝업 위에 가져다 놓으면(drag-and-drop), 설치가 자동으로 진행되게 된다는 것이다. 아래 그림은 Marketplace를 이용하여 설치하는 과정을 보여준다.

그림 2.9 Eclipse Marketplace를 이용해 GNU ARM plug-in을 설치하는 모습

이번에는 CDT(C/C++ Development Tooling) plug-in을 설치할 차례이다. 이를 설치하는 절차는 간단하다. Eclipse Menu -> Help -> Install New Software를 선택한 상태에서 아래 그림과 같이 Work with: 항목을 CDT - http://download.eclipse.org/tools/cdt/releases/9.2으로 선택 한 후, 설치를 진행해 주면 된다.

그림 2.10 Eclipse CDT plug 설치 모습

지금까지 설치한 plug-in을 확인하기 위해서는 Eclipse Menu -> Help -> About Eclipse -> Installation Details 버튼을 눌러 결과를 확인해 보기 바란다.

그림 2.11 Eclipse Plug-in 설치 내용 확인

이상으로 SAM-ICE 및 Eclipse 디버깅 환경을 위한 모든 준비가 마무리 되었다. 이제 부터는 본격적으로 debugging 절차에 들어가 보도록 하자.


3. JTAG을 이용한 AT91Bootstrap Loader Debugging 절차 소개
이번 절에서는 secondary bootloader인 AT91Bootstrap loader를 debugging해 보는 절차를 소개하도록 하겠다.

a) Project 생성하기
File -> New -> Makefile Project with Existing Code 선택 후, 아래 그림 3.1과 같이 적절히 값을 입력하여 project를 하나 생성해 본다.

그림 3.1 AT91Bootstrap loader용 project 생성 모습

b) build하기
Project -> Build Project를 선택하여 build를 진행한다.

그림 3.2 AT91Bootstrap loader project build 모습

c) Debugging 환경 설정하기
Run -> Debug Configurations... 선택 후, 좌측 GDB Hardware Debugging을 선택(mouse 우 click) 후, New하여 새로운 debugging 환경을 생성한다. 이후 아래(그림 3.3 ~ 3.6)와 같이 값을 차례로 입력하도록 한다.

그림 3.3 at91bootstrap_configuration - Main tab 설정

그림 3.4 at91bootstrap_configuration - Debugger tab 설정


그림 3.5 at91bootstrap_configuration - Startup tab 설정


그림 3.6 at91bootstrap_configuration - Common tab 설정

이제 모든 준비가 끝났다. Debugging을 시작하기 전에, 다시 아래 조건을 새롭게 확인한 상태에서 "Debug" 버튼(위 그림 3.6 우측 하단 버튼)을 눌러 debugging을 시작해 보도록 하자.

<debugging 시작 조건>
a) SAMA5D3 Xplained board를 재시작하고, u-boot prompt 상태에서 멈추도록 한다.
b) ./JLinkGDBServer -device ATSAMA5D36를 다시 시작한다.

Debug 버튼을 선택한다. 잠시 후, JLink GDB Server가 아래와 같이 동작(elf file을 loading하고, read 명령 등을 실행함)을 시작해야 한다.

그림 3.7 JLink GDB Server의 동작 모습

약간의 시간이 경과한 후, 아래와 같은 화면이 뜨면 성공이다.

 그림 3.8 AT91Bootstrap loader debugging 화면(초기 모습)

<F6> 키를 눌러 다음 단계로 Step Over해 보도록 하자.

그림 3.9 AT91Bootstrap loader debugging 화면(F6 키 선택 후 모습)

이후 부터는 본인이 원하는 형태로 다양한 debugging을 시도해 볼 수 있을 것이다.


4. JTAG을 이용한 U-Boot Debugging 절차 소개
U-boot을 debugging하는 절차는 AT91bootstrap loader의 그것과 동일하다. 다만, 아래의 차이가 있을 뿐이다.

Existing Code Location: /home/chyi/Atmel/buildroot/output/build/uboot-linux4sam_5.5
C/C++ Application명: /home/chyi/Atmel/buildroot/output/build/uboot-linux4sam_5.5/u-boot

참고) debugging에 사용되는 u-boot 파일의 형식은 ELF(Executable and Linkable Format)인데, ELF는 실행 파일, object 파일, shared library 및 core dump를 위한 표준 파일 형식을 말한다.

U-boot debugging을 시도하기에 앞서, 대략적은 u-boot bootloader의 코드 흐름을 분석해 보고, debugger로 분석한 내용과 비교해 보는 것도 좋을 듯 싶다.

$ grep -rl "sama5" *
  => grep으로 u-boot code 중 SAMA5D3 Xplained board와 관련 내용을 추려 본다.
  => 이 밖에도 코드를 이것 저것 살펴 보면서 SAMA5D3 Xplained board와 연관되는 string을 찾아낸 후, 다시 grep을 시도해 보도록 한다.

코드 4.1 SAMA5D3 Xplained 보드용 u-boot 주요 코드 검색


대략적인 코드 흐름은 다음과 같다(예상된다).

arch/arm/cpu/armv7/start.S    ...... 코드 시작 Point !
|
V


코드 4.2 SAMA5D3 Xplained 용 u-boot code 흐름(main code flow)

아래 내용은 Eclipse로 u-boot을 debugging하는 모습(F6, F5 키를 적절히 선택하면서 다음 단계로 진행)을 보여준다.

<debugging 시작 조건>
a) SAMA5D3 Xplained board를 재시작하고, u-boot prompt 상태에서 멈추도록 한다.
b) ./JLinkGDBServer -device ATSAMA5D36를 다시 시작한다.

이후 Eclipse를 다시 구동하고, Debug 버튼을 선택한다.

그림 4.1 u-boot 디버깅 화면 1

그림 4.2 u-boot 디버깅 화면 2


그림 4.3 u-boot 디버깅 화면 3

 그림 4.4 u-boot 디버깅 화면 4

그림 4.5 u-boot 디버깅 화면 5

<TBD> 현재 breakpoint 명령이 제대로 먹히지 않는 것 같다. 추가 검토가 필요하다.


5. JTAG을 이용한 Kernel Debugging 절차 소개
Linux kernel을 debugging하는 절차 역시 AT91bootstrap loader or u-boot bootloader와 동일하다. 차이점을 정리해 보면 다음과 같다.

Existing Code Location: /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5
C/C++ Application명: /home/chyi/Atmel/buildroot/output/build/linux-linux4sam_5.5/vmlinux

또한 linux kernel을 debugging 하기 위해서는 반드시 아래 kernel feature를 enable해 주어야 한다.

$ make linux-menuconfig

Kernel hacking -->
    Compile-time checks and compiler options --->
        [*] Compile the kernel with debug info

그림 5.1 kernel debug feature를 enable 시키는 모습

Linux kernel의 경우는 size가 매우 크므로, JLinkGDBServer를 통해 vmlinux 파일을 memory로 load하는 시간이 매우 오래 걸린다. 또한 at91bootstrap loader나 u-boot 처럼, debugging 절차가 단순하지도 않다. 따라서 보다 세밀한 접근 방법이 필요해 보인다. 이 부분은 다음 시간에 추가로 검토해 보도록 하겠다.

<debugging 시작 조건>
a) SAMA5D3 Xplained board를 재시작하고, u-boot prompt 상태에서 멈추도록 한다.
b) ./JLinkGDBServer -device ATSAMA5D36를 다시 시작한다.
c) u-boot을 먼저 debugging한다 - 단, kernel 시작 전에 멈추도록 한다(breakpoint 지정)

<TBD> 실제 vmlinux debugging 모습 정리해야 함.


6. KGDB를 이용한 Kernel Debugging 방법 소개
KGDB를 이용한 kernel debugging 방법은 JTAG이 없을 경우 kernel을 효과적으로 debugging할 수 있는 방법이다. 하지만, 아래와 같은 제약 사항을 안고 있는 것도 사실이다. 이런 제약 사항에도 불구하고, booting 중 특정 device driver에서 문제(panic, Oops)가 발생할 경우, 효과적으로 debugging할 수 있는 방법임에는 틀림이 없을 것 같다. 따라서 이번 절에서는 KGDB를 이용한 kernel debugging 기법을 소개하고자 한다.

<제약 조건>
a) bootloader 등 kernel booting 이전 단계에 대해서는 debugging이 불가하다.
b) kernel의 경우도 serial console이 초기화되기 전까지의 상황에 대해서는 역시 debugging이 불가하다.

6.1 KGDB를 위해 kernel 재 build하기
먼저 KGDB를 사용하기 위해서는 몇가지 kernel feature를 enable시켜 주어야 한다.

$ cd buildroot
make linux-menuconfig
Kernel hacking --->
   Compile-time checks and compiler options  --->
       [*] Compile the kernel with debug info

   [*] KGDB: kernel debugger  --->
       <*>   KGDB: use kgdb over the serial console

그림 6.1 KGDB enable 모습

make
  => output/build/linux-linux4sam_5.5/vmlinux 파일이 생성될 것임.

6.2 KGBD 동작 확인하기 
SAMA5D3 Xplained board의 u-boot prompt 상에서 아래 명령을 실행해 준다(NFS booting을 하기 위함임). NFS booting과 관련해서는 이전 blog(2절)를 참조하기 바란다.

<SAMA5D3 Xplained target board - u-boot 명령>
=> setenv nb1 'setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}::${netmask}::eth0:off console=ttyS0,115200 kgdboc=ttyS0,115200 kgdbwait'

=> setenv nb2 'tftp 0x22000000 zImage; tftp 0x21000000 at91-sama5d3_xplained_pda4.dtb; bootz 0x22000000 - 0x21000000'

=> run nb1; run nb2

그림 6.2 kgdbwait에 의해 부팅 중 대기 상태에서 빠진 모습

위의 그림에서도 알 수 있듯이 "kgdboc=ttyS0,115200 kgdbwait" command line 명령에 의해, kernel은 아래 message를 마지막으로 출력한 채 대기 상태에 빠지게 된다.

...
console [ttyS0] enabled
KGDB: Registered I/O driver kgdboc
KGDB: Waiting for connection from remote gdb...
  <= 이 상태에서 대기하게 됨.
=============================================

이 상태에서 Host PC에서 gdb(arm cross gdb)를 이용하여 vmlinux(ELF file)에 대한 debugging을 시도해 보면 다음과 같다.

<Host PC - gdb 명령>
export PATH=/home/chyi/Atmel/buildroot/output/host/usr/bin:$PATH
$ cd build/linux-linux4sam_5.5
arm-linux-gdb ./vmlinux
GNU gdb (GDB) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-buildroot-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./vmlinux...done.
(gdb) target remote /dev/ttyUSB0    <= kgdb와 /dev/ttyUSB0 포트를 통해 연결
Remote debugging using /dev/ttyUSB0
0xc0069a2c in arch_kgdb_breakpoint () at kernel/debug/debug_core.c:1070
1070 wmb(); /* Sync point before breakpoint */
(gdb) list
1065  * the debugger.
1066  */
1067 noinline void kgdb_breakpoint(void)
1068 {
1069 atomic_inc(&kgdb_setting_breakpoint);
1070 wmb(); /* Sync point before breakpoint */
1071 arch_kgdb_breakpoint();
1072 wmb(); /* Sync point after breakpoint */
1073 atomic_dec(&kgdb_setting_breakpoint);
1074 }
(gdb)

<TBD> gdb 대신 eclipse로 debugging하는 내용 정리해야 함.


이상으로 JTAG을 활용한 debugging 기법에 관하여 간략히 정리해 보았다. 내용 중 미비한 부분은 추가로 정리 & 검토해 볼 것을 약속하며 이번 post를 마무리 하고자 한다.


References
1. http://www.at91.com/linux4sam/bin/view/Linux4SAM/AT91BootstrapDebugEclipse
2. AT91SAM-ICE_User_Guide.pdf, Atmel.
3. https://www.segger.com/admin/uploads/productDocs/UM08001_JLink.pdf
4. Atmel-11269-32-bit-Cortex-A5-Microcontroller-SAMA5D3-Xplained_User-Guide.pdf, Atmel.
5. Mastering Embedded Linux Programming, Chris Simmonds, PACKT publishng.

<Internet>
6. https://www.element14.com/community/community/designcenter/single-board-computers/riotboard/blog/2014/07/24/debugging-u-boot-on-riotboard-using-eclipse-and-jlink-under-linux
7. http://electro-don.tistory.com/entry/Eclipse-Yagarto-Segger-JLink-%EB%A1%9C-ARM-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-%EC%A0%95%EB%A6%AC
8. http://www.sw-at.com/blog/2011/02/11/linux-kernel-development-and-debugging-using-eclipse-cdt/
9. http://stackoverflow.com/questions/13085211/linux-debugging-with-jtag-arm9at91sam9g25-amontec-openocd-gdb-eclipse


Slowboot


댓글 없음:

댓글 쓰기