
هندسة عكسية لـ TI AM3358 boot ROM
ربما مرّت ثمانية عشر شهرًا منذ أن حصلت لأول مرة على بضع لوحات Beaglebone Black، كانت قد أُنقذت من حاوية النفايات. لسوء الحظ، لم تعمل اللوحات مباشرة. الآن، كانت هذه أول تجربة لي مع واحدة من هذه اللوحات، أو أي حاسوب أحادي اللوحة في هذا الشأن، لذلك لم أكن متأكدًا مما إذا كانت المشكلة شيئًا أفعله أنا، أم شيئًا خاطئًا في اللوحات نفسها (ربما لهذا كانت في طريقها إلى حاوية النفايات في المقام الأول). استغرقني وقت طويل جدًا، وجهد كبير، لأجعل هذه اللوحات تبدأ الإقلاع فعلًا، لكن بحق الجحيم، فعلتها. وهذا ما تعلمته على طول الطريق.
لقد أدرجت بعض الأدوات المساعدة في هذا المستودع، بالإضافة إلى ملف xml مُصدَّر من Ghidra يحتوي على جميع الرموز التي حصلت عليها حتى الآن من الهندسة العكسية. استخدمت هذا المنشور للتصدير دون البرنامج الثابت الفعلي، لتجنب أي مشاكل حقوق نشر، فقط في حالة. إذا كنت تريد تصحيح أخطاء boot ROM بنفسك، فسيكون لديك بالفعل JTAG موصولًا، لذا يمكنك تفريغ boot ROM (من 0x20000 إلى 0x2BFFF) بنفسك.
لتحميل الرموز:
0x20000 تحت Options، ويمكنك ضبط اسم الكتلة إلى bootrom.main()، أو معالج إقلاع بطاقة MMC/SD.في البداية، كنت أعرف أن هذه إصدارات مخصصة من beaglebone black القياسي، لذلك قررت مبكرًا أنه قد يكون هناك شيء مفقود على اللوحة نفسها، مثل معرّف اللوحة. ما رأيته عند الإقلاع من بطاقة SD قياسية منسّقة باستخدام balenaEtcher، كان لا شيء. توقعت أن تبدأ مصابيح LED على اللوحة في الوميض، وتوقعت أن توصيل كابل UART إلى USB سيتيح لي رؤية عملية U-Boot. ومع ذلك، كان UART صامتًا. إذا أزلت بطاقة SD، فإنه يُخرج الحرف C مرارًا وتكرارًا، وهو سلوك متوقع لإقلاع UART/تسلسلي. كان بالتأكيد يحاول الإقلاع، وكانت بطاقة SD تغيّر هذا السلوك، لكن لم يكن لدي أي رؤية إضافية. معظم استكشاف الأخطاء على الويب يعتمد على مخرجات U-Boot كنقطة بداية لتشخيص المشكلات. أظن أنني لن أحظى بذلك الرفاهية.
رأيت في هذه المرحلة أنه سيكون من المفيد توصيل مسبار تصحيح أخطاء. لسوء الحظ، لم يكن لدي موصل رأس مطابق للبصمة الموجودة، لذا صنعت واحدًا بنفسي.
لوحة beaglebone تحتوي على موصل رأس بتسمية P2 والذي يوصل توصيلات JTAG. وصلت بعض الأسلاك من هذا إلى موصل رأس أنثوي حتى أتمكن من التواصل معه عبر J-Link الخاص بي.



عند التشغيل في Ozone (مصحح Segger) قمت بتهيئة J-Link وبدأت بمجرد محاولة العثور على نقطة الدخول. ظننت أن reset-halt سيضعني حيث أحتاج، وهكذا توصلت إلى الافتراض (الخاطئ) بأن نقطة الدخول هي 0x2148a، على الرغم من أنني لاحظت بالتأكيد أن هذا لم يكن ثابتًا. لاحقًا، أدركت أن لوحات AM335x لا تتوافق جيدًا مع reset-halt في J-Link، لذلك كان هناك في الواقع تأخير ربما بضع مئات من دورات الساعة، مما أوصلني إلى مكان ما داخل معالج إقلاع، بشكل غير حتمي. (تجاوزت هذا في النهاية بكتابة ملف GEL لـ TI's Code Composer Studio الذي يدعم تصحيح أخطاء J-Link - عند إعادة الضبط، يتم تعيين سجل PC إلى معالج إعادة الضبط، وتُمسح السجلات، ويُجبر وضع التعليمات على ARM.)
من موضوع في منتديات TI (AM335x: TI employees, where can I get the ROM Bootloader source code/symbols?) حصلت على رمزي تصحيح أخطاء: SPI Initialize عند 0x231e0، وSPI ReadSectors عند 0x23230، و0x24bfa هو روتين يقوم بقراءة UART. هذا قدر لا بأس به من المساعدة على ما أظن. لاحظت أن الإقلاع فشل بالوصول إلى حلقة لا نهائية عند 0x402f0440، وهي حلقة ميتة. همم، بعيدة جدًا عن بقية boot ROM، يجب أن تكون في RAM أو شيء من هذا القبيل. ربما حان الوقت للانتقال إلى دليل المرجع التقني (TRM)!
يحتوي الفصل 26 من TRM على كمية هائلة من المعلومات حول الإقلاع. نحصل على العرض التالي لـ boot ROM:

الوصف:
تُظهر البنية المعمارية لـ Public ROM Code في الشكل 26-1. وهي مقسمة إلى ثلاث طبقات رئيسية بنهج من الأعلى إلى الأسفل: المستوى العالي، وبرامج التشغيل، وطبقة تجريد العتاد (HAL). تتواصل إحدى الطبقات مع طبقة مستوى أدنى من خلال واجهة موحدة. الطبقة عالية المستوى مسؤولة عن المهام الرئيسية لـ Public ROM Code: تهيئة الـ watchdog والساعات وروتين الإقلاع الرئيسي. تنفذ طبقة برامج التشغيل البروتوكولات المنطقية والاتصالية لأي جهاز إقلاع وفقًا لمواصفات الواجهة. أخيرًا، تنفذ HAL الكود منخفض المستوى للتفاعل مع بنى IP الخاصة ببنية العتاد. الأجهزة الطرفية للإقلاع النهائية موصولة بمنصات إدخال/إخراج الجهاز.

يوضح الشكل 26-2 التدفق عالي المستوى لإجراء إقلاع Public ROM Code. على هذا الجهاز، يبدأ Public ROM Code عند اكتمال بدء التشغيل الآمن (المنفذ بواسطة Secure ROM Code). ثم يقوم ROM Code بتهيئة النظام الأساسي وإعداده كجزء من إجراء البدء العام. يتم إنشاء قائمة أجهزة الإقلاع بناءً على دبابيس SYSBOOT. يمكن أن يكون جهاز الإقلاع جهاز إقلاع ذاكرة (ذاكرة فلاش ملحومة أو جهاز إقلاع مؤقت مثل بطاقة الذاكرة) أو واجهة طرفية متصلة بمضيف. تمر الحلقة الرئيسية لإجراء الإقلاع عبر قائمة أجهزة الإقلاع وتحاول البحث عن صورة من جهاز الإقلاع المحدد حاليًا. يتم الخروج من هذه الحلقة إذا تم العثور على صورة إقلاع صالحة وتنفيذها بنجاح أو عند انتهاء مهلة الـ watchdog. يتم تنفيذ إجراء مصادقة الصورة قبل تنفيذ الصورة على جهاز HS. يؤدي الفشل في إجراء المصادقة إلى التفرع إلى "حلقة ميتة" في Secure ROM (بانتظار إعادة ضبط الـ watchdog).
خريطة الذاكرة! متجهات الاستثناءات! مخططات التدفق! الكثير من المعلومات في هذا القسم. أصبحت مهمتي أسهل كثيرًا.
في هذه المرحلة استخدمت مسبار JTAG لتنزيل البرنامج الثابت إلى ملفين مختلفين، وبدأت في تحميل الأشياء إلى Ghidra. لم تكن هناك أي ملفات SVD أو تعيينات سجلات أخرى متاحة بتنسيق مناسب، وهو أمر مؤسف حقًا، لأن ذلك يعني أنني بحاجة إلى تعريف مناطق الذاكرة والسجلات وكل شيء يدويًا. كانت هذه عملية مضنية، لكن بعد فترة أصبح لدي سكربت بايثون يمكنني استخدامه لتحميل الرموز إلى Ghidra لـ AM3358. أمر أقل للقلق بشأنه!
يبدو أن الملفات التي لدي يمكن تعيينها على النحو التالي:
| Region | Start Address | Length |
|---|---|---|
| Boot ROM (Public) | 0x4002_0000 | 0xBFFF |
| Boot ROM (Public, alias) | 0x0002_0000 | 0xBFFF |
| SRAM Internal | 0x402F_0400 | 0xFC00 |
| L3 OCM0 | 0x4030_0000 | 0x10000 |
من المثير للاهتمام أن الحلقة اللانهائية عند 0x402f_0440 تقع في أعلى "الصورة التي تم تنزيلها" في SRAM الداخلية، بينما تُخزَّن متجهات الاستثناءات في مكان آخر. ربما سيكون هذا تلميحًا مهمًا لاحقًا...
عند إعادة الضبط، يتولى boot ROM الخاص التعامل مع أمور الأمان، ويتفرع إلى 0x2 0000 الذي يحتوي على متجهات إعادة الضبط. أول تعليمة هي فرع إلى 0x2 08d0 والتي يجب أن تكون نقطة الدخول. إنها ليست تعليمة BX لذا، على الأرجح، ما زلنا في وضع ARM عند تلك النقطة.