अत्यधिक Pi बूट ऑप्टिमाइज़ेशन
(kittenlabs.de)- SolarCamPi एक off-grid solar camera है जो केवल फोटो लेते समय Raspberry Pi Zero 2 W को चालू करता है और फिर बंद कर देता है, इसलिए बूट समय सीधे बैटरी लाइफ को प्रभावित करता है
- Debian 12 arm64 Lite पर
/init.shको पहले user-space code के रूप में मापने पर, शुरुआती बूट में लगभग 12 सेकंड और 9.5Ws ऊर्जा लगती है - HDMI, LED, HAT/PoE/LCD, कैमरा·डिस्प्ले auto-detect, और initramfs को कम करके अनावश्यक इंतज़ार और detection हटाए गए, और करंट 136.7mA → 120.6mA तक घट गया
- Buildroot 2024.02.1 और custom kernel पर जाने के बाद driver, compression, KASLR, और कुछ mitigation फीचर हटाकर 3.5 सेकंड से कम में Linux user-space प्रोग्राम तक पहुँचा गया
- input voltage को 5.0V से 3.6V तक घटाने पर कुल ऊर्जा 1.754Ws → 1.438Ws तक कम हुई, लेकिन यह spec के बाहर का operation है, इसलिए stability और reliability की जाँच अभी बाकी है
SolarCamPi को बूट समय कम करने की ज़रूरत क्यों थी
- SolarCamPi एक solar-powered WiFi camera है, जो Raspberry Pi Zero 2 W को समय-समय पर बूट करके फोटो लेता है, WiFi के ज़रिए उन्हें cloud service पर अपलोड करता है, और फिर बंद हो जाता है
- पश्चिमी यूरोप की सर्दियों जैसी कम-ऊर्जा परिस्थितियों में, Pi के चालू रहने का हर सेकंड सीधे ऊर्जा लागत बन जाता है
- user-space application का server connection और photo upload पहले से ही यथासंभव optimized था, और sleep के दौरान power कम रखने के लिए electronic circuit भी उसी हिसाब से डिज़ाइन किया गया था
- बची हुई बचत के दो रास्ते थे
- current consumption कम करना
- execution time कम करना
- सिर्फ करंट कम करना हमेशा फ़ायदेमंद नहीं होता
- अगर CPU turbo बंद करने से करंट घटे लेकिन execution time बढ़ जाए, तो कुल ऊर्जा उल्टा बढ़ सकती है
- लक्ष्य current और time के ग्राफ़ के नीचे का area न्यूनतम करना है
मापन उपकरण और टेस्ट तरीका
- embedded boot optimization में बदलाव के बाद असली execution को जल्दी verify करना ज़रूरी होता है, इसलिए SD card निकालने-लगाने और power control के काम को कम करने वाले टूल महत्वपूर्ण हैं
- इस्तेमाल किए गए उपकरण ये थे
- Nordic Power Profiler Kit II
- USB-SD-Mux Fast
- USB-UART converter
- Power Profiler Kit II टेस्ट डिवाइस को power देते हुए समय के साथ power consumption और 8 digital input की स्थिति साथ में मापता है
- Raspberry Pi के GPIO pin को digital input से जोड़ा गया
- application की पहली action के रूप में GPIO toggle करके power-on से user-space code चलने तक का समय मापा गया
- USB-SD-Mux एक interposer है जो microSD card और डिवाइस के बीच लगता है, ताकि कंप्यूटर card को अपने पास लेकर उसका data दोबारा लिख सके और फिर डिवाइस को वापस दे सके
- इससे card निकालकर reader में लगाना और फिर डिवाइस में वापस डालना वाला दोहराव खत्म हो गया
- onboard GPIO से टेस्ट डिवाइस का reset या power control भी automate किया जा सकता है
- USB-UART console बूट failure या WiFi समस्या जैसी स्थितियों में सिस्टम टूटने पर उसकी स्थिति देखने के लिए ज़रूरी है
Debian पर बूट मापन
- साफ़ Debian 12 bookworm arm64 Lite image में
/boot/firmware/cmdline.txtमेंinit=/init.shजोड़ा गया - यह सेटिंग kernel को systemd से पहले
/init.shको user space की पहली process के रूप में चलाने देती है - उदाहरण
init.shGPIO4 को toggle करने के बादexec /sbin/initसे systemd boot को आगे बढ़ाता है - शुरुआती मापन में लगभग 12 सेकंड बाद digital input 0 low हुआ, जिससे
init.shचलना confirmed हुआ - इस boot process ने कुल 1.90 coulomb इस्तेमाल किया
1.9As * 5.0V = 9.5Ws- एक AA alkaline battery लगभग 13500Ws ऊर्जा दे सकती है
current consumption कम करना
- HDMI encoder को पूरी तरह disable करने पर करंट 136.7mA से 122.6mA तक घट गया
- कैमरा data को encode करना ज़रूरी था, इसलिए GPU को पूरी तरह बंद नहीं किया जा सका
- अगर application को कैमरा या GPU की ज़रूरत न हो, तो GPU disable करना भी आज़माया जा सकता है
- सिर्फ activity LED disable करने से 2mA की बचत हुई और करंट 122.6mA से 120.6mA तक आ गया
- अगर camera LED हो तो उसे भी disable किया जा सकता है
- इससे LED के image में reflect होने की संभावना भी कम होती है
- turbo setting बदलने के टेस्ट में मौजूदा modified Pi ने 1.62As इस्तेमाल किया
- force turbo के बिना चलाने पर 1.58As इस्तेमाल हुआ
- अज्ञात कारण से turbo/boost mode बंद करने पर GPIO4 की default state उलट गई, इसलिए
init.shमें polarity बदलनी पड़ी
बूट समय कम करना
- करंट लगभग 13% घट गया था, लेकिन Linux का पहला output console पर आने से पहले अब भी लगभग 8 सेकंड लग रहे थे, और इस दौरान लगभग 1As खर्च हो रहा था
- Raspberry Pi परिवार में पहले GPU initialize होता है
- GPU SD card पर
bootcode.binखोजता है - Pi 4 और उसके बाद के मॉडल EEPROM इस्तेमाल करते हैं
- GPU SD card पर
bootcode.binमेंBOOT_UARTचालू करने पर विस्तृत UART log देखा जा सकता है- मूल
bootcode.binका backup ज़रूरी है, और यह बदलाव संभावित रूप से नुकसानदेह हो सकता है
- मूल
- bootloader जुड़े हुए HDMI monitor के video parameter auto-detect करने के लिए EDID response का इंतज़ार करता है
- HDMI का उपयोग नहीं था, इसलिए detection से बचने के लिए EDID string को hardcode किया गया
- HAT, PoE fan, LCD, और touchscreen से जुड़े I2C EEPROM detection भी disable किए गए
- ये options I2C bus response का इंतज़ार करते हैं, इसलिए ज़रूरत न हो तो इन्हें बंद किया जा सकता है
- MIPI camera और display auto-detect भी समय लेते हैं
- इस्तेमाल किया गया कैमरा HQ Camera IMX477 तय था, इसलिए
camera_auto_detect=0,display_auto_detect=0से इन्हें बंद करकेdtoverlay=imx477सीधे लोड किया गया
- इस्तेमाल किया गया कैमरा HQ Camera IMX477 तय था, इसलिए
- इन बदलावों से self-reported boot time 5.38 सेकंड से 4.75 सेकंड हुआ, और
auto_initramfs=1हटाकर initramfs बंद करने पर यह 4.47 सेकंड तक आ गया - SD peripheral को 100MHz पर overclock करने वाली
sdtweakतकनीक मापने लायक boot performance फ़र्क नहीं ला सकी- write access के दौरान data corruption का जोखिम है, इसलिए remote IoT device के लिए यह उचित नहीं है
kernel loading bottleneck और Buildroot पर स्विच
- इस बिंदु पर kernel loading सबसे धीमे कामों में से एक थी
kernel8.imgके 9,276,375 byte लोड होने में लगभग 1.54 सेकंड लगे- transfer speed लगभग 6MiB/s थी
- kernel loading GPU द्वारा की जाती है, जो अंदरूनी proprietary VideoCore IV processor इस्तेमाल करता है
- संभव है loader code अक्षम हो या conservative setting इस्तेमाल करता हो, लेकिन यह black box होने के कारण register या parameter को उपयोगी रूप से tune नहीं किया जा सका
- GPU processor core overclock सिद्धांततः संभव था और kernel load time को 20% तक घटाता था
- reliability जैसे side effect अज्ञात होने के कारण इसकी सिफारिश नहीं की गई
- सिस्टम को Raspbian/Debian से Buildroot 2024.02.1 आधारित custom distribution पर शिफ्ट किया गया
- native aarch64 toolchain का उपयोग किया गया
- glibc और Raspberry Pi userland tools को बनाए रखा गया
- custom kernel में ये चीज़ें हटाई या कम की गईं
- sound support
- ज़्यादातर block device और filesystem driver, सिर्फ SD/MMC और ext4 रखे गए
- RAID, USB, HID, DVB
- video और framebuffer support
- tunnel, bridging, firewall जैसी advanced networking features
- Gzip kernel compression और module compression
- kernel और module दोनों को uncompressed रखने का तरीका, GPU के ज़्यादा देर तक loading करने के बावजूद, कुल ऊर्जा के हिसाब से फ़ायदेमंद रहा
- Gzip decompression बहुत ऊर्जा लेती है और व्यवहार में एक अतिरिक्त relocation step जैसी बन जाती है
- KASLR भी disable किया गया
- KASLR kernel memory load address को randomize करके exploit लिखना कठिन बनाता है, लेकिन GPU loading के बाद kernel relocation की ज़रूरत पड़ती है
- इस use case में network attack surface बहुत सीमित था और application software पूरा का पूरा root के रूप में चलता था
- Spectre जैसी speculative execution vulnerability mitigation भी disable की गईं
- नतीजे में kernel size 8.5MiB uncompressed था, और तुलना के लिए Gzip compressed size 4.1MiB थी
- मूल Raspbian kernel 25MiB uncompressed और 8.9MiB Gzip compressed था
अंतिम परिणाम और input voltage optimization
- अंततः Linux user-space प्रोग्राम तक 3.5 सेकंड से कम में पहुँचा गया
- Linux kernel के अंदर लगा समय लगभग 400ms था
- कुल ऊर्जा खपत 0.364As * 5.0V = 1.82Ws रही
- stock Debian में user-space तक पहुँचने वाली 9.5Ws ऊर्जा की तुलना में यह लगभग पाँचवाँ हिस्सा है
- पोस्ट प्रकाशित होने के बाद Graham Sutherland / Polynomial ने बताया कि Pi Zero का regulator 5.0V input पर दक्ष नहीं है
- टेस्ट scenario और तैयार प्रोडक्ट में input voltage को 4.0V तक घटाया जा सका
- 5.0V:
350.94mAs * 5.0V = 1.754Ws - 4.0V:
390.77mAs * 4.0V = 1.563Ws - 3.6V:
399.60mAs * 3.6V = 1.438Ws
- 5.0V:
- voltage घटाने पर mC यानी mAs बढ़ता है, क्योंकि करंट बढ़ता है, लेकिन कुल ऊर्जा काफ़ी घट जाती है
- 3.6V operation में switching regulator को अधिक आदर्श operating point पर चलाकर ऊर्जा में अतिरिक्त लगभग 20% कमी मिली, लेकिन तकनीकी रूप से यह spec के बाहर है, इसलिए stability और reliability की और जाँच ज़रूरी है
सार्वजनिक रूप से उपलब्ध सेटिंग्स और कोड
- SolarCamPi config.txt: पूरा
config.txt - SolarCamPi Linux kernel defconfig: कम किया गया kernel config
- SolarCamPi-Buildroot v2 branch: पूरा Buildroot tree, जिस पर काम अभी जारी है
1 टिप्पणियां
Hacker News की राय
Raspberry Pi सीरीज़ का power management वाकई इसकी कमजोरियों में से एक है। इसलिए नए Pico 2 को लेकर उम्मीद है, क्योंकि ऐसा लगता है कि बाहरी hardware के बिना भी अपेक्षाकृत deep sleep state में जाना आसान हो गया है
मैंने इसी तरह के उपयोग के लिए Google Coral mini से एक camera बनाया था। camera HQ cam जितना अच्छा नहीं है, लेकिन built-in RTC की वजह से standby/wake बहुत आसानी से support होता था, इसलिए periodic शूटिंग वाली apps के लिए बिल्कुल सही था। high-resolution images process करने लायक performance और 2GB memory भी थी
HQ camera को physically connect तो किया जा सकता है, लेकिन मेरी जानकारी में Coral पर उसे manage करने वाला कोई software pipeline नहीं है
Raspberry Pi ecosystem कहीं ज्यादा mature है, और Google Coral line की supply जारी रखेगा या नहीं, इसके बजाय मैं Raspberry Pi की future availability पर ज्यादा भरोसा करता हूं। फिर भी hardware में अच्छा power support कितना उपयोगी होता है, यह साफ महसूस हुआ
irony यह है कि camera का अगला version एक external contractor ने Raspberry Pi पर बनाया, और power issue को बहुत बड़ी battery लगाकर compensate किया। नतीजा यह है कि मेरे पास unopened Coral dev mini और 100 cameras पड़े हैं, और अब मुझे या तो कोई अच्छा idea ढूंढना है या उन्हें बेचना है
official Twitter account खोजने के लिए "google coral twitter" search किया तो दूसरा result आपका वही tweet निकला जिसमें आप बचे हुए 100 boards बेचने की कोशिश कर रहे हैं—यह देखकर हैरानी हुई
आपने कहा कि बाहरी hardware से power manage करते हैं, तो लगता है यह सिर्फ software की समस्या नहीं है
application को kernel से linked initramfs में bundle कर दें तो simple cases में filesystem mount की जरूरत नहीं रहती, जिससे काफी कमी लाई जा सकती है
कुछ cases में BusyBox init जैसी चीजों को भी minimal boot करने वाली simple bash script से replace किया जा सकता है। devtmpfs, proc, sysfs वगैरह mount करना, और संभव हो तो glibc को छोड़ना भी consider करने लायक है
initramfs को kernel से bundle करने से पहले chroot में test कर लेना अच्छा है कि जरूरी application dependencies मौजूद हैं या नहीं। अगर वह chroot में चलता है, तो kernel भी boot के दौरान उसे चला सकता है, और development iteration काफी तेज हो जाती है
kernel modules बंद करके सिर्फ जरूरी functions को kernel में link कर दें तो space और boot time और घट सकते हैं। gzip की जगह zstd compression भी test करने लायक है
यह उन cases में होता है जहां शुरुआती boot stages hardware performance का पूरा इस्तेमाल नहीं कर पातीं, या image इतनी बड़ी हो कि loading के parallel में दूसरे काम करना बेहतर हो
तब बस initramfs बचता है जिसमें एक statically linked binary होती है
Pi boot time घटाने पर दो और अच्छे articles हैं
https://www.furkantokac.com/rpi3-fast-boot-less-than-2-secon...
http://himeshp.blogspot.com/2018/08/fast-boot-with-raspberry...
इन दोनों articles को reference बनाकर मैंने Pi से digital photo frame बनाया, और kiosk mode browser तक को बहुत तेजी से boot करा दिया। requirements बहुत कम हों तो काफी impressive boot times मिल सकते हैं
असली त्रासदी यह है कि bootcode.bin GPU code proprietary black box है और उसका source code नहीं है
hacking और hobby projects के लिए ऐसा छिपा हुआ secret black box होना, जिसे modify नहीं किया जा सके, भयानक है
अब यह free open source software है
https://www.theregister.com/2023/11/28/microsoft_opens_sourc...
इसका मतलब यह नहीं कि पूरा Pi firmware अपने-आप free open source हो जाता है। क्योंकि वे drivers नहीं हैं। लेकिन चाहें तो ऐसा किया जा सकता है
अंदर ऐसा क्या है कि उसे बंद रखना पड़ता है, यह जानने की उत्सुकता है
पूरा लेख पसंद आया, लेकिन इस हिस्से को लेकर मुझे यकीन नहीं है
CPU turbo बंद करके करंट खपत थोड़ी बचाना खराब विकल्प है, और धीमा होने की वजह से जल्दी खत्म करके बंद करने की तुलना में ज़्यादा ऊर्जा लगती है—मैं इसी हिस्से की बात कर रहा हूँ
Computer Science क्लास में सीखा था कि power consumption clock frequency के square के अनुपात में होती है। यानी clock को दोगुना करने पर power चार गुना हो जाती है
तो clock बढ़ने से होने वाली quadratic वृद्धि, काम का समय बढ़ने से होने वाली fixed power consumption के गुणनफल से ज़्यादा है या नहीं, यह देखने के लिए असल power अंतर मापना पड़ेगा
इससे जुड़ा, अच्छा होगा अगर Pi CPU datasheet से निकाली जा सकने वाली या register के जरिए real-time expose होने वाली बारीक power consumption जानकारी दे
ज़्यादातर chips को ज़्यादा clock speed तक पहुँचने के लिए ज़्यादा voltage चाहिए होता है, इसलिए वहीं quadratic relation आता है
लेकिन मेरी जानकारी में Raspberry Pi में dynamic voltage control नहीं है, इसलिए voltage घटाए बिना सिर्फ clock घटाने से कुल switching energy consumption पर असर नहीं पड़ेगा
बेशक इसका optimal point भी होता है। CPU को बहुत ज़्यादा overclock कर दें तो performance per watt इतनी गिर जाती है कि race to idle आगे काम नहीं करता
इसलिए modern embedded systems अक्सर "race-to-sleep" या "race-to-halt" strategy इस्तेमाल करते हैं: काम बहुत तेजी से चलाकर, अगले event तक ज़्यादातर components बंद रख देते हैं
अगर कोई computation 1 सेकंड में करने में 1J लगता है, जैसे 1GHz पर 1W, तो perfect spherical cow model में वही computation 0.5 सेकंड में करने के लिए 2J लगेंगे शायद। क्योंकि 2GHz पर 4W हो जाएगा
लेकिन वह सिर्फ CPU consumption देखता है, और अगर पूरे system में 4W की fixed consumption है तो 1GHz पर CPU 1J और system 4J, कुल 5J लगेंगे; 2GHz पर CPU 2J और system 2J, कुल 4J लगेंगे
अगर मैंने सही समझा है, तो मतलब यह है कि अगर पूरे system की power consumption, turbo state में CPU power consumption के बराबर के आसपास हो तो turbo इस्तेमाल करना सही है, वरना नहीं?
प्रभावशाली है। लेकिन ऐसे लेख पढ़ते ही मुझे Pi Zero पर Plan 9 boot record किया हुआ याद आता है: https://taoofmac.com/space/blog/2020/09/02/1900#resurrecting
GIF real-time output है
लेकिन original project के लिए ज़रूरी camera और Wi-Fi drivers load हो पाएँगे या नहीं, यह अलग बात है
व्यक्तिगत रूप से Linux distributions का boot time कुल मिलाकर काफी निराशाजनक लगता है, और ऐसे कमजोर hardware पर यह समस्या बहुत बढ़ जाती है
MQ-Pro SBC पर भी मैंने similar optimization की थी। laptop पर भी यह काफी महसूस होता है। MacBook शायद exception हो, लेकिन जो भी हो, यह annoying है
एक बार on हो जाने के बाद सिर्फ फिर से login करना instant है, लेकिन reboot में काफी समय लगता है
लेकिन distributions, वाजिब वजहों से, बहुत generic kernel और initramfs बनाते हैं, और यह combination खास तेज boot नहीं करता
[0]: https://blog.davidv.dev/posts/minimizing-linux-boot-times/
जब तक कोई भयानक misconfiguration न हो, जैसे NetworkManager किसी non-existent Wi-Fi का 90 सेकंड इंतज़ार करे। मेरे Linux box को graphical.target तक करीब 4 सेकंड लगते हैं, और उसका ज़्यादातर हिस्सा Wi-Fi connection और ntpd की वजह से है, दोनों सिद्धांततः optional हैं
अगर सच में fast boot चाहिए तो bootloader compatibility layers, abstractions, initramfs जैसी dynamic configurability सब छोड़ सकते हैं। लेकिन तब आप hardware vendors पर निर्भर हो जाएँगे, इसलिए यह worth it नहीं है
उदाहरण के लिए Linux वाला MacBook Air 11 login screen तक इतना जल्दी पहुँचता है कि boot logs मुश्किल से दिखते हैं। systemd-analyze के हिसाब से graphical target तक 4 सेकंड से कम
मुख्य बात दो लगती हैं। desktop environment इस्तेमाल नहीं करता, text mode में boot करके जरूरत पड़ने पर startx करता हूँ, या हल्के login manager (lightdm) से X में boot करता हूँ। desktop environment न हो तो services की संख्या single-digit गुना कम हो जाती है, जिससे पुराने hardware पर boot के दौरान I/O pressure काफी घटता है। X चलाने पर भी booted system 200MB से कम है
दूसरी बात, EFI stub speed बढ़ा सकता है: https://wiki.archlinux.org/title/EFISTUB
पहला अंदाज़ा यही था कि क्या दूसरे core का इस्तेमाल नहीं किया जा सकता। फोटो लेकर cloud पर भेजने के लिए क्या सच में Linux चाहिए?
मैं hardware वाला इंसान नहीं हूं, इसलिए जानना चाहता हूं कि कम-से-कम बजट में यह काम कैसे पूरा किया जा सकता है। लेख दिलचस्प था
अभी मेरी डाइनिंग टेबल पर दो ESP32-CAM पड़े हैं, इसलिए सोच रहा था कि ESP32-CAM configuration की तुलना कैसी होगी। शायद 2-megapixel image तक ही ठीक रहे, लेकिन start time और power consumption दोनों लगभग एक order of magnitude कम लगते हैं
दिलचस्पी हो तो यहां details हैं: https://components101.com/modules/esp32-cam-camera-module
सिद्धांत रूप में bare-metal पर भी संभव है, लेकिन जरूरी peripherals को चलाना आसान नहीं है
मैं सोच रहा था कि custom kernel इतनी देर से क्यों आया। optimization करनी हो तो क्या LFS या source-based distribution से शुरू नहीं करते? ऐसे device में autonomous software updates अनिवार्य हों, ऐसा भी नहीं लगता
यह भी जानना चाहता था कि ऐसे device में EFI/BIOS को optimize किया जा सकता है या नहीं। कम-से-कम मेरे आम Arch Linux desktop पर boot time का बड़ा हिस्सा वही लेता है
$ systemd-analyzeStartup finished in 10.076s (firmware) + 1.339s (loader) + 1.569s (kernel) + 2.974s (initrd) + 3.894s (userspace) = 19.854sRaspberry Pi hardware के बारे में मुझे ठीक-ठीक नहीं पता, लेकिन कई दूसरे embedded SoC में u-boot से चलने वाला काफी minimal bootloader होता है और आम तौर पर बहुत fast होता है। खासकर जब user input का इंतजार करने वाला delay 0 पर set कर दिया जाए
minimal kernel और busybox system कहीं कम दर्दनाक है, और Gentoo भी बुरा विकल्प नहीं है
> systemd-analyzeStartup finished in 3.259s (firmware) + 35.127s (loader) + 1.823s (kernel) + 2.927s (userspace) = 43.138s3.5 seconds शानदार हैं, लेकिन अगर पूरा scenario सच में हर कुछ मिनट में Wi-Fi से connect होकर image upload करने का है, तो ESP32 power consumption के लिहाज से कहीं बेहतर choice होता
बशर्ते Pi के camera module में कोई ऐसी खास functionality जरूरी न हो जो ESP32-CAM compatible camera में नहीं है
ऐसा लगता है कि जिस काम को microcontroller लगभग बिना मेहनत कर सकता है, उसे करने के लिए बहुत ज्यादा काम किया जा रहा है