linux ऑपर QEMU और केजीडीबी के साथ लिनक्स कर्नेल कैसे डीबग करें?




लिनक्स के फायदे (2)

मैं qemu (v1.7.0) को लागू करने के लिए निम्न तरीके का उपयोग करके एक पावरपीसी आधारित सिस्टम (विशिष्ट होने के लिए एमपीसीएटीएटीएटीएडीएडीएस) को बूट करने में सक्षम हूं।

qemu-system-ppc -M mpc8544ds -m 512 -kernel zImage -s -nographic -initrd busyboxfs.img -append "root=/dev/ram rdinit=/bin/sh kgdboc=ttyS0,115200 kgdbwait"

जहां zImage एक कस्टम क्रॉस संकलित लिनक्स कर्नेल (v2.6.32) है, जिसमें किजीडीबी सक्षम और संकलित किया गया है (स्टार्ट-अपकोड डीबगिंग के लिए) और busyboxfs.img एक busyboxfs.img आधारित busyboxfs.img है।

चूंकि मैं क्यूएम में झंडे का उपयोग कर रहा हूं, इसलिए मैं क्रॉस जीडीबी का उपयोग कर कर्नेल को तोड़ सकता हूं:

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
mem_serial_in (p=<value optimized out>, offset=5) at drivers/serial/8250.c:405
405  }

हालांकि अगर मैं -s ध्वज निकालता हूं और /dev/ttyS0 पर कर्नेल में तोड़ने की कोशिश करता हूं तो यह मुझे अनुमति अस्वीकृत त्रुटि देता है:

(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
permission denied 

क्या ऐसा इसलिए है क्योंकि यह क्यूमु द्वारा आयोजित किया गया है? इसके अतिरिक्त उदाहरण के तौर पर इंटरनेट पर, केजीडीबीओसी को टीटीएएमए 0 पर सेट कर दिया गया है जिसे मैं AMBA बस के लिए समझा रहा हूं जो कि एआरएम आधारित सिस्टम के लिए विशिष्ट है क्या हमारे पास PowerPC के लिए कुछ समान है? क्या मुझसे यहां कुछ गलत हो रहा है?


केजीडीबी + QEMU चरण-दर-चरण

सबसे पहले, QEMU का -gdb विकल्प -gdb की -gdb में सख्ती से अधिक शक्तिशाली है, इसलिए आप इसके बजाय इसका उपयोग करना चाहेंगे: GDB और QEMU के साथ लिनक्स कर्नेल को डिबग कैसे करें? हालांकि, वास्तविक हार्डवेयर की तैयारी में केजीएमडी के साथ खेलने के लिए क्यूईएमयू एक आसान तरीका है। मैंने कुछ रास्पबेरी पी केजीडीबी पॉइंटर्स पोस्ट किया है: लिनक्स कर्नेल लाइव डीबगिंग, इसे कैसे किया जाता है और कौन से टूल उपयोग किए जाते हैं?

यदि आप स्क्रैच से जल्दी से शुरू करना चाहते हैं, तो मैंने कम से कम पूरी तरह से स्वचालित Buildroot उदाहरण बनाया है: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/d424380fe62351358d21406280bc7588d795209c#kgdb

मुख्य कदम हैं:

  1. इसके साथ कर्नेल संकलित करें:

    CONFIG_DEBUG_KERNEL=y
    CONFIG_DEBUG_INFO=y
    
    CONFIG_CONSOLE_POLL=y
    CONFIG_KDB_CONTINUE_CATASTROPHIC=0
    CONFIG_KDB_DEFAULT_ENABLE=0x1
    CONFIG_KDB_KEYBOARD=y
    CONFIG_KGDB=y
    CONFIG_KGDB_KDB=y
    CONFIG_KGDB_LOW_LEVEL_TRAP=y
    CONFIG_KGDB_SERIAL_CONSOLE=y
    CONFIG_KGDB_TESTS=y
    CONFIG_KGDB_TESTS_ON_BOOT=n
    CONFIG_MAGIC_SYSRQ=y
    CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
    CONFIG_SERIAL_KGDB_NMI=n
    

    उनमें से अधिकतर अनिवार्य नहीं हैं, लेकिन यह है कि मैंने क्या परीक्षण किया है।

  2. अपने QEMU कमांड में जोड़ें:

    -append 'kgdbwait kgdboc=ttyS0,115200' \
    -serial tcp::1234,server,nowait
    
  3. जीडीबी को लिनक्स कर्नेल स्रोत पेड़ की जड़ से चलाएँ:

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
    
  4. जीडीबी में:

    (gdb) c
    

    और बूट समाप्त होना चाहिए।

  5. QEMU में:

    echo g > /proc/sysrq-trigger
    

    और जीडीबी को तोड़ना चाहिए।

  6. अब हम कर चुके हैं, आप सामान्य रूप में जीडीबी का उपयोग कर सकते हैं:

    b sys_write
    c
    

उबुंटू में परीक्षण 14.04

एआरएम

यह काम नहीं कर सकता संभवतः से संबंधित: एआरएम पर किग्रा बीबी का उपयोग कैसे करें ??


आप मेजबान सीरियल डिवाइस / dev / ttyS0 को अतिथि के लिए भ्रमित करते हैं, और गेस्ट कर्नेल में केजीआईडीबी के लिए QEMU के स्वयं के gdbserver हैं।

आमतौर पर मेजबान के सीरियल पोर्ट को स्पर्श करने के लिए QEMU के लिए कोई कारण नहीं है। वास्तव में ऐसा करने का एकमात्र कारण होगा यदि आप एक भौतिक मशीन मेजबान QEMU करना चाहते हैं, और प्रभावी रूप से अतिथि को भौतिक धारावाहिक पोर्ट दे, ताकि आप एक अलग भौतिक मशीन का उपयोग वास्तविक धारावाहिक केबल से डिबग करने के लिए कर सकें अतिथि।

जब आप -s फ्लैग का उपयोग करते हैं, तो आप QEMU को अपने स्वयं के जीडीबी सर्वर (होस्ट लूपबैक टीसीपी पोर्ट 1234 पर सुनकर डिफ़ॉल्ट रूप से सुनकर) को चलाने के लिए कह सकते हैं जो अतिथि को प्रोग्राम में तोड़ने की इजाजत देते हैं, जो कि एक कर्नेल या बूटलोडर या कुछ और । यह ऐसा नहीं है कि अतिथि कर्नेल स्वयं केजीडीबी के माध्यम से डीबगिंग के साथ सहयोग करता है।

यदि आप केजीडीबी का उपयोग करना चाहते हैं, तो आपको ऐसा करने के लिए कर्नेल के निर्माण में केजीडीबी को विन्यस्त करना होगा ताकि एक अनुरुप सीरियल पोर्ट के अतिथि पक्ष का उपयोग किया जा सके, और उसके बाद मेजबान पर जीडीबी को उस एमुलेट पोर्ट के मेजबान अंत का उपयोग करने के लिए कहें। QEMU कमांड लाइन documenation विस्तार से इस कवर:

डीबग / विशेषज्ञ विकल्प:

'-sariial dev' वर्चुअल सीरियल पोर्ट को वर्ण डिवाइस देव होस्ट करने के लिए रीडायरेक्ट करें डिफ़ॉल्ट उपकरण ग्राफ़िकल मोड में vc और गैर ग्राफिकल मोड में stdio है।

यह विकल्प 4 सीरियल पोर्ट तक अनुकरण करने के लिए कई बार इस्तेमाल किया जा सकता है।

आपके कुछ और दिलचस्प विकल्पों की एक संक्षिप्त सूची:

'पीटी' [लिनक्स केवल] छद्म टीटीआई (एक नया पीटीआई स्वचालित रूप से आवंटित किया गया है)

'/ dev / XXX' [केवल लिनक्स] होस्ट टीटीआई का प्रयोग करें, जैसे '/ dev / ttyS0' मेजबान सीरियल पोर्ट मापदंडों की गणना अनुकरण वाले लोगों के अनुसार की जाती है।

यह वही है जिसे आप नहीं चाहते हैं - जब तक कि आप किसी सीरियल केबल का उपयोग एक अलग भौतिक मशीन के लिए करना चाहते हैं जो जीडीबी चलाएगा।

'टीसीपी: [होस्ट]: पोर्ट [, सर्वर] [, अब) [[, नोडलाय]' टीसीपी नेट कंसोल के दो मोड ऑपरेशन हैं यह सीरियल I / O को किसी स्थान पर भेज सकता है या किसी स्थान से कनेक्शन की प्रतीक्षा कर सकता है। डिफ़ॉल्ट रूप से पोर्ट पर होस्ट करने के लिए टीसीपी नेट कंसोल भेजा जाता है। यदि आप सर्वर विकल्प का उपयोग करते हैं, तो QEMU क्लाइंट सॉकेट एप्लिकेशन के लिए पोर्ट से कनेक्ट करने के लिए इंतजार करेगा, जब तक कि अब विकल्प विकल्प निर्दिष्ट नहीं किया गया था। नोडले विकल्प नेल्ले बफरिंग एल्गोरिथम को अक्षम करता है। यदि मेजबान छोड़ा गया है, 0.0.0.0 माना जाता है। एक समय में केवल एक टीसीपी कनेक्शन स्वीकार किया जाता है। आप संबंधित चरित्र डिवाइस से कनेक्ट करने के लिए टेलनेट का उपयोग कर सकते हैं।

टीसीपी कंसोल को 1 9 2.168.0.2 पोर्ट 4444 -एसिरियल टीसीपी भेजने के लिए उदाहरण: 1 9 2.168.0.2: 4444

कनेक्शन के लिए बंदरगाह 4444 पर सुनने और प्रतीक्षा करने के लिए उदाहरण -एसिरियल tcp :: 4444, सर्वर

आईपी ​​192.168.0.100 पोर्ट 4444 -सिरीयल टीसीपी: 192.168.0.100: 4444, सर्वर, अब प्रतीक्षा

यह एक अच्छा और आम पसंद है आप मूल रूप से एक ही जीडीबी वाक्यविन्यास का उपयोग कर सकते हैं, उदाहरण के लिए यदि आप लूपबैक इंटरफ़ेस पता 127.0.0.1 और पोर्ट 1234 निर्दिष्ट करते हैं तो आप पहले से ही उसी जीडीबी कमांड का उपयोग कर सकते हैं।

'यूनिक्स: पथ [, सर्वर] [, आता है]' एक यूनिक्स डोमेन सॉकेट का इस्तेमाल टीसीपी सॉकेट के बजाय किया जाता है विकल्प समान रूप से कार्य करता है जैसे कि> निर्दिष्ट किया गया था - कनेक्शन के लिए यूनिक्स डोमेन सॉकेट पथ को छोड़कर -सिरियल टीसीपी का उपयोग किया जाता है

यह भी एक अच्छा विकल्प है, यह सोचकर कि आपका जीडीबी इसका समर्थन करता है।

इन विकल्पों में से एक को कॉन्फ़िगर करने की आवश्यकता हो सकती है, केजीडीबी के बिना चलाने के लिए और एक खोल खोलें और पता करें कि एमुलेटेड डिवाइस के अतिथि अंत क्या है, फिर उस के इस्तेमाल के लिए कॉन्फ़िगर किए गए केजीडीबी के साथ रीबूट करें।







powerpc