U-boot 디버깅
Zynq의 특수 상황
Zynq에서 u-boot 같은 Eclipse에서 관리되지 않는 프로그램을 디버깅할 때 원래의 gdb와 xmd를 사용합니다.
일반적인 디버그는 SystemDebug(TCF) 사용
Eclipse에서 사용할 경우 System Debugger와 XSDB(XMD 대체)를 사용합니다.XSDB는 tcl을 사용할 수 있어 매우 편리하다.TCF를 사용하면 칩스코프도 일괄적으로 사용할 수 있다.언뜻 보기에 gdb에 대한 대리가 없다.어려운 점은 Eclipse 에서만 사용할 수 있다는 점입니다.
Zynq 시작
보통 FSBL->u-boot->Linux로 직립하는 SD로 일어서보세요.FSL에서 DDR 초기화 등을 수행하므로 편리합니다.U-boot 프롬프트에서 리눅스가 일어나기 전에 중지합니다.
u-boot-init.txt
U-Boot 2014.01-dirty (Jul 04 2014 - 19:54:37)
I2C: ready
Memory: ECC disabled
DRAM: 1 GiB
MMC: zynq_sdhci: 0
SF: Detected N25Q128 with page size 256 Bytes, erase size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: Gem.e000b000
Hit any key to stop autoboot: 0
Linux에 일어나면 MMU가 사용되기 시작하여 디버깅이 순조롭게 진행되지 않습니다.리눅스에 설 때는 Powerroff를 가만히 두고 처음부터 다시 하세요.xmd로 Zynq 잡기
xmd 프롬프트에서 connecthwarm으로 Zynq에 연결합니다.이렇게 xmd는 gdb 서버로 동작합니다.
이 예에서 TCP 포트 1237로 시작합니다. (보통 1234입니다. 몇 번 반복하면 번호가 하나씩 증가합니다. disconnect를 잘 하면 증가하지 않습니다.)xmd로 잡았기 때문에 Zynq의 u-boot 알림이 무효입니다.반대로 U-boot이 움직이면 xmd로 못 잡았어요.
뱀발이지만 이 방법으로 cpu1도 디버깅할 수 있습니다.이 경우 connectarm hw-debugdevice cpuncer2
DDR이 초기화되지 않았습니다.
DDR이 초기화되지 않으면 gdb로 원활하게 실행할 수 없습니다.gdb load 이후 stepi로 금방 죽은 상황에서 그럴 가능성이 있어.ps7_init.xmd에서 tcl을 실행하면 DDR을 초기화할 수 있습니다.또한 이렇게 제어를 잃을 때 xmd에서stop 명령을 실행하면 CPU가 강제로 정지됩니다.
실제 디버깅
u-boot 컴파일
디버그하기 전에 u-boot을 컴파일합니다.
make CROSS_COMPILE=arm-none-linux-gnueabi- zynq_ted_emc_config
make
Xilinx 컴파일러를 사용하는 사람은 CROSS입니다.COMPILE=arm-xilinx-linux-gnueabi-.gdb로 다운로드
gdb에서 u-boot의 매개 변수로 시작하여 target과 연결한 후load를 진행합니다.
> arm-none-linux-gnueabi-gdb u-boot
GNU gdb (Sourcery CodeBench Lite 2012.09-64) 7.4.50.20120716-cvs
Copyright (C) 2012 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=i686-pc-linux-gnu --target=arm-none-linux-gnueabi".
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>...
Reading symbols from /home/ryos/vdma_sd_boot/gemini_xosl_build_20140709/u-boot-xlnx/u-boot...done.
(gdb) target remote <IPアドレス>:1237
Remote debugging using <IPアドレス>:1237
0x3ff7221c in ?? ()
(gdb) load
Loading section .text, size 0x39d6c lma 0x4000000
Loading section .rodata, size 0xdf2f lma 0x4039d6c
Loading section .hash, size 0x2c lma 0x4047c9c
Loading section .data, size 0x212c lma 0x4047cc8
Loading section .got.plt, size 0xc lma 0x4049df4
Loading section .u_boot_list, size 0x87c lma 0x4049e00
Loading section .rel.dyn, size 0x8160 lma 0x404a67c
Start address 0x4000000, load size 337883
Transfer rate: 4 KB/sec, 95 bytes/write.
(gdb)
의 섹션은 xmd에서 일어나는 PC의 IP 주소입니다.로컬은localhost이지만 원래 U-boot은 로컬(windows)에서 컴파일할 수 없기 때문에 Linux 서버의 gdb를 사용합니다.gdb를 cont로 하면 u-boot을 실행합니다.미리 브레이크 포인트를 걸면 디버깅을 할 수 있습니다.멈추고 싶을 때 xmd부터 stop.그리고 하드웨어의 돌파점을 추가하고 싶을 때 xmd에서 bps 등을 사용할 수 있을 것이다.하드웨어의 돌파점은 소프트웨어가 제어를 잃을 때 유효하다.또한 (개인은 실제 성적이 없지만) 워치 포인트도 xmd부터 사용해야 한다.gdb 등 조사하기 어려운 특정 메모리 구역이 파괴되었을 때 역할을 발휘한다.
U-boot 응용 프로그램(외부 명령)
주제는 여기, 오프닝이 길어졌다.U-boot이 make라면 examples/standalone에서도 u-boot에서 시작하는 간단한 standalone 프로그램을 컴파일할 수 있습니다.gdb로 그걸 불러서 실행해 보세요.
hello_월드도 gdb load.
u-boot 다운로드 후 hello -월드를 다운로드하면 gdb에서 메모리를 읽을 수 있습니다.주의해야 할 것은load라면 gdb가 pc를 다시 쓸 것이다.load 나중에 컴퓨터 돌려줄게.
Program received signal SIGINT, Interrupt.
0x3ff7152c in ?? ()
(gdb) p $pc
$1 = (void (*)()) 0x3ff7152c
(gdb) load examples/standalone/hello_world
Loading section .text, size 0x1c8 lma 0xc100000
Loading section .rodata, size 0x8a lma 0xc1001c8
Start address 0xc100000, load size 594
Transfer rate: 3 KB/sec, 84 bytes/write.
(gdb) p $pc
$2 = (void (*)()) 0xc100000
(gdb) set $pc= 0x3ff7152c
(gdb) p $pc
$3 = (void (*)()) 0x3ff7152c
(gdb) cont
Continuing.
그런 다음 U-boot으로 돌아가서 0xc100000부터 실행합니다.zynq-uboot> go 0xc100000
## Starting application at 0x0C100000 ...
Example expects ABI version 6
Actual U-Boot ABI version 6
Hello World
argc = 1
argv[0] = "0xc100000"
argv[1] = "<NULL>"
Hit any key to exit ...
## Application terminated, rc = 0x0
** 0xc100000 다운로드 주소다운로드한 주소는 0xc100000입니다.이것은arch/arm/config입니다.mk에 기재되어 있지만 각 판에 설정해야 할 주소입니다.기분상 DDR은 보통 0번부터 256M에 랭크돼 있다.128M에 불과한 판자가 있으면 원활하게 작동하지 않기 때문에 주의가 필요하다는 것이다.
U-boot 응용 프로그램 다시 컴파일
다운로드 주소 설정을 변경하려면 CONFIGSTANDALONE_LOAD_ADDR을 변경할 수도 있고 make 시 지정할 수도 있습니다.내가 바꿔볼게.
> rm examples/standalone/hello_world
> make CROSS_COMPILE=arm-none-linux-gnueabi CONFIG_STANDALONE_LOAD_ADDR=0x040a0000
> arm-none-linux-gnueabi-objdump -h examples/standalone/hello_world
examples/standalone/hello_world: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000001c8 040a0000 040a0000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rodata 0000008a 040a01c8 040a01c8 000081c8 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
<攻略>
그리고 hello월드 읽기> fg
arm-none-linux-gnueabi-gdb u-boot-orig
^C
Program received signal SIGINT, Interrupt.
0x3ff71530 in ?? ()
(gdb) load examples/standalone/hello_world
Loading section .text, size 0x1c8 lma 0x40a0000
Loading section .rodata, size 0x8a lma 0x40a01c8
Start address 0x40a0000, load size 594
Transfer rate: 3 KB/sec, 84 bytes/write.
(gdb) set $pc=0x3ff71530
(gdb) cont
Continuing.
U-boot에서 실행zynq-uboot> go 0x40a0000
## Starting application at 0x040A0000 ...
Example expects ABI version 6
Actual U-Boot ABI version 6
Hello World
argc = 1
argv[0] = "0x40a0000"
argv[1] = "<NULL>"
Hit any key to exit ...
## Application terminated, rc = 0x0
동작이 아름답다.상기 0x040a 0000이 u-boot에서 사용되는지 모르기 때문에 상술한 것은 우연히 이동한 것일 수 있습니다.따라서 CONFFIG는 U-boot에서 사용하지 않는 부분이 있습니다.STANDALONE_LOAD_ADDR로 지정해야 합니다.
CONFIG_STANDALONE_LOAD_ADDR
이 CONFIG는 examples/standalone/Makefile에서 사용됩니다.
examples/standalone/Makefile에는 다음과 같은 설명이 있습니다.지금은 여기서만 사용하는 것 같아요.그러니까 로드 주소만 정하는 거야.현재 U-boot 호스트에는 영향이 없지만(확인됨) 원래 U-boot에서 사용되지 않았던 영역으로서 U-boot 호스트도 조정해야 한다.또 향후 조정이 이뤄질 것으로 보인다.따라서 각 판에 적당한 값을 설정해야 한다.
$(obj)%: $(obj)%.o $(LIB)
$(LD) $(LDFLAGS) -g -Ttext $(CONFIG_STANDALONE_LOAD_ADDR) \
-o $@ -e $(SYM_PREFIX)$(notdir $(<:.o=)) $< $(LIB) \
-L$(gcclibdir) -lgcc
fatload 후bootelf만든 helloworld는fatload에서 u-boot에서 불러와서 실행할 수 있습니다.elf를 사용합니다.바이너리에는 어떤 동태적인 설정이 있는 것 같고 단순한 동작이 없다.먼저 Zynq 측 Linux를 시작하고 SD 카드 hello를world.elf를 쓰고 (리눅스를 시작하지 않아도 SD카드에 걸면 됩니다) gdb에서 u-boot를 다시 시작합니다.거짓 helloworld.elf 확인 후 fatload로 적당한 곳에 불러오세요.bootelf를 이용해서 로드된 elf를 실행합니다.
가짜 확인을 통과하다
fatls
zynq-uboot> fatls mmc 0:1
40687 hello_world
fatload에서 사용하지 않은 주소로 불러오기fatload
zynq-uboot> fatload mmc 0:1 0x3000000 hello_world
reading hello_world
40687 bytes read in 21 ms (1.8 MiB/s)
bootelf에서 실행bootelf
zynq-uboot> bootelf 0x3000000
## Starting application at 0x0c100000 ...
Example expects ABI version 6
Actual U-Boot ABI version 6
Hello World
argc = 1
argv[0] = "0x3000000"
argv[1] = "<NULL>"
Hit any key to exit ...
## Application terminated, rc = 0x0
Reference
이 문제에 관하여(U-boot 디버깅), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ryos36/items/28bce4990661fefb981b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)