임베디드 시스템 개발 및 분석 중 라즈베리 파이4를 통해 디버깅 및 테스트를 하는 것이 제일 간단하고 유용할 것으로 예상되어 찾아본 결과 라즈베리파이4 자체의 JTAG Pin을 활용하여 ARM64 환경의 Bare-Metal Code 테스트를 진행 할 수 있으며 쉽게 테스트 및 디버깅이 가능하여 테스트 및 응용에 매우 강력하고 유용한 플랫폼으로 활용이 가능할 것으로 생각한다.

 

대략적인 연결 방법은 라즈베리파이4 Bare-Metal Code 로드 및 디버깅과 커널 디버깅에 사용할 수 있도록 OpenOCD를 사용하여 JTAG Interface를 활용 및 연결해야 한다.

그러기 위해서 라즈베리파이의 JTAG Pin을 소유하고 있는 JTAG Debugger (Olimex ARM-USB-OCD-H) 연결하여 TAP 인식 및 ARM Core Debugging 이 가능하다.

 

라즈베리파이4의 JTAG Pin 위치는 하기와 같다.

위에 나와있는 그림처럼 RPI의 JTAG Pin을 참고하여 사용하고자 하는 JTAG(여기서는 Olimex ARM-USB-OCD-H)의 Pin Map을 확인하여 1대1 연결하여 JTAG 통신 환경을 구축한다.

 

라즈베리파이에서 JTAG Pin을 사용하기 위해서는 Default Pin Func(Mux)가 JTAG 용도로 정의 되어 있지 않기 때문에

하기와 같이 booting 시 config.txt에 기입하여 Pin Mux를 진행하여야 한다.

 

[all]
# Disable pull downs
gpio=22-27=np

# Enable jtag pins (i.e. GPIO22-GPIO27)
enable_jtag_gpio=1

 

OpenOCD에서 rpi4 디버깅 연결을 위하여 하기와 같이 rpi4 관련된 config 파일을 생성해야 하는데 하기와 같이 작성하여

rpi4.cfg를 /share/openocd/script/targets 내에 저장해준다.

 

# SPDX-License-Identifier: GPL-2.0-or-later

# The Broadcom BCM2711 used in Raspberry Pi 4
# No documentation was found on Broadcom website

# Partial information is available in raspberry pi website:
# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/

if { [info exists CHIPNAME] } {
    set  _CHIPNAME $CHIPNAME
} else {
    set  _CHIPNAME bcm2711
}

if { [info exists CHIPCORES] } {
    set _cores $CHIPCORES
} else {
    set _cores 4
}

if { [info exists USE_SMP] } {
    set _USE_SMP $USE_SMP
} else {
    set _USE_SMP 0
}

if { [info exists DAP_TAPID] } {
    set _DAP_TAPID $DAP_TAPID
} else {
    set _DAP_TAPID 0x4ba00477
}

jtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4
adapter speed 3000

dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

# MEM-AP for direct access
target create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0

# these addresses are obtained from the ROM table via 'dap info 0' command
set _DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}
set _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}

set _smp_command "target smp"

for { set _core 0 } { $_core < $_cores } { incr _core } {
    set _CTINAME $_CHIPNAME.cti$_core
    set _TARGETNAME $_CHIPNAME.cpu$_core

    cti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]
    target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME

    set _smp_command "$_smp_command $_TARGETNAME"
}

if {$_USE_SMP} {
    eval $_smp_command
}

# default target is cpu0
targets $_CHIPNAME.cpu0

 

 

OpenOCD 실행을 하기와 같이 JTAG Interface와 RPI4에 관련된 cfg 파일을 -f 매개인자를 통하여 실행한다.

 

.\bin\openocd.exe -f .\share\openocd\scripts\interface\ftdi\olimex-arm-usb-ocd-h.cfg -f .\share\openocd\scripts\target\rpi4.cfg

 

 

위의 명령을 통해 OpenOCD를 터미널 혹은 PowerShell 상에서 실행하여  아래의 그림과 같이 GDB Server 와 Telnet Port가 생성되는 것을 확인 할 수 있다.

 

 

GDB Server가 정상적으로 실행되면 Rpi4의 Kernel 또는 Bare-metal Code를 작성하여 빌드 후 테스트 할 수 있는 환경을 갖추게 됩니다.

 

이 이후의 GDB Server Remote 연결 및 GDB 디버깅은 다음 포스트에서 진행하도록 하겠습니다.

 

 

'System Programming > Arm' 카테고리의 다른 글

Rockchip AP 부팅 흐름 정리  (0) 2020.03.11
ARM Processor 7개의 Mode  (0) 2016.08.29
ARM Processor 개요  (0) 2016.08.29

Virtualbox 사용 시 윈도우와 서로 파일을 주고 받기 편하기 위해 공유 폴더를 설정 할 수 있습니다.

 

하지만, 아래의 그림처럼 설정을 완료하고 사용하려 해도 권한 문제가 발생한다.

 

 

폴더 권한 예시

 

자동 마운트 되는 경로는 '/media' 내에 모두 디렉토리가 생성되어 마운트 되어 있을 것이다.

아래의 그림과 같이 'media' 경로 안에서 'ls -al' 명령어를 통해 확인해 보면 그룹 권한이 'vboxsf' 로 되어 있다.

디렉토리 권한 체크

위의 상황에서 간단한 해결 방법은 내가 사용하는 유저를 'vboxsf' 그룹에 포함 시켜주어야 한다.

 

vboxsf 그룹 등록 명령

위의 그림과 같이 'sudo gpasswd -a USER_ID vboxsf' 명령을 통해 그룹 등록을 진행해주어야 한다.

주의해야 할 점은 그룹 등록이 완료되었다 하더라도 이미 로그인된 세션에는 해당 권한이 적용되지 않으므로

재부팅 또는 로그아웃을 진행해주어야 한다.

 

재부팅 후 공유 폴더 내용 확인 예시

 - STL(Standard Templete Library)

    : C++의 템플릿을 사용하여 표준으로 정리된 라이브러리

     반복자 / 컨테이너 / 알고리즘 함수객체 등으로 구성되어 있다.


 - 컨테이너(Container)
    : 컨테이너는 기본 자료형과 사용자가 정의한 자료형을 담는 일종의 자료 구조

      클래스 템플릿 형태이므로 변수 선언할 때 컨테이너에 포함될 요소의 타입을 명시해야 한다.

      컨테이너에는 복사 생성과 대입을 할 수 있는 타입의 객체 및 변수만 저장할 수 있다.

      또한, 컨테이너는 요소의 추가 및 제거 등의 기능을 포함한 작업을 수행하는 멤버함수도 포함되어 있음

  1. 시퀀스 컨테이너
    : 데이터를 선형으로(순서대로) 저장하며, 특별한 제약이나 규칙이 없는 가장 일반적인 컨테이너
    시퀀스 컨테이너에서 삽입된 요소의 순서가 그대로 유지된다.
    vector, deque, list, forward_list

  2. 연관 컨테이너
    : 데이터를 일정 규칙에 따라 조직화하여 저장하고 관리하는 컨테이너
    set, multiset, map, multimap

  3. 어댑터 컨테이너
    : 간결함과 명료성을 위해 인터페이스를 제한한 시퀀스나 연관 컨테이너에서 변형된 컨테이너
    단, 반복자를 지원하지 않아 STL 알고리즘에서는 사용이 불가능하다.
    stack, queue, priority_queue

 

RPC failed; curl 56 GnuTLS recv error (-110): The TLS connection was non-properly terminated.

 

Git 및 Git LFS 등을 사용하여 빌드되는 경우 큰 파일 또는 TLS 값 에러가 발생하는 경우는 파일 수령 시 파일 크기가 Git 설정보다 클 경우 깨지게 된다.

 

해당 부분을 해결 또는 회피하기 위하여 Git File Buffer 사이즈를 늘려 큰 파일을 받는데 문제가 없도록 수정해야 한다.

 

하기의 Config 를 참고로 버퍼 크기를 수정하도록 한다.

 

ex) git config --global http.postBuffer 1048576000

     또는 SSL Verify false --> git config http.sslVerify false 까지 추가

+ Recent posts