بسبب عبء العمل على المتخصصين ، فقد اضطررنا منذ عدة سنوات إلى إعطاء تطور واحد للأطراف المقابلة. تم إجراء التطوير على وحدة Enclustra Mars ZX3 ، والتي تستخدم SOC ARM + FPGA Zynq-7020. لبناء Linux ، استخدمنا Bcl من Enclustra (bsp-xilinx) ، والذي تم تعديله قليلاً.
في عملية اختبار البرنامج المطوَّر ، واجهنا على الفور إخفاقات البرامج عند إيقاف تشغيل الطاقة. أثناء التحليل ، وجد أن أوامر التكوين المرسلة إلى الجهاز عبر الشبكة قد تمت كتابتها إلى ملفات ، والتي عندما حدث انقطاع التيار الكهربائي ، كانت أحيانًا فارغة أو غائبة تمامًا. لقد أجبرنا ذلك على إعادة النظر في أيديولوجية بناء مجموعة Linux التي تم تسليمها إلينا. تم وصف عملية بناء النظام نفسه جيدًا على
موقع الشركة المصنعة للوحدة النمطية ، لذلك لن أتطرق إليها. سوف أصف فقط ما سمح لنا بحل المهمة أمامنا المتمثلة في زيادة الموثوقية ومنع الفشل.
تحتوي وحدة Mars ZX3 على رقائق QSPI Flash و NAND Flash. في حالتنا ، يتم تحميل الوحدة النمطية مع QSPI Flash ، حيث تمت كتابة U-Boot. نظرًا لأن كلتا الرقاقتين تستخدمان نفس دبابيس Zynq-7020 ، بعد تحميل U-Boot ، يتم تبديل المسامير إلى NAND Flash ، حيث تتم كتابة أقسام التمهيد ، شجرة الجهاز ، و Linux kernel ، ونظام ملفات ubifs ، ومتغيرات البيئة في أقسام منفصلة. علاوة على ذلك ، تم حجز جميع الأقسام ، باستثناء القسم ذي متغيرات البيئة (أي ، كان هناك قسمان من هذا القبيل). فيما يلي جزء من ملف Device Tree ، والذي يوضح كيفية كسر NAND Flash في الإصدار الذي أرسله إلينا المقاولون:
partition@nand-linux { label = "nand-linux"; reg = <0x0 0x500000>; }; partition@nand-device-tree { label = "nand-device-tree"; reg = <0x500000 0x100000>; }; partition@nand-bootscript { label = "nand-bootscript"; reg = <0x600000 0x100000>; }; partition@nand-linux-second { label = "nand-linux-second"; reg = <0x700000 0x500000>; }; partition@nand-device-tree-second { label = "nand-device-tree"; reg = <0xC00000 0x100000>; }; partition@nand-bootscript-second { label = "nand-bootscript"; reg = <0xD00000 0x100000>; }; partition@nand-rootfs { label = "nand-rootfs"; reg = <0xE00000 0xF500000>; }; partition@nand-rootfs-second { label = "nand-rootfs"; reg = <0x10300000 0xF500000>; }; partition@boot-env { label = "nand-env"; reg = <0x1F800000 0x100000>; };
كان من المفترض استخدام القسم الثاني عند فشل الأقسام الرئيسية. للقيام بذلك ، كان على Linux تنفيذ عملية تراقب تكامل النظام ، وفي حالة حدوث عطل ، تكتب قيمة لمتغير البيئة الذي يرشدك لبدء تشغيل النظام من أقسام النسخ الاحتياطي. كان من المفترض أن يتم تنفيذ هذه الخوارزمية في المستقبل.
تم تسجيل بيانات التكوين في مجلدين للنسخ الاحتياطي ، ولكن هذا لم يحفظ الموقف. من المفترض أنه في حالة عدم وجود ملفات التكوين ، يتم إنشاؤها مرة أخرى تلقائيًا ، مع الإعدادات الافتراضية.
المشكلة هي أن NAND Flash يكتب البيانات صفحة واحدة في كل مرة ، ومحو يحدث في كتل. وبالتالي ، في حالة حدوث انقطاع في الطاقة أثناء تسجيل البيانات ، لن تتلف هذه البيانات فقط ، ولكن قد يتلف نظام الملفات. يمكن أن يؤدي بدء تشغيل نظام النسخ الاحتياطي إلى تأخير حدوث مشكلة فقط. على الرغم من أنه في هذه الحالة ، يمكن تحقيق استعادة الأقسام الرئيسية من الأقسام الاحتياطية.
قررنا المضي قدمًا في الاتجاه الآخر ، وتثبيت rootfs كنظام ملفات للقراءة فقط ، وكتابة ملفات التكوين لفصل أقسام
البيانات والنسخ الاحتياطي التي تم تركيبها للقراءة والكتابة. في هذه الحالة ، تختفي الحاجة إلى أقسام النسخ الاحتياطي ، لكننا تركناها للمستقبل ، لأن مقدار الذاكرة سمح لنا بذلك. إذا لزم الأمر ، يمكن حذفها.
نتيجة لذلك ، تم تقسيم NAND Flash التالي:
partition@nand-linux { label = "nand-linux"; reg = <0x0 0x500000>; }; partition@nand-device-tree { label = "nand-device-tree"; reg = <0x500000 0x100000>; }; partition@nand-bootscript { label = "nand-bootscript"; reg = <0x600000 0x100000>; }; partition@nand-linux-second { label = "nand-linux-second"; reg = <0x700000 0x500000>; }; partition@nand-device-tree-second { label = "nand-device-tree"; reg = <0xC00000 0x100000>; }; partition@nand-bootscript-second { label = "nand-bootscript"; reg = <0xD00000 0x100000>; }; partition@nand-rootfs { label = "nand-rootfs"; reg = <0xE00000 0x9600000>; }; partition@nand-rootfs-second { label = "nand-rootfs"; reg = <0xA400000 0x9600000>; }; partition@nand-data { label = "nand-data"; reg = <0x13A00000 0x5F00000>; }; partition@nand-data-backup { label = "nand-data-backup"; reg = <0x19900000 0x5F00000>; }; partition@boot-env { label = "nand-env"; reg = <0x1F800000 0x100000>; };
عند وميض NAND Flash باستخدام أمر U-Boot ، نقوم بمسح مقاطع
بيانات nand و
nand-backup :
u-boot>nand erase.part nand-data u-boot>nand erase.part nand-data-backup
في البرنامج النصي لنظام التشغيل Linux ، قمنا بتركيب نظام الملفات الجذر باعتباره للقراءة فقط ، مع استبدال السطر الموجود في الملف / etc / inittab في مجموعة Linux:
::sysinit:/bin/mount -o remount,rw /
في
::sysinit:/bin/mount -o remount,ro /
أضفنا سكريبت تمهيد إلى المجلد
/etc/init.d/ ، الذي يحمّل أقسام
nand-data و
nand-backup في القراءة والكتابة. في حالة حدوث خطأ في التركيب (أثناء التمهيد الأول أو في حالة تلف نظام الملفات) ، يتم تنسيق هذه الأقسام وإعادة تركيبها. يجب إنشاء المجلدات
/ mnt / data / و
/ mnt / backup / مسبقًا في نظام الملفات الجذر.
عند التنزيل ، إذا كانت ملفات التكوين في المجلد
/ mnt / data / مفقودة ، فيتم تنزيلها من المجلد
/ mnt / backup / . في حالة عدم وجود ملفات تهيئة في
/ mnt / backup / ، يتم إنشاؤها تلقائيًا من البرنامج مع المعلمات الافتراضية. إذا كانت الملفات موجودة في
/ mnt / data / ولكن غير موجودة في
/ mnt / backup / ، يتم نسخها من
/ mnt / data / إلى
/ mnt / backup / . يتم تنفيذ جميع هذه العمليات بواسطة برنامج المستخدم.
في المرحلة التالية ، لزيادة الموثوقية ، رفضنا كتابة التكوين إلى ملف لكل أمر. يتم تخزين التكوين بأكمله الآن في ذاكرة الوصول العشوائي ، وإذا لزم الأمر ، يمكن حفظه بواسطة أمر منفصل في ملفات في
/ mnt / data / و
/ mnt / backup / مجلدات.
إذا كنت بحاجة إلى إجراء تغييرات على نظام الملفات الجذر أثناء العمل دون إعادة تحميل الجهاز ، فيمكنك إعادة تحميل النظام من وحدة التحكم للقراءة والكتابة باستخدام الأمر
mount -o remount,rw /
قم بإجراء تغييرات ثم قم بإعادة التحميل في للقراءة فقط:
mount -o remount,ro /