
قبل بضع سنوات ، أنشأت
قرصًا مرنًا قابلاً للتمهيد ولعبة قديمة تتناسب مع تغريدة واحدة. منذ ذلك الحين ، ضاعف Twitter طول التغريدات ، لذلك قررت إنشاء قرص مضغوط قابل للتمهيد. يتم تشغيل نسخة محسنة قليلاً من ترون.
perl -E 'say"A"x46422,"BDRDAwMQFFTCBUT1JJVE8gU1BFQ0lGSUNBVElPTg","A"x54,"Ew","A"x2634,"/0NEMDAxAQ","A"x2721,"BAAAAYQ","A"x30,"SVVVqogAAAAAAAEAF","A"x2676,"LMBaACgB76gfbgTAM0Qv8D4uYAI86qqgcc+AXP45GA8SHIRPFB3DTeYSEhyBSwCa8CwicMB3rSG/sHNFbRFJjAke9rrwQ","A"x2638'|base64 -D>cd.iso
ينشئ الرمز الموجود في التغريدة صورة قرص مضغوط قابل للتمهيد:
cd.iso
. يمكنك تحميل الرمز إلى qemu أو الجهاز الافتراضي المفضل لديك - واللعب باستخدام مفاتيح الأسهم. يمكنك حتى نسخ iso إلى CD-R والتمهيد على جهاز كمبيوتر حقيقي.
لإنشاء صورة قرص مضغوط يدويًا ، تحتاج أولاً إلى الحصول على فهم أساسي
لمعيار ISO 9660 . لسوء الحظ ، تكون المستندات بمعايير ISO باهظة الثمن عادةً. ومع ذلك ، فإن ISO 9660 هو نفسه
ECMA 119 ، لذا يمكن قراءة المواصفات مجانًا.
يحتوي ISO 9660 على العديد من الامتدادات ، مثل UDF و El Torito و RockRidge و Joliet وما إلى ذلك. بالنسبة لصور التمهيد ، فإن
El Torito فقط هو المهم بالنسبة لنا. في رأيي ، فإن مواصفات El Torito مكتوبة بشكل سيئ. هناك أخطاء (على سبيل المثال ، السطر الأخير في الجدول 7) ، من السهل نسيان أن القيم سداسية عشرية (لم يتم تحديد البادئات
0x
) ، ولا يتم فرز الأرقام بشكل حدسي ، إلخ. لحسن الحظ ، الوثيقة صغيرة جدًا.
لإنشاء قرص تمهيد ، نبدأ بكتابة 17 قطاعًا فارغًا ، متبوعًا بمجموعة من مجموعة واصف وحدة التخزين. لكل قطاع 2048 بايت.
ملاحظة تنص مواصفات ISO-9660 على أن مجموعة واصف وحدة التخزين تبدأ بالقطاع 16. تتطلب مواصفات El Torito بدء سجل التمهيد في القطاع 17. من الناحية الفنية ، يجب وضع واصف وحدة تخزين وهمية في القطاع 16 ، ولكن كل شيء يعمل بشكل جيد بدونه.
نكتب واصف المجلد الأول:
0x00 // Type (0 = boot record) 'CD001' // Identifier 0x01 // Version 'EL TORITO SPECIFICATION' // Boot System Identifier 9 x 0x00 // Padding 32 x 0x00 // Unused 0x13 0x00 0x00 0x00 // Boot Catalog address (in absolute sectors) 1973 x 0x00 // Unused
يحتوي المقطع التالي على Termimator Set Descriptor Set:
0xff // Type (255 = terminator) 'CD001' // Identifier 0x01 // Version 2041 x 0x00 // Unused
ويلي كتالوج التمهيد وصفات وحدة التخزين. يدعم El Torito أوضاع المحاكاة المختلفة. يمكن للأقراص المضغوطة محاكاة قرص تمهيد أو محرك أقراص صلبة قابل للتمهيد وما إلى ذلك. لم أقم بتثبيت مضاهاة ، أي أن BIOS سيحمّل عددًا معينًا من القطاعات - ويأخذ أداة تحميل التشغيل.
يتم حساب المجموع الاختباري بحيث يتم جمع كل قيم 16 بت في السجل إلى 0 (mod 65536).
الإدخال الأول في دليل التمهيد (إدخال التحقق):
0x01 // Header ID 0x00 // Platform ID (0 = Intel x86) 0x00 0x00 // Reserved 'a' // ID string 23 x 0x00 // Padding cksum cksum // Checksum (2 bytes) 0x55 0xaa // Key bytes
السجل الثاني (افتراضي):
0x88 // Boot Indicator (0x88 = bootable) 0x00 // Boot Media Type (0 = no emulation) 0x00 0x00 // Load segment 0x00 // System Type 0x00 // Unused 0x01 0x00 // Number of sectors to load 0x14 0x00 0x00 0x00 // Virtual disk address (in absolute sectors) 20 x 0x00 // Unused
ثم الأصفار إلى نهاية القطاع:
1984 x 0x00
القطاع التالي هو محمل الإقلاع ولعبة الرجعية:
; to compile: ; nasm bootloader.asm -o bootloader.img [bits 16] ; Pragma, tells the assembler that we ; are in 16 bit mode (which is the state ; of x86 when booting from a floppy). [org 0x7C00] ; Pragma, tell the assembler where the ; code will be loaded. mov bl, 1 ; Starting direction for the worm. push 0xa000 ; Load address of VRAM into es. pop es restart_game: mov si, 320*100+160 ; worm's starting position, center of ; screen ; Set video mode. Mode 13h is VGA (1 byte per pixel with the actual ; color stored in a palette), 320x200 total size. mov ax, 0x0013 int 0x10 ; Draw borders. We assume the default palette will work for us. ; We also assume that starting at the bottom and drawing 2176 pixels ; wraps around and ends up drawing the top + bottom borders. mov di, 320*199 mov cx, 2176 rep draw_loop: stosb ; draw right border stosb ; draw left border add di, 318 jnc draw_loop ; notice the jump in the middle of the ; rep stosb instruction. game_loop: ; We read the keyboard input from port 0x60. This also reads bytes from ; the mouse, so we need to only handle [up (0x48), left (0x4b), ; right (0x4d), down (0x50)] in al, 0x60 cmp al, 0x48 jb kb_handle_end cmp al, 0x50 ja kb_handle_end ; At the end bx contains offset displacement (+1, -1, +320, -320) ; based on pressed/released keypad key. I bet there are a few bytes ; to shave around here given the bounds check above. aaa cbw dec ax dec ax jc kb_handle sub al, 2 imul ax, ax, byte -0x50 kb_handle: mov bx, ax kb_handle_end: add si, bx ; The original code used set pallete command (10h/0bh) to wait for ; the vertical retrace. Today's computers are however too fast, so ; we use int 15h 86h instead. This also shaves a few bytes. ; Note: you'll have to tweak cx+dx if you are running this on a virtual ; machine vs real hardware. Casual testing seems to show that virtual machines ; wait ~3-4x longer than physical hardware. mov ah, 0x86 inc cl int 0x15 ; Draw worm and check for collision with parity ; (even parity=collision). xor [es:si], ah ; Go back to the main game loop. jpo game_loop ; We hit a wall or the worm. Restart the game. jmp restart_game TIMES 2048 - ($ - $$) db 0 ; Fill the rest of the sector with 0
ثم كتبت نصًا برمجيًا لتجميع أداة تحميل التشغيل وإنشاء الصورة وإنشاء تغريدة. أخيرًا ، قمت بنسخ القرص المضغوط وتحقق من أن
كل شيء يعمل على أجهزة حقيقية .