2012-07-10 67 views
23

Tôi mới phát triển hạt nhân và tôi muốn biết cách chạy/gỡ lỗi hạt nhân Linux bằng QEMU và gdb. Tôi thực sự đọc cuốn sách của Robert Love nhưng tiếc là nó không giúp người đọc làm thế nào để cài đặt các công cụ thích hợp để chạy hoặc gỡ lỗi hạt nhân ... Vì vậy, những gì tôi đã làm là làm theo hướng dẫn này http://opensourceforu.efytimes.com/2011/02/kernel-development-debugging-using-eclipse/. Tôi đang sử dụng nhật thực như là một IDE để phát triển trên hạt nhân nhưng tôi muốn đầu tiên để có được nó làm việc theo QEMU/gdb. Vì vậy, những gì tôi đã làm cho đến nay là:Làm thế nào để gỡ lỗi hạt nhân Linux với GDB và QEMU?

1) Để biên dịch hạt nhân với:

make defconfig (then setting the CONFIG_DEBUG_INFO=y in the .config) 
make -j4 

2) Khi biên soạn kết thúc tôi chạy Qemu sử dụng:

qemu-system-x86_64 -s -S /dev/zero -kernel /arch/x86/boot/bzImage 

mà khởi động hạt nhân trong trạng thái "đã dừng"

3) Vì vậy, tôi phải sử dụng gdb, tôi thử lệnh sau:

gdb ./vmlinux 

chạy chính xác nhưng ... Bây giờ tôi không biết phải làm gì ... Tôi biết rằng tôi phải sử dụng gỡ lỗi từ xa trên cổng 1234 (cổng mặc định được Qemu sử dụng), sử dụng vmlinux làm tệp bảng biểu tượng để gỡ lỗi. Vì vậy, câu hỏi của tôi là: Tôi nên làm gì để chạy hạt nhân trên Qemu, đính kèm trình gỡ lỗi của tôi vào nó và do đó, làm cho chúng hoạt động cùng nhau để làm cho cuộc sống của tôi dễ dàng hơn với sự phát triển hạt nhân.

Trả lời

19

Tôi muốn thử:

(gdb) target remote localhost:1234 
(gdb) continue 

Sử dụng tùy chọn '-s' làm Qemu lắng nghe trên cổng tcp :: 1234, mà bạn có thể kết nối là localhost: 1234 nếu bạn đang ở trên cùng một máy. Tùy chọn '-S' của Qemu làm cho Qemu ngừng thực thi cho đến khi bạn đưa ra lệnh tiếp tục.

Điều tốt nhất có thể là xem qua hướng dẫn GDB phong nha để làm quen với những gì bạn đang làm. This one trông khá đẹp.

+0

Cảm ơn rất nhiều nó hoạt động :). Tôi vừa kết thúc để đọc cuốn sách xử lý DDD, nhật thực và gdb được xuất bản bởi báo chí không tinh bột nhưng không có gỡ lỗi từ xa trong cuốn sách này. Hạt nhân của tôi hiện đang khởi chạy nhưng có vẻ như cần thời gian để tải (vì Qemu dường như chỉ sử dụng 1 luồng trên máy của tôi) và hiện bị chặn tại:? kernel_thread_helper + 0x0/0x10. Đó có phải là cách mà hạt nhân sử dụng được tải không? Tôi có nghĩa là, chúng ta không nên có một dấu nhắc lệnh khi nó được nạp? Cảm ơn bạn –

+0

nó hoạt động cho tôi. Tuy nhiên, tôi không biết làm thế nào để buộc hạt nhân dừng lại trên breakpoint sau khi gọi đầu tiên tiếp tục. Ví dụ, tôi đặt một điểm ngắt trong hàm start_kernel nhưng nó sẽ không bao giờ dừng ở đó. Bất kỳ ý tưởng ? – ARH

2

Khi bạn cố gắng để bắt đầu vmlinux exe sử dụng gdb, điều đó đầu tiên trên gdb là đưa ra cmds:

(gdb) mục tiêu từ xa localhost: 1234

(gdb) phá vỡ start_kernel

(tiếp tục)

Điều này sẽ phá vỡ hạt nhân tại start_kernel.

+0

Tôi sử dụng nhật thực để gỡ lỗi hạt nhân chạy trong qemu, và dừng lại ở start_kernel.But nó chạy sau khi chạy eclipse debug. Tôi đã thiết lập qemu dừng lại khi nó bắt đầu và sử dụng gdb một mình là ok. – Ezio

3

Câu trả lời của BjoernID không thực sự hiệu quả đối với tôi. Sau khi việc tiếp tục đầu tiên, không có điểm dừng là đạt và trên ngắt, tôi sẽ thấy các đường như:

0x0000000000000000 in ??() 
(gdb) break rapl_pmu_init 
Breakpoint 1 at 0xffffffff816631e7 
(gdb) c 
Continuing. 
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..] 

Tôi đoán đây có cái gì để làm với chế độ CPU khác nhau (chế độ thực sự trong BIOS vs chế độ dài khi Linux có khởi động). Dù sao, giải pháp là để chạy QEMU đầu tiên mà không cần chờ (nghĩa là không phải -S):

qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s 

Trong trường hợp của tôi, tôi cần thiết để phá vỡ tại một cái gì đó trong khi khởi động, vì vậy sau khi một số deciseconds, tôi chạy lệnh gdb. Nếu bạn có nhiều thời gian hơn (ví dụ: bạn cần gỡ lỗi mô-đun được tải theo cách thủ công), thì thời gian không thực sự quan trọng.

gdb cho phép bạn chỉ định các lệnh sẽ chạy khi bắt đầu. Điều này làm cho tự động hóa dễ dàng hơn một chút. Để kết nối với QEMU (mà nên bây giờ đã được bắt đầu), phá vỡ trên một chức năng và tiếp tục thực hiện, sử dụng:

gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux 
13

Step-by-step thủ tục thử nghiệm trên Ubuntu 16.10 chủ

Để bắt đầu từ đầu một cách nhanh chóng tôi đã thực hiện một tối thiểu hoàn toàn tự động ví dụ qemu + Buildroot tại địa chỉ: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md chính các bước được trình bày bên dưới.

Đầu tiên có hệ thống tệp gốc rootfs.cpio.gz. Nếu bạn cần một, xem xét:

Sau đó trên nhân Linux:

git checkout v4.15 
make mrproper 
make x86_64_defconfig 
cat <<EOF >.config-fragment 
CONFIG_DEBUG_INFO=y 
CONFIG_DEBUG_KERNEL=y 
CONFIG_GDB_SCRIPTS=y 
EOF 
./scripts/kconfig/merge_config.sh .config .config-fragment 
make -j"$(nproc)" 
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \ 
        -initrd rootfs.cpio.gz -S -s \ 
        -append nokaslr 

Trên một thiết bị đầu cuối khác, từ bên trong cây nhân Linux, giả sử bạn muốn bắt đầu gỡ lỗi từ start_kernel:

gdb \ 
    -ex "add-auto-load-safe-path $(pwd)" \ 
    -ex "file vmlinux" \ 
    -ex 'set arch i386:x86-64:intel' \ 
    -ex 'target remote localhost:1234' \ 
    -ex 'break start_kernel' \ 
    -ex 'continue' \ 
    -ex 'disconnect' \ 
    -ex 'set arch i386:x86-64' \ 
    -ex 'target remote localhost:1234' 

và chúng tôi đã hoàn tất !!

Đối với các module kernel xem: How to debug Linux kernel modules with QEMU?

Đối với Ubuntu 14.04, GDB 7.7.1, hbreak là cần thiết, break breakpoint phần mềm đã bị lờ đi. Không phải là trường hợp nữa trong 16.10. Xem thêm: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944

Các lộn xộn disconnect và những gì đến sau nó là để làm việc xung quanh lỗi:

Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000 

chủ đề liên quan:

biết đến giới hạn:

Xem thêm: