1 पॉइंट द्वारा GN⁺ 2024-04-07 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • UEFIRC एक ग्राफिकल IRC क्लाइंट है जो OS के बूट होने से पहले मेनबोर्ड फ़र्मवेयर के UEFI pre-boot environment में चलता है, और दिखाता है कि bootloader जैसे environment में भी सामान्य app जैसी UI और networking capabilities बनाई जा सकती हैं
  • इसका implementation, network boot के लिए UEFI द्वारा दिए गए NIC drivers और TCP stack का उपयोग करता है, और QEMU का vmnet network backend development को संभव बनाता है
  • सबसे कठिन हिस्सा Rust में UEFI TCP protocol को handle करना था, जहाँ global state, reentrant callbacks, scatter-gather buffers, events, tokens, handles और protocols जटिल रूप से एक-दूसरे से जुड़े हुए हैं
  • GUI, axle के Rust GUI toolkit और TrueType renderer को UEFI में लाकर बनाया गया है, और mouse input, scrollbar, scroll view text rendering के लिए libgui improvements भी साथ में किए गए
  • यह परिणाम किसी practical IRC client से ज़्यादा एक परिष्कृत मज़ाकिया project जैसा है, लेकिन UEFI TCP/IP stack पर नाराज़गी को UEFI के भीतर IRC पर कहने का एक tool बन जाता है

UEFIRC क्या करता है

  • UEFIRC एक ग्राफिकल IRC क्लाइंट है जो UEFI में चलता है
  • यह Rust में लिखा गया है और axle user space के लिए बनाए गए GUI toolkit और TrueType renderer का उपयोग करता है
  • यह IRC server से connect होकर chat कर सकता है और messages पढ़ सकता है
  • development के लिए QEMU का vmnet network backend इस्तेमाल किया गया

UEFI नाम का execution stage

  • OS का bootloader, motherboard ROM में stored firmware की मदद से load होता है
  • पुराने BIOS में कई सीमाएँ थीं, और इन्हें बदलने के लिए UEFI standard बनाया गया
    • BIOS में bootloader को 16-bit mode में शुरू होना पड़ता था
    • first-stage loader को 512 bytes के भीतर फिट होना भी ज़रूरी था
  • UEFI, bootloader को शुरुआत से ही 64-bit environment में रखता है और VESA display resolution switching, memory allocation, EFI filesystem access जैसी APIs देता है
  • यह BIOS की तुलना में बड़ा सुधार है, लेकिन इसे overengineered भी माना जाता है

Network boot feature का IRC के लिए पुन: उपयोग

  • कुछ bootloaders local block device के बजाय network के जरिए operating system load कर सकते हैं
  • इस use case को support करने के लिए UEFI firmware में network stack शामिल होना चाहिए
    • NIC drivers
    • TCP implementation
    • pre-boot environment में चलने वाले applications के लिए इस stack तक पहुँच की APIs
  • चूँकि bootloader का काम केवल OS load करना ही नहीं होना चाहिए, उसी environment में IRC client भी चलाया जा सकता है

Rust में UEFI TCP को संभालने की कठिनाई

  • project का सबसे कठिन हिस्सा Rust में UEFI TCP protocol client implement करना था
  • UEFI TCP protocol ऐसे data lifetimes और interactions माँगता है जिन्हें Rust में व्यक्त करना कठिन है
    • global state
    • reentrant callbacks
    • scatter-gather buffers
    • events, tokens, handles, protocols
  • memory leaks और TCP receive buffer के use-after-free को हटाने के लिए Rust code को कई दिनों तक test किया गया

NOTIFY_SIGNAL और NOTIFY_WAIT की उलझन

  • UEFI event API का behavior केवल नाम देखकर समझना कठिन है
  • NOTIFY_SIGNAL देने पर event होने पर callback call होता है, और wait() का उपयोग error बन जाता है
  • NOTIFY_WAIT देने और wait() call करने पर, UEFI event होने से पहले callback को कई बार call कर सकता है, और event होने पर wait() खुल जाता है
  • एक ही callback होने पर भी दोनों modes का मतलब पूरी तरह अलग हो जाता है
    • NOTIFY_SIGNAL: event हो चुका है, अब अगला काम करना है
    • NOTIFY_WAIT: event अभी नहीं हुआ है, आगे बढ़ने के लिए कोशिश करनी है
  • receive packet data को asynchronously buffer करने के लिए अंत में NOTIFY_WAIT loop और short-timeout timer को साथ इस्तेमाल किया गया

Mouse और cursor support

  • IRC client के लिए mouse अनिवार्य नहीं है, लेकिन इससे app ज़्यादा interactive महसूस होता है
  • UEFI के Simple Pointer Protocol का उपयोग कर mouse movement और button input पढ़े गए, और GUI में cursor position feedback जोड़ा गया
  • Simple Pointer Protocol scroll wheel support नहीं करता
    • UEFIRC में scroll करने के लिए arrow keys या cursor से scrollbar drag करना पड़ता है
  • standard OVMF UEFI firmware में mouse events नहीं मिलते, इसलिए UsbMouseDxe जैसे ज़रूरी drivers और protocols वाला custom UEFI firmware build किया गया
  • QEMU में UEFIRC को test करने के लिए वही UEFI firmware भी release में upload किया गया

Mouse movement scaling

  • mouse driver absolute position नहीं, बल्कि position delta report करता है
  • सिर्फ delta_x, delta_y को सीधे जोड़ने वाली linear scaling सुस्त लगती है
  • operating systems आम तौर पर ऐसी scaling इस्तेमाल करते हैं जो तेज movement और fine adjustment दोनों को संभव बनाती है
  • example implementation में movement के absolute values के योग पर log2() लगाकर उसे cursor movement multiplier की तरह उपयोग किया गया
  • linear movement cursor से पूरा environment धीमा और कम responsive महसूस हो सकता है

IRC message modeling

  • IRC message modeling अपेक्षाकृत सरल और सहज था
  • IRC text-based line format का उपयोग करता है, इसलिए इसे parse करना आसान है
  • हालाँकि, कई दशकों के extensions की वजह से इसका कुछ ही हिस्सा standardized है, जिससे थोड़ा बोझ आता है

UEFI में libgui का उपयोग

  • axle का Rust GUI toolkit पहले से axle के बाहर के contexts में उपयोग योग्य बनाने के लिए काफी हद तक तैयार था, इसलिए इसे UEFI में चलाना बहुत कठिन नहीं था
  • मुख्य काम UEFI के भीतर इस्तेमाल करने लायक AwmWindow implementation देना था
  • उसके बाद libgui की कई सुविधाओं का सीधे उपयोग किया गया
    • event management
    • font rendering
    • layer compositing
    • view decoration
    • scroll view जैसे जटिल components

Scrollbar और scroll view text rendering

  • axle की C-based libgui में scrollbar feature था, लेकिन Rust version में अभी कुछ functionality की कमी थी
  • UEFIRC का मुख्य interaction text से भरे scroll view में होता है, इसलिए Rust libgui में scrollbar feature फिर से implement किया गया
  • scroll view की pixel rendering cost, fixed-size view से अधिक होती है
    • fixed-size view के लिए width * height आकार का RGB buffer सोचना काफी है
    • scroll view में अनंत तक बढ़ सकने वाले canvas को संभालना पड़ता है
  • axle का Rust GUI toolkit scroll view को tile-based तरीके से handle करता है
    • हर tile सैकड़ों pixels चौड़ाई वाला square pixel buffer होता है
    • सिर्फ उन्हीं tiles को allocate किया जाता है जहाँ content वास्तव में render होना है
    • visible tiles को calculate करके final image में जोड़ा जाता है
  • जब TrueType renderer glyph के हर pixel के लिए putpixel() call करता है, तो scroll view पूरी rendering area को पहले से नहीं जान पाता, जिससे inefficiency होती है
  • इसे हल करने के लिए polygon stack को line, circle, rectangle जैसे basic drawing units तक बढ़ाया गया
    • इससे scroll view पहले से जान सकता है कि बड़ा polygon draw होने वाला है और ज़रूरी tiles पहले allocate कर सकता है
    • arbitrary polygon fill को basic primitive बनाना आदर्श नहीं लगता, लेकिन व्यवहार में यह अच्छी तरह काम करता है

UEFIRC बनाते समय बेहतर हुई libgui

पूरी तरह अनावश्यक परिणाम

  • IRC client खुद एक परिष्कृत मज़ाकिया project है, इसलिए इसकी practical usability बहुत ज़्यादा नहीं है
  • लेकिन जब UEFI TCP/IP stack पर गुस्सा आए, तो यह उस शिकायत को कहने का tool बन सकता है
  • अंत में, UEFI के भीतर से UEFI #edk2 development IRC channel में जाकर अभिवादन भी छोड़ा गया

1 टिप्पणियां

 
GN⁺ 2024-04-07
Hacker News की राय
  • मज़ाक-मज़ाक में मैंने एक graphical IRC client बनाया जो सिर्फ UEFI pre-boot environment में चलता है, और उसमें TrueType फ़ॉन्ट, cursor, GUI decoration जैसी हद से ज़्यादा सुविधाएँ भी डाल दीं
    असल में यह प्रोजेक्ट इसलिए शुरू किया था क्योंकि बिल्कुल शुरुआत से GPS receiver बनाते-बनाते थक गया था और कुछ तेज़ व हल्का करना चाहता था, लेकिन हमेशा की तरह इसमें भी उम्मीद से बहुत ज़्यादा समय लग गया
    लेख में scroll view को model करने और उसे static viewport में render करने के तरीके की visualization पर भी मैंने काफ़ी समय लगाया, उम्मीद है लोगों को यह मज़ेदार लगेगा
    शुरुआत में सोचा था, “चलो UEFI में वह चीज़ ठूँसते हैं जिसे वहाँ नहीं होना चाहिए,” और Twitter client का विचार आया, लेकिन किसी ने पहले ही UEFI के HTTP protocol के साथ बढ़िया काम कर लिया था, इसलिए मैंने HTTP से बचने का फ़ैसला किया
    इसलिए मैंने IRC चुना, जो TCP पर चलता है और pre-boot environment के लिए बिल्कुल बेमेल social media जैसा एहसास भी देता है

    • इसे “ऐसी चीज़ जो pre-boot environment के पास भी नहीं होनी चाहिए” कहा जा सकता है, लेकिन अगर boot समस्या में मदद माँगनी हो तो यह तो उल्टा एकदम सही जगह लगती है
    • मैं बेकार के विशाल operating system और तरह-तरह की अतिरिक्त सुविधाएँ छोड़कर छोटे और सरल UEFI की तरफ़ जाना चाहूँगा। शुरुआत भी तेज़ होगी और “embedded” development भी आसान हो जाएगा
      बेशक, यह मज़ाक है। कम से कम कुछ हद तक
      मैं minimalist हूँ, इसलिए मुझे GUI या mouse की भी ज़रूरत नहीं, और UEFI भी मुझे ज़रूरत से ज़्यादा लगता है
      ऊपर बताया गया Twitter client यहाँ है: https://github.com/arata-nvm/mitnal
    • अगर कोई software UEFI में ठूँसने के लिए बहुत बड़ा है, तो शुरुआत से ही उसे पूरी तरह अनावश्यक bloated software मानना चाहिए। पहले तो 360KB की दो floppy काफ़ी होती थीं
    • यह सच में शानदार है। मैं लंबे समय से सोच रहा था कि क्या VPN credentials को UEFI में store किया जा सकता है, ताकि system server से connect होकर PXE network boot कर सके
      यह शायद remote system की automatic recovery के लिए, जहाँ installation पूरी तरह टूट चुकी हो और सामान्य boot संभव न हो, एक काफ़ी अच्छा और शायद सुरक्षित तरीका हो सकता है
    • मुझे शुरुआत से बनाए गए GPS receiver वाले हिस्से के बारे में और जानने की ज़्यादा उत्सुकता है
  • यह बहुत अच्छा है। यह इस बात को भी अच्छी तरह दिखाता है कि जिस सिस्टम को ज़्यादातर लोग अंतिम आधार समझते हैं, उसके नीचे भी उम्मीद से कहीं अधिक जटिल और शक्तिशाली software पड़ा होता है
    लोग अक्सर ग़लती से operating system को software stack की “सबसे निचली परत” मान लेते हैं, लेकिन वास्तव में सिस्टम पर असली नियंत्रण रखने वाला firmware-जैसा code भी होता है
    कभी-कभी वह अपना काम पूरा करके ग़ायब हो जाता है, और कभी-कभी पूरे समय मौजूद रहता है, जबकि operating system को भी उसका पता नहीं चलता
    अक्सर रवैया यह रहता है कि “वह तो बस devices चलाने वाला low-level code है, वहाँ कुछ गंभीर नहीं होता,” लेकिन अगर उसके नीचे IRC client तक डाला जा सकता है, तो और भी कई दुर्भावनापूर्ण चीज़ों की कल्पना करना आसान हो जाता है

  • “क्यों?” से आपका क्या मतलब है? यह भी कोई सवाल है? मैं HN पर ऐसी ही भावना देखने आता हूँ
    “फिर सबसे डरावनी समझ आई। मैंने जो किया, उसका कोई कारण ही नहीं था। मैं जानता था कि मैंने यह क्यों किया। बस इसलिए कि यह मज़ेदार लग रहा था। लेकिन वे लोग पूछेंगे, ‘आख़िर तुमने यह किया ही क्यों,’ और अगर मेरे पास कोई काफ़ी विश्वसनीय वजह न हुई, तो शायद वे मुझे पागलखाने भेज देंगे।” — Boyd Rice

  • अपने काम को कम मत आँकिए। यहाँ तो botnet command-and-control client प्रोजेक्ट भी है
    उसका UI थोड़ा मज़ेदार है

  • यह सच में शानदार है। मुझे नहीं पता था कि UEFI API इतनी सुलभ और इतनी अच्छी तरह documented है
    development cycle कैसी थी, यह जानने की जिज्ञासा है। शायद आपने VM में चलाया होगा, तो क्या client हर बार चलाने के लिए पूरा “boot” करना पड़ता था?

    • आम तौर पर workflow ऐसा था कि UEFI application को लादकर QEMU instance boot किया जाता था
      मुख्य run script UEFIRC की नई build वाला EFI filesystem दोबारा बनाती थी और उसे QEMU को दे देती थी
      लेकिन GUI बनाते समय यह overhead काफ़ी परेशान करने लगा, इसलिए app को इस तरह सेट किया गया कि वह शुद्ध UEFI और Mac पर चलने वाले host environment, दोनों targets के लिए build हो सके
      build flag बदलने पर GUI toolkit या तो UEFI द्वारा दिए गए framebuffer पर सीधे draw करती थी, या फिर Mac के window system से जुड़कर events भेजती-लेती थी
      इस dual-target approach का overhead entry point में भी दिखता है: https://github.com/codyd51/uefirc/blob/main/src/main.rs
      IRC message parsing को अलग सजावट की ज़रूरत नहीं थी, इसलिए उसे Mac पर सीधे चलने वाले unit tests के सेट के रूप में विकसित किया गया, जिनमें से कुछ यहाँ हैं: https://github.com/codyd51/uefirc/blob/main/src/irc/response...
    • QEMU UEFI apps चला सकता है
  • कभी न कभी मैं अपने अब भी चल रहे IRC bot के लिए operating system लिखना पूरा करना चाहता हूँ
    शायद यह अब तक की सबसे बेकार बात लगे, लेकिन nonlinear mouse movement, यानी acceleration, वह setting है जिसे मैं नया operating system boot करते ही सबसे पहले बंद करता हूँ। अजीब तरह से इससे हाथ में सचमुच दर्द होता है
    उदाहरण के लिए Mac पर मुफ़्त linearmouse है, Windows में बस acceleration बंद कर दीजिए। Linux में तो यह स्वाभाविक रूप से आसान है
    mouse acceleration के साथ, mouse की वास्तविक movement और स्क्रीन पर pointer की movement के बीच mapping की समझ बनाना कठिन होता है, और लंबे समय में बिना acceleration के इस्तेमाल ज़्यादा कुशल लगता है
    यह मैंने gamers से सीखा है, और मुझे लगता है कि gamers के ऐसा करते रहने की अब भी अच्छी वजह है

    • मैं mouse settings बदलता नहीं, इसलिए default क्या है, यह नहीं जानता, लेकिन छिपे हुए screen area पर भी मैं अब भी ठीक से click कर सकता हूँ
      किसी भी तरह, लगता है समय के साथ एहसास की आदत पड़ ही जाती है। जैसे कार का accelerator pedal भी आम तौर पर सीधे speed से mapped नहीं होता
  • अगर आप पूछते हैं “क्यों?”, तो इसलिए कि जब UEFI पहली बार पेश किया गया था, तब इसी तरह के low-level applications का वादा किया गया था
    UEFI बनाने वालों ने तो यह सपना भी देखा था कि कुछ vendors जो boot के दौरान एक खास key दबाकर Linux-आधारित internet-only mini operating system तक पहुँच देते थे, उसकी जगह भी यह ले लेगा। उसका नाम याद नहीं

    • वह शायद पुराने Dell वगैरह में मिलने वाला Quick View / Quick Boot feature था। आम तौर पर वह सीधे कुछ productivity apps में boot करता था
      मैंने YouTube पर इस पर एक गहराई वाला वीडियो देखा था; याद पड़ता है कि शुरुआत में वह किसी stripped-down Linux या दूसरे custom operating system पर आधारित था, बाद में UEFI app में बदला गया, और फिर आख़िरकार उसका चलन खत्म हो गया
  • लेख अच्छा है। इससे मुझे 2 साल पहले barebox bootloader का April Fools मज़ाक याद आ गया। अगर बाकी सारे boot targets fail हो जाएँ, तो वह #barebox से connect कर देता था[1]
    वहाँ फ़ोकस barebox में TCP support जोड़ने पर था, यहाँ जैसी शानदार GUI चीज़ों पर नहीं
    interface सिर्फ command line था, और barebox को EFI payload के रूप में build करने पर EFI GOP के ऊपर draw किया जा सकता था
    [1]: https://lore.barebox.org/barebox/20220401145902.GF4351@telli...

  • मुझे तुरंत Cathode Ray Dude का हाल का वीडियो याद आ गया। उसमें HP के “email client”, जो असल में Outlook plugin QuickLook था, की चर्चा थी, और वह भी इसी तरह लागू होकर बाज़ार में आया था: https://www.youtube.com/watch?v=ssob-7sGVWs
    वीडियो में HP की और भी अजीब चीज़ें दिखाई गई हैं। लेकिन इस प्रोजेक्ट ने वह मुश्किल हिस्सा भी कर दिखाया है जिससे QuickLook बच निकला था: networking

  • लेख की visualization हैरान कर देने वाली हद तक बेहतरीन और प्रभावशाली है