我正在學習 ARM 上的裸機開發,為此我選擇在 QEMU 上模擬 Raspi3。因此,它是一個實作 ARMv8 架構的虛擬 ARM Cortex A-53。我編譯了以下簡單的裸機代碼:
.global _start
_start:
1: wfe
b 1b
我使用以下方式啟動它:
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -display none -S -s
并且 GDB 使用以下命令從另一個終端連接到它:
gdb-multiarch ./kernel8.elf -ex 'target remote localhost:1234' -ex 'break *0x80000' -ex 'continue'
到目前為止一切都很好,我可以注意到 gdb 中的斷點。
Reading symbols from ./kernel8.elf...
Remote debugging using localhost:1234
0x0000000000000000 in ?? ()
Breakpoint 1 at 0x80000: file start.S, line 5.
Continuing.
Thread 1 hit Breakpoint 1, _start () at start.S:5
5 1: wfe
(gdb) info threads
Id Target Id Frame
* 1 Thread 1.1 (CPU#0 [running]) _start () at start.S:5
2 Thread 1.2 (CPU#1 [running]) 0x0000000000000300 in ?? ()
3 Thread 1.3 (CPU#2 [running]) 0x000000000000030c in ?? ()
4 Thread 1.4 (CPU#3 [running]) 0x000000000000030c in ?? ()
(gdb) list
1 .section ".text.boot"
2
3 .global _start
4 _start:
5 1: wfe
6 b 1b
(gdb)
根據我的理解,在 ARM 的情況下,所有內核在復位時都會執行相同的代碼,所以理想情況下,我的所有內核都必須運行相同的代碼。我只想通過設定斷點來驗證這一點,這就是問題所在。其他核心的斷點未命中。如果我沒記錯的話,在我的情況下,執行緒只不過是核心。我試過休息但不起作用:
(gdb) break *0x80000 thread 2
Note: breakpoint 1 (all threads) also set at pc 0x80000.
Breakpoint 2 at 0x80000: file start.S, line 5.
(gdb) thread 2
[Switching to thread 2 (Thread 1.2)]
#0 0x0000000000000300 in ?? ()
(gdb) info threads
Id Target Id Frame
1 Thread 1.1 (CPU#0 [running]) _start () at start.S:5
* 2 Thread 1.2 (CPU#1 [running]) 0x0000000000000300 in ?? ()
3 Thread 1.3 (CPU#2 [running]) 0x000000000000030c in ?? ()
4 Thread 1.4 (CPU#3 [running]) 0x000000000000030c in ?? ()
(gdb) s
Cannot find bounds of current function
(gdb) c
Continuing.
[Switching to Thread 1.1]
Thread 1 hit Breakpoint 1, _start () at start.S:5
5 1: wfe
(gdb)
我洗掉了核心 1 斷點,然后核心 2 永遠掛起:
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000080000 start.S:5
breakpoint already hit 2 times
2 breakpoint keep y 0x0000000000080000 start.S:5 thread 2
stop only in thread 2
(gdb) delete br 1
(gdb) info break
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000000080000 start.S:5 thread 2
stop only in thread 2
(gdb) thread 2
[Switching to thread 2 (Thread 1.2)]
#0 0x000000000000030c in ?? ()
(gdb) c
Continuing.
What can I do get a breakpoint on core 2? What am I doing wrong here?
EDIT
I tried set scheduler-locking on (assuming this is what I need) but this also seems not working for me.
(gdb) break *0x80000
Breakpoint 3 at 0x80000: file start.S, line 5.
(gdb) thread 2
[Switching to thread 2 (Thread 1.2)]
#0 0x000000000000030c in ?? ()
(gdb) set scheduler-locking on
(gdb) c
Continuing.
^C/build/gdb-OxeNvS/gdb-9.2/gdb/inline-frame.c:367: internal-error: void skip_inline_frames(thread_info*, bpstat): Assertion `find_inline_frame_state (thread) == NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) n
This is a bug, please report it. For instructions, see:
<http://www.gnu.org/software/gdb/bugs/>.
/build/gdb-OxeNvS/gdb-9.2/gdb/inline-frame.c:367: internal-error: void skip_inline_frames(thread_info*, bpstat): Assertion `find_inline_frame_state (thread) == NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n)
EDIT 2
Upon @Frank's advice, I built (latest) qemu 6.2.0 locally and used the gdb available in the arm toolchain.
naveen@workstation:~/.repos/src/arm64/baremetal/raspi3-tutorial/01_bareminimum$ /opt/qemu-6.2.0/build/qemu-system-aarch64 -version
QEMU emulator version 6.2.0
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
naveen@workstation:~/.repos/src/arm64/baremetal/raspi3-tutorial/01_bareminimum$ /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb -version
GNU gdb (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.2.90.20210621-git
But I am still having the problem. My other cores 2,3 and 4 never hit the breakpoints. It seems they are not even running my code, as the address they are pointing to, does not look ok.
(gdb) info threads
Id Target Id Frame
* 1 Thread 1.1 (CPU#0 [running]) _start () at start.S:5
2 Thread 1.2 (CPU#1 [running]) 0x000000000000030c in ?? ()
3 Thread 1.3 (CPU#2 [running]) 0x000000000000030c in ?? ()
4 Thread 1.4 (CPU#3 [running]) 0x000000000000030c in ?? ()
EDIT 3
The problem seems with my Makefile, as when I used the command to build, as suggested by Frank, it worked for me. Can someone please look as what's wrong with this Makefile :
CC = /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf
CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostartfiles -nostdlib -g
all: clean kernel8.img
start.o: start.S
${CC}-gcc $(CFLAGS) -c start.S -o start.o
kernel8.img: start.o
${CC}-ld -g -nostdlib start.o -T link.ld -o kernel8.elf
${CC}-objcopy -O binary kernel8.elf kernel8.img
clean:
rm kernel8.elf kernel8.img *.o >/dev/null 2>/dev/null || true
EDIT 4
事實證明,當我使用kernel8.elfQEMU 進行引導時,一切都按預期作業。但是當我使用kernel8.img二進制格式時,我遇到了問題。通過閱讀,我了解到 ELF 包含使示例作業所需的“額外”資訊。但為了澄清,我怎樣才能完成這項kernel8.img作業?
uj5u.com熱心網友回復:
您可能對gdb或qemu您正在使用的版本有問題,因為我無法重現您使用 aarch64-elf-gdb 10.1 版和 qemu-system-aarch64 從頭開始??編譯的 6.2.0 版的問題Ubuntu 20.04.3 LTS系統:
wfe.s:
.global _start
_start:
1: wfe
b 1b
建筑wfe.elf:
/opt/arm/10/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gcc -g -ffreestanding -nostdlib -nostartfiles -Wl,-Ttext=0x80000 -o wfe.elf wfe.s
查看生成的代碼:
/opt/arm/10/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-objdump -d wfe.elf
wfe.elf: file format elf64-littleaarch64
Disassembly of section .text:
0000000000080000 <_stack>:
80000: d503205f wfe
80004: 17ffffff b 80000 <_stack>
開始qemu在shell會話:
/opt/qemu-6.2.0/bin/qemu-system-aarch64 -M raspi3b -kernel wfe.elf -display none -S -s
從gdb另一個開始:
/opt/gdb/gdb-10.1-aarch64-elf-x86_64-linux-gnu/bin/aarch64-elf-gdb wfe.elf -ex 'target remote localhost:1234' -ex 'break *0x80000' -ex 'continue'
gdb 會話:
GNU gdb (GDB) 10.1
Copyright (C) 2020 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-linux-gnu --target=aarch64-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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".
Remote debugging using localhost:1234
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x0000000000080000 in ?? ()
Breakpoint 1 at 0x80000
Continuing.
[Switching to Thread 1.4]
Thread 4 hit Breakpoint 1, 0x0000000000080000 in ?? ()
(gdb) break *0x80000 thread 2
Note: breakpoint 1 (all threads) also set at pc 0x80000.
Breakpoint 2 at 0x80000
(gdb) info threads
Id Target Id Frame
1 Thread 1.1 (CPU#0 [running]) 0x0000000000080000 in ?? ()
2 Thread 1.2 (CPU#1 [running]) 0x0000000000080000 in ?? ()
3 Thread 1.3 (CPU#2 [running]) 0x0000000000080000 in ?? ()
* 4 Thread 1.4 (CPU#3 [running]) 0x0000000000080000 in ?? ()
(gdb) c
Continuing.
[Switching to Thread 1.2]
Thread 2 hit Breakpoint 1, 0x0000000000080000 in ?? ()
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000080000
breakpoint already hit 2 times
2 breakpoint keep y 0x0000000000080000 thread 2
stop only in thread 2
breakpoint already hit 1 time
(gdb) del 1
(gdb) info b
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000000080000 thread 2
stop only in thread 2
breakpoint already hit 1 time
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, 0x0000000000080000 in ?? ()
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, 0x0000000000080000 in ?? ()
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, 0x0000000000080000 in ?? ()
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, 0x0000000000080000 in ?? ()
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, 0x0000000000080000 in ?? ()
(gdb)
因此,您的兩個問題的答案是:
- 我該怎么做才能在核心 2 上獲得斷點?
正是你在做什么。
- 我在這里做錯了什么?
什么都沒有,但可能正在使用gdb和/或的舊/錯誤版本qemu- 我的猜測是 gdb 是罪魁禍首是你的情況,但我可能是錯的。
您可以使用gdbArm 提供的 gcc 工具鏈中提供的版本再次測驗輕松驗證,AArch64 ELF 裸機目標 (aarch64-none-elf) - 我試過了,效果也很好:
/opt/arm/10/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb wfe.elf -ex 'target remote localhost:1234' -ex 'break *0x80000' -ex 'continue'
GNU gdb (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.2.90.20210621-git
Copyright (C) 2021 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=aarch64-none-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.linaro.org/>.
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 wfe.elf...
Remote debugging using localhost:1234
_start () at wfe.s:3
3 1: wfe
Breakpoint 1 at 0x80000: file wfe.s, line 3.
Continuing.
Thread 1 hit Breakpoint 1, _start () at wfe.s:3
3 1: wfe
(gdb) break *0x80000 thread 2
Note: breakpoint 1 (all threads) also set at pc 0x80000.
Breakpoint 2 at 0x80000: file wfe.s, line 3.
(gdb) info threads
Id Target Id Frame
* 1 Thread 1.1 (CPU#0 [running]) _start () at wfe.s:3
2 Thread 1.2 (CPU#1 [running]) _start () at wfe.s:3
3 Thread 1.3 (CPU#2 [running]) _start () at wfe.s:3
4 Thread 1.4 (CPU#3 [running]) _start () at wfe.s:3
(gdb) c
Continuing.
[Switching to Thread 1.2]
Thread 2 hit Breakpoint 1, _start () at wfe.s:3
3 1: wfe
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000080000 wfe.s:3
breakpoint already hit 2 times
2 breakpoint keep y 0x0000000000080000 wfe.s:3 thread 2
stop only in thread 2
breakpoint already hit 1 time
(gdb) del 1
(gdb) info b
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000000080000 wfe.s:3 thread 2
stop only in thread 2
breakpoint already hit 1 time
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, _start () at wfe.s:3
3 1: wfe
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, _start () at wfe.s:3
3 1: wfe
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, _start () at wfe.s:3
3 1: wfe
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, _start () at wfe.s:3
3 1: wfe
(gdb) c
Continuing.
Thread 2 hit Breakpoint 2, _start () at wfe.s:3
3 1: wfe
(gdb)
請注意,解釋如何構建最新版本的gdb和qemu超出了當前答案的范圍。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/405046.html
標籤:
