1 คะแนน โดย GN⁺ 2024-09-21 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • Debian Linux ถูกบูตบนบอร์ดจริงที่ใช้ Intel 4004 แบบ 4 บิตจากปี 1971 เป็น CPU เพียงตัวเดียว แสดงให้เห็นทั้งขีดจำกัดของไมโครโปรเซสเซอร์ยุคเก่าและความสุดขั้วของการทำซอฟต์แวร์เป็นชั้นๆ
  • Linux ไม่ได้รันตรงบน 4004 แต่บูตบน อีมูเลเตอร์ MIPS R3000/DECstation 2100 ที่เขียนด้วยแอสเซมบลี 4004 โดยทำให้ดิสก์และคอนโซลบางส่วนเรียบง่ายลงด้วยไฮเปอร์คอลและไดรเวอร์แบบพาราเวอร์ชวลไลซ์
  • เนื่องจากข้อจำกัด ROM 4KB, การคำนวณแบบ 4 บิต, การไม่มีลอจิกโอเปอเรชัน, call stack ที่ตื้น และการอ้างแอดเดรสอันแปลกของ RAM 4002 จึงต้องใช้วิธีอ้อมอย่าง ROM banking, lookup table, status nibble และ virtual RAM ที่อิงกับ PSRAM
  • หลังปรับแต่งแล้ว เวลาที่คาดว่าจะใช้บูต Linux บน 4004 จริงที่ 740KHz คือ 4.76 วัน และบอร์ดที่สร้างขึ้นโอเวอร์คล็อกไปที่ 790KHz ทำให้ MIPS เสมือนทำงานได้ราว 74.73Hz
  • ผลงานชิ้นนี้ถูกออกแบบให้เป็น บอร์ดศิลปะเรโทร สำหรับแขวนผนัง พร้อม VFD 40x2, PC LED 32 ดวง, SD card, SPI PSRAM และ UART โดยเปิดเผยซอร์สและดิสก์อิมเมจภายใต้เงื่อนไขการใช้งานแบบไม่เชิงพาณิชย์

บูต Debian Linux บน 4004 จริง

  • Linux/4004 เป็นโปรเจกต์ที่บูต Debian Linux บนบอร์ดจริงที่ใช้ Intel 4004 จากปี 1971 เป็น CPU เพียงตัวเดียว
  • 4004 ถูกแนะนำในฐานะไมโครโปรเซสเซอร์ที่ผลิตเชิงพาณิชย์ตัวแรกของโลก และในโปรเจกต์นี้ใช้ชิป Intel 4004 ของจริงจากยุค 1970
  • วิดีโอสาธิตถูกปรับความเร็วแบบแปรผันเป็นช่วงๆ เพื่อลดความน่าเบื่อ และนาฬิกากับปฏิทินบนหน้าจอยังคงถูกต้องแม่นยำ
  • ยังมีวิดีโออีกชุดที่คงลักษณะต้นฉบับและเล่นด้วยความเร็วคงที่ให้ดูแยกต่างหาก

ทำไมต้องเป็น 4004

  • ในปี 2012 เคยมีการรัน Linux บนไมโครคอนโทรลเลอร์ AVR แบบ 8 บิตจนสร้างสถิติ “รัน Linux บนสเปกต่ำที่สุด” และต่อมาก็มีโปรเจกต์ LinuxCard ที่ใช้งานได้จริงมากขึ้น
  • เมื่อปี 2023 มีทั้งความพยายามทำลายสถิติเดิมด้วย AVR และโปรเจกต์บูต Linux บน MOS 6510 ทำให้เป้าหมายขยับไปสู่ CPU ที่ต่ำระดับยิ่งกว่าเดิม
  • เพื่อย้อนกลับไปไกลกว่า Intel 8080 และ 8008 ที่เคยเป็นตัวเลือก จึงเลือก Intel 4004 จากปี 1971
  • เพราะ 4004 เป็นชิป 4 บิต จึงกำหนดเกณฑ์ที่ต่ำกว่า CPU 8 บิตได้อย่างชัดเจน

ข้อจำกัดของ Intel 4004

  • 4004 ทำงานในหน่วย 4 บิต และคำสั่งส่วนใหญ่มีขนาด 1 ไบต์ ทำงานใน 8 คลอกไซเคิล
    • คำสั่ง 2 ไบต์บางตัวต้องใช้ 16 ไซเคิล
    • FIN เป็นข้อยกเว้นที่แม้จะเป็นคำสั่ง 1 ไบต์ แต่ใช้ 16 ไซเคิล
  • ชุดคำสั่งไม่มีลอจิกโอเปอเรชันอย่าง AND, OR, XOR และโดยพื้นฐานเน้นที่ ADD กับ SUB
  • carry flag มีพฤติกรรมแปลกคือในอินพุตของ SUB จะทำงานเหมือน borrow แต่หลัง SUB จะทำงานเหมือน not borrow ซึ่งยืนยันได้จากฮาร์ดแวร์จริง
  • รีจิสเตอร์ภายในมี 16 ตัวแบบ 4 บิต, PC เป็น 12 บิต และฮาร์ดแวร์ return stack ลึก 4 ระดับ
    • เนื่องจาก top stack entry ปัจจุบันถูกใช้เป็น PC การซ้อนฟังก์ชันจริงจึงทำได้สูงสุด 3 ระดับ
  • ไม่มี interrupt และสิ่งที่ใกล้เคียงกับการจัดการเหตุการณ์ภายนอกที่สุดคือการ polling ขา TEST ด้วยการกระโดดแบบมีเงื่อนไข

โครงสร้างหน่วยความจำและ I/O

  • 4004 ไม่ได้จัดการคำสั่งเกี่ยวกับหน่วยความจำโดยตรง แต่ใช้ชิปที่ต่ออยู่บนบัสอย่าง 4001/4002/4289/4265/4308 เป็นตัวดีโค้ดและดำเนินการคำสั่ง
  • 4001 เป็นชิป ROM ที่มี mask ROM 256 ไบต์และพอร์ต I/O 4 บิต โดยเนื้อหา ROM และการตั้งค่าพอร์ต I/O จะถูกกำหนดตายตัวตอนผลิต
  • 4002 เป็นชิป RAM ที่มี DRAM 320 บิต, วงจร refresh และพอร์ต 4 บิตแบบ output-only
    • RAM bank หนึ่งชุดสามารถประกอบด้วย 4002 ได้ 4 ตัว
    • แต่ละ RAM bank มี 256 nibble ที่อ้างแอดเดรสได้โดยตรง และมี status nibble 64 ตัวที่เข้าถึงแยกต่างหาก
  • 4289 เป็น ROM controller ที่รวมความสามารถของ 4008 และ 4009 ทำให้ 4004 เชื่อมต่อกับ EEPROM/EPROM 5V ได้ค่อนข้างง่าย
  • การเข้าถึงหน่วยความจำต้องผ่านหลายขั้นตอน เช่น เลือก bank, โหลดแอดเดรสเข้ารีจิสเตอร์คู่, ส่งแอดเดรสขึ้นบัสด้วย SRC แล้วจึงสั่ง RDM/WRM
    • status nibble มีประโยชน์มากในการเข้าถึงข้อมูลที่ใช้บ่อยอย่างรวดเร็ว และช่วยเพิ่มความเร็วของอีมูเลเตอร์ MIPS ได้ราว 30%

เตรียมบอร์ดพัฒนาและอีมูเลเตอร์

  • บอร์ดพัฒนาเพื่อการตรวจสอบเบื้องต้นประกอบด้วย 4201 clock generator, 4004 CPU, 4002-1 RAM, 4289 ROM controller และ ATMEGA48 ที่ทำหน้าที่เป็น ROM
  • แหล่งจ่ายไฟเริ่มจาก 5V แล้วนำขั้วบวกของ isolated 5V-to-10V boost converter ลงกราวด์เพื่อสร้างไฟ -10V ป้อนให้ชิป MCS-04
  • โปรแกรม 4004 ตัวแรกเป็นโค้ดกะพริบ LED ที่ต่อกับ 4002 output pin 0 และเริ่มทำงานได้หลังเพิ่มขีดจำกัดกระแส
  • ก่อนสร้างบอร์ดจริง มีการเขียนอีมูเลเตอร์ 4004 ชื่อ u4004 ขึ้นมาก่อน
    • มันอีมูเลตไม่เฉพาะคอร์ 4004 แต่รวมถึง SD card เสมือน, SPI UART, VFD, การจัดวาง 4002 และ PC LED ด้วย
    • ใช้เพื่อตรวจสอบสถานะขา SPI และการทำงานของอุปกรณ์ต่อพ่วงล่วงหน้า ซึ่งดีบักบนฮาร์ดแวร์จริงได้ยาก

ไม่ได้รัน Linux ตรงๆ แต่ใช้อีมูเลต MIPS

  • Linux ไม่สามารถรันตรงบน 4004 ได้
    • ไม่มี C compiler สำหรับ 4004 และจากข้อจำกัดของสถาปัตยกรรมจึงเห็นว่าการยก Linux kernel ขึ้นรันตรงๆ ทำได้ยาก
    • การซ้อนการเรียก, พื้นที่แอดเดรสของ ROM/RAM และข้อจำกัดของการคำนวณแบบ 4 บิต ล้วนขวางการรันตรง
  • ทางเลือกคือเขียนอีมูเลเตอร์ MIPS R3000 บน 4004 แล้วบูต Linux สำหรับ DECstation 2100 บนชั้นนั้น
  • MIPS ถูกเลือกเพราะอีมูเลตได้ง่ายกว่าตัวเลือกอื่นภายในพื้นที่โค้ดของ 4004
    • ARM มี shift operand แบบกำหนดได้อิสระจำนวนมาก
    • RISC-V ถูกมองว่าน่าจะช้าเพราะรูปแบบการอ้างแอดเดรส
    • x86 อาจใช้พื้นที่เกิน 4KB แค่การดีโค้ดคำสั่ง
    • PPC ซับซ้อนเกินไป
  • เป้าหมายแรกคือใส่อีมูเลเตอร์ทั้งหมดไว้ใน ROM 4KB ที่ 4004 อ้างแอดเดรสได้โดยพื้นฐาน

วิธีอ้อมในการทำอีมูเลเตอร์ MIPS

  • เพียงแค่การดีโค้ดคำสั่ง MIPS ก็ใช้พื้นที่ ROM ไปมาก
    • dispatch table ของ top-level opcode 64 ตัวต้องใช้ 128 ไบต์
    • เมื่อนับ sub-table เพิ่มเติมด้วย การดีโค้ดหลักกินพื้นที่ 359 ไบต์
  • รีจิสเตอร์ 32 ตัวขนาด 32 บิตของ MIPS มีรวม 1024 บิต หรือเท่ากับ 256 nibble ในมุมมองของ 4004 ซึ่งกิน RAM bank ไปหนึ่งชุดพอดี
  • เดิมที MIPS TLB มี 64 entry แต่เพราะ Linux ไม่ได้ต้องการครบ 64 แบบเป๊ะๆ จึงลดเหลือ 16 entry
    • จำนวน TLB entry ถูกออกแบบให้ปรับเป็น 4, 8, 12 หรือ 16 ได้ด้วย
  • เพราะ 4004 ไม่มีลอจิกโอเปอเรชัน การทำ AND/OR/XOR/NOR จึงต้องอาศัยการบวกกับ carry, การ shift และลูป
    • ภายหลังเมื่อมีพื้นที่ ROM เพิ่มขึ้น จึงปรับให้เร็วขึ้นด้วย lookup table ขนาด 256 entry
  • การ shift ก็ต้องอาศัยคำสั่ง rotate ผ่าน carry ทีละ 1 บิตของ 4004 และต่อมาปรับปรุงด้วยการคัดลอกเป็นหน่วย nibble ร่วมกับ bit shift สูงสุด 3 ครั้ง
  • การจัดการรีจิสเตอร์ $zero ของ MIPS ใช้ประโยชน์จากคุณสมบัติ circular return stack ของ 4004 เพื่อประหยัดพื้นที่ ROM
    • หากปลายทางเป็น $zero จะไม่ return แต่ย้ายไปประมวลผลคำสั่งถัดไปทันที ช่วยลดได้ 3 ไบต์และ 3 ไซเคิลต่อ callsite

ROM banking และการปรับปรุงประสิทธิภาพ

  • ROM 4KB อย่างเดียวไม่พอสำหรับโค้ดที่ต้องจัดการทั้ง SD card, PSRAM, VFD และ UART จึงใช้ ROM 8KB แบ่งเป็น 2 bank
  • การสลับ ROM bank ควบคุมผ่าน 4002 output pin และมีการวาง veneer เพื่อรองรับ call/return ข้าม bank
  • เมื่อมีพื้นที่ ROM เพิ่มขึ้น ก็สามารถปรับแต่งประสิทธิภาพได้
    • AND/OR/XOR ถูกทำเป็น lookup table ขนาด 256 entry แยกกัน
    • ใช้ lookup table สำหรับการคูณระดับ nibble ทำให้ multiplication เร็วกว่าแบบเดิมที่ทำระดับบิตถึง 8 เท่า
  • lookup table สำหรับลอจิกโอเปอเรชันอาศัยคุณสมบัติของ JIN บน 4004 ที่เมื่ออยู่ท้าย ROM page จะ jump โดยอิงจาก page ถัดไป
  • ตาราง multiplication ถูกทำร่วมกันระหว่างวิธีอ่านข้อมูล byte จาก ROM ด้วย FIN และการหลีกเลี่ยงการจัดการ entry ค่า 0

การจัดวางฮาร์ดแวร์ขั้นสุดท้าย

  • บอร์ดสุดท้ายถูกออกแบบเป็น อาร์ตบอร์ดที่เน้นชิ้นส่วนแบบ through-hole ให้ความรู้สึกยุค 1970
    • มีลายทองแดงหนาเป็นมุมฉาก, ไม่มี via, มีรูสำหรับแขวนผนัง, และมีจอแสดงผล VFD
  • องค์ประกอบหลักมีดังนี้
    • CPU 4004 หรือ 4040
    • 4201 clock generator
    • ชิป RAM 4002
    • 4289 ROM controller
    • EEPROM
    • SPI PSRAM 1~2 ตัว
    • ช่องเสียบ SD card
    • SC16IS741A SPI UART
    • VFD 40x2
    • LED แสดงสถานะ PC 32 ดวง
  • SPI PSRAM ถูกใช้เป็น RAM ของ MIPS เสมือน
    • PSRAM ตัวแรกต้องมีอย่างน้อย 4MB เพราะต้องโหลดเคอร์เนลแบบต่อเนื่อง
    • PSRAM ตัวที่สองจะปล่อยว่างไว้หรือใส่ขนาดใดก็ได้ตั้งแต่ 128KB ขึ้นไป
  • ใช้ VFD รุ่น Futaba M402SD10FJ และได้รับข้อมูลว่า Noritake CU40025-UW6J ใช้แทนกันได้
  • UART เลือกใช้ชิ้นส่วนแบบติดผิวหน้า SC16IS741A เพราะ MAX3100 ซึ่งเคยเป็นตัวเลือก SPI UART แบบ through-hole มีข้อจำกัดด้าน flow control

พลังงานและการเลื่อนระดับสัญญาณ

  • ชิ้นส่วน MCS-04 ใช้แรงดันแบบพิเศษตระกูล -15V และใช้ inverted logic
    • ในเชิงระบบจะมองว่าเป็นแหล่งจ่าย -10V และ +5V จะเข้าใจง่ายกว่า
  • บอร์ดรับ +5V ผ่าน USB-C edge connector และสร้าง +3.3V กับ -10V เพิ่มเอง
  • ตัวแปลง step-down +3.3V สร้างบนพื้นฐานของ LM2574
  • แหล่งจ่าย -10V เปลี่ยนจาก MAX764 ใน revision แรก ซึ่งจ่ายกระแสได้ไม่พอ ไปเป็น MAX774 พร้อม FET ภายนอก, diode ขนาดใหญ่, และ inductor ขนาดใหญ่
    • สุดท้ายจ่ายกระแสที่ -10V ได้เกิน 700mA และมี ripple ต่ำกว่า 200mV
  • การเลื่อนระดับสัญญาณเพื่อแปลงเอาต์พุต 4002 ไปยังโดเมน 3.3V ทำได้ยาก และแก้ได้ด้วยการผสม 10K pulldown, 2.7K resistor, TVS clamp, และตัวแบ่งแรงดันแบบตัวต้านทาน

เครื่องมือดีบักและข้อบกพร่องที่พบจริง

  • เนื่องจาก 4004 ไม่มีความสามารถด้านดีบักในตัว จึงใช้ Saleae Logic จับสัญญาณ MCS-04 bus เป็นเวลานาน
  • มีการเขียน MCS-04 bus decoder เพื่อวิเคราะห์ bus state, ROM address, ค่าอ่านจาก ROM, disassembly, และค่าการอ่าน/เขียน RAM/I/O
    • ต่อมาถูกนำกลับไปมีส่วนร่วมกับ Saleae และถูกรวมเข้าในซอฟต์แวร์ Saleae ทั่วไป
  • บนบอร์ด revision 1.1 มีปัญหาที่ตัวอักษรเอาต์พุตเพี้ยนเป็นครั้งคราว
    • ตัวอย่างเช่น i แสดงเป็น h, และ C แสดงเป็น B เหมือนบิตล่างหายไป
  • จากการวิเคราะห์พบว่า ระหว่าง kernel memcpy() มีข้อบกพร่องที่ชิป 4002 ซึ่งเก็บ $t1 ที่จำลองไว้ ทำให้บิตล่างสุดของ nibble บางตำแหน่งตกจาก 1 เป็น 0 เป็นครั้งคราว
  • หลังเปลี่ยน 4002 ตัวนั้นแล้ว การแสดงข้อความก็กลับมาปกติ

เส้นทางการบูต

  • เฟิร์มแวร์จะตรวจสอบจำนวนชิปหน่วยความจำใน RAM bank ที่สามก่อน เพื่อระบุจำนวน TLB entry
  • จากนั้นจึงเริ่มต้น VFD, UART, และ SD card
    • หากการเริ่มต้น SD card ล้มเหลว จะแสดง "Failed to init SD card. Halting here and now!"
    • สตริงนี้เป็นสตริงเดียวในเฟิร์มแวร์ทั้งหมด
  • เฟิร์มแวร์ไม่มี virtual ROM แต่จะโหลด sector แรกของ SD card ไปยัง 0x80000000 ใน RAM แล้วกระโดดไปทำงาน
  • loader ขนาด 446 ไบต์ใน sector แรกจะค้นหา partition ชนิด 0xBB จาก partition table แล้วอ่านไปยัง 0x80001000 ก่อนกระโดดไปทำงาน
  • loader ตัวที่สองมีขนาดประมาณ 14KB และเขียนด้วย C
    • เมานต์ active partition เป็น FAT12/16/32
    • แยกวิเคราะห์ vmlinux ในรูปแบบ ELF แล้วโหลดเข้า RAM ก่อนกระโดดไปยัง entrypoint
    • ส่ง machine type, magic value, RAM mapping, และ callback table สำหรับการพิมพ์ early console ไปด้วย

ดิสก์และการเข้าถึง SD card

  • การเข้าถึงดิสก์ใช้ ไดรเวอร์ดิสก์แบบ PVD paravirtualized เช่นเดียวกับโครงการ LinuxCard
  • แทนที่จะอีมูเลตชิป SII SCSI และดิสก์ SCSI ด้วย 4004 assembly นั้น hypercall สำหรับอ่าน/เขียน sector จะทำงานเหมือน DMA จากมุมมองของ MIPS เสมือน
  • RAM ทั้งหมดของบอร์ด Linux/4004 มี 440 ไบต์หากนับ status nibble และ 352 ไบต์หากไม่นับ
    • state ของรีจิสเตอร์ MIPS และ TLB กินพื้นที่ส่วนใหญ่ จึงไม่เหลือที่สำหรับ sector buffer ขนาด 512 ไบต์ของ SD card
  • ข้อมูล sector ของ SD จะไม่ถูกเก็บใน RAM ของ 4004 แต่ใช้อ่านเข้า PSRAM โดยตรงหรือเขียนจาก PSRAM ไปยัง SD ผ่าน SPI bus แยกของ SD card และ PSRAM
  • การอ่านหรือเขียน SD sector หนึ่งรายการใช้เวลามากกว่า 1 วินาทีเล็กน้อย
  • ข้อกำหนดด้านจังหวะเวลาเริ่มต้น ACMD41 ของสเปก SD ไม่สามารถทำให้ตรงได้ด้วย bit-banged SPI แต่ SD card ที่ทดสอบทั้งหมดก็เริ่มต้นได้แม้ที่ 5KHz และเว้นช่วงเกิน 200ms

ความเร็วการทำงานและผลลัพธ์จากการปรับแต่ง

  • หลังอีมูเลต SD card จริงและ SPI PSRAM แล้ว เวลาบูตที่คาดไว้ตอนแรกอยู่ที่ 8.9 วัน บน 4004 ที่ 740KHz
  • ผลการปรับแต่งหลักมีดังนี้
    • การคำนวณเชิงตรรกะและ multiplication lookup table เหลือ 8.4 วัน
    • การคลี่ลูปส่งรับ nibble ของ PSRAM เหลือ 7.25 วัน
    • specialized memory copy และการคลี่ลูป เหลือ 6.63 วัน
    • การลบพื้นที่เก็บคำสั่งปัจจุบันและใช้ liveness tracking เหลือ 6.50 วัน
    • การปรับปรุง shift เหลือ 6.19 วัน
    • การคลี่ลูปส่ง address ของ PSRAM เหลือ 6.01 วัน
    • การลด Linux kernel config และตั้ง dummy console 1x1 พร้อมใช้ tiny init เหลือ 5.33 วัน
    • การตัดการรองรับ block device ขนาดเกิน 2TB และปิดฟีเจอร์ ext4 huge_files เหลือ 4.81 วัน
    • fast path สำหรับ instruction fetch โดยเฉพาะ เหลือ 4.76 วัน
  • การบูตใน 4.76 วัน เทียบได้กับเครื่อง MIPS ประมาณ 70Hz บน 4004 ที่ 740KHz
  • บอร์ดที่สร้างจริงใช้ 4201 ในโหมด divide-by-7 และใช้ crystal 5.5296MHz จึงโอเวอร์คล็อกเป็น 790KHz
  • instruction mix ของ 4004 บนบอร์ด Linux/4004 คือคำสั่ง 16-cycle 8.8% และคำสั่ง 8-cycle 91.2% โดยมีความเร็วใช้งานจริง 90,640 instructions/s
  • virtual timer interrupt อยู่ที่ 16Hz และส่ง IRQ ทุก 65,536 virtual instruction ทำให้ virtual CPU มองว่าตัวเองทำงานที่ 1.05MHz
    • guest MIPS ที่ถูกอีมูเลตจริงทำงานประมาณ 70Hz ที่ 740KHz และประมาณ 74.73Hz ที่ 790KHz
    • เวลาเดินช้าลง 14,030 เท่า และเวลาเสมือน 1 วินาทีเท่ากับเวลาจริงประมาณ 3 ชั่วโมง 54 นาที

การตั้งค่า Linux และประสบการณ์การใช้งาน

  • Linux kernel ถูกลดขนาดลงเหลือประมาณ 2.5MB โดยตัด subsystem, filesystem, TCP/IP และการตั้งค่าที่ไม่จำเป็นออก
  • หากใช้เพียง init=/bin/sh จะได้สภาพแวดล้อมที่ไม่มี session, $PATH, /proc, /sys เป็นต้น จึงมีการเขียน tiny init ชื่อ /sbin/uMIPSinit
    • เมานต์ /proc และ /sys
    • ตั้งค่า hostname และ $PATH
    • เรียก sh ใหม่ทุกครั้งที่มันจบการทำงาน
  • RAM 4.5MB เช่น ชิป 4MB + ชิป 512KB ก็เพียงพอสำหรับบูตจนถึง shell prompt ได้โดยไม่ต้องใช้ swap
  • หากเปิด swap ก็สามารถคอมไพล์ kernel source บนอุปกรณ์นั้นได้เอง
    • คาดว่าการ build kernel source จะใช้เวลาหลายปี
    • มีแผนจะอาศัย ext4 journal เพื่อกู้ filesystem หลังไฟดับและเริ่ม compilation ต่อหลังรีบูต

เป้าหมายในฐานะอาร์ตบอร์ด

  • โครงการนี้มี เป้าหมายเชิงศิลปะ อยู่บางส่วนตั้งแต่แรก
  • บอร์ดถูกออกแบบให้แขวนผนังได้ และมี VFD, PCB layout สไตล์ย้อนยุค, และ LED แบบ PC
  • มีโปรแกรมสำหรับวาด Mandelbrot set ใน text mode บน VFD และ serial port
    • เวอร์ชัน floating point /root/mandelbrot ใช้เวลาประมาณ 30 วันในการวาดภาพขนาด 13 แถว x 40 คอลัมน์ เพราะ Linux ต้องอีมูเลตการคำนวณ floating point
    • เวอร์ชัน integer-only /root/mandelbrot_nofp ทำเสร็จได้ภายใน 9 ชั่วโมง

ต้นทุนชิ้นส่วนและความสามารถในการทำซ้ำ

  • เนื่องจากเป้าหมายสำคัญคือทำให้ผู้อื่นสามารถทำซ้ำได้ จึงหลีกเลี่ยง 4265 ที่หายาก
  • เลือก 4201 เพราะง่ายกว่าวงจร clock แบบทดแทน และเลือก 4289 เพราะหาได้ง่ายกว่าชุดผสม 4008+4009
  • บอร์ดถูกออกแบบให้ติดตั้ง 4040 ได้ด้วยนอกเหนือจาก 4004 และเนื่องจากไม่ได้ใช้ฟังก์ชันเพิ่มเติมของ 4040 จึงยังคงความเข้ากันได้กับ 4004
  • ชิป 4002 สำหรับ TLB สามารถติดตั้งได้ 1, 2, 3 หรือ 4 ตัว เพื่อใช้เป็น TLB ขนาด 4, 8, 12, 16 entry ตามลำดับ
    • หากจำนวน TLB entry น้อย ประสิทธิภาพจะลดลง
    • bank ดังกล่าวยังรับผิดชอบ high 16 bits ของ LED แสดงผล PC ด้วย ดังนั้นหากติดตั้งเพียงบางส่วน LED บางดวงจะไม่ทำงาน
  • ชิ้นส่วนจากยุค 1970 มีราคาแพง
    • 4004 ประมาณ $250
    • 4040 ประมาณ $60
    • 4201 ประมาณ $50
    • 4002-1 ประมาณ $7
    • 4002-2 ประมาณ $25
    • 4289 ประมาณ $70
  • ชิ้นส่วนสมัยใหม่มีราคาถูกกว่าค่อนข้างมาก และแม้ SPI VFD อาจหาซื้อยาก แต่ก็มีกรณีที่ซื้อได้จาก eBay ในราคา $15
  • รองรับการใช้งานแบบไม่ติดตั้ง VFD และโต้ตอบผ่าน serial port เพียงอย่างเดียว

กระบวนการทำวิดีโอ

  • ภาพการบูตจริงถูกถ่ายเป็นภาพนิ่งนานประมาณ 9 วันแล้วนำมาทำเป็นวิดีโอ
  • หากถ่ายภาพขนาด 1920x1080 ทุก 2 วินาที จะเกิดข้อมูลประมาณ 1.76GB ต่อชั่วโมง และการถ่าย 9 วันจะได้ประมาณ 379GB กับไฟล์ราว 388,000 ไฟล์
  • อุปกรณ์ Android มีปัญหา hang หรือร้อนเกินไประหว่างการถ่ายระยะยาว ส่วน iPhone SE3 แม้การถ่ายจะเสถียร แต่มีปัญหาเรื่องพื้นที่เก็บข้อมูลและการ offload รูปภาพ
  • สุดท้ายจึงใช้ iPhone 12 Pro Max ขนาด 512GB ถ่ายต่อเนื่องทั้งหมด จากนั้น mount บน Linux ด้วย ifuse แล้วคัดลอกไฟล์เกือบ 400,000 ไฟล์ด้วย cp -Rvf เป็นเวลามากกว่า 10 ชั่วโมง
  • วิดีโอสุดท้ายถูกสร้างด้วยคำสั่ง ffmpeg และช่วงที่น่าเบื่อถูกปรับเป็นความเร็วแปรผัน
    • ความเร็วการเล่นเปลี่ยนตั้งแต่ 5FPS หรือ 10x realtime ไปจนถึง 960FPS หรือ 1920x realtime
    • เวอร์ชันไม่ตัดต่อแยกต่างหากใช้ 0.5FPS capture และ 60FPS playback คิดเป็นความเร็ว 120x realtime

เอกสารที่เผยแพร่และไลเซนส์

  • disk image สำหรับ SD card มีให้ดาวน์โหลดแยกต่างหาก
  • main download มีสิ่งต่อไปนี้รวมอยู่ด้วย
    • MCS-04 bus analyzer สำหรับซอฟต์แวร์ Saleae
    • ซอร์สของ i4004 DECstation 2100 emulator
    • ซอร์สของ MIPS MBR และ second-stage bootloader
    • kernel config และข้อมูลเวอร์ชัน
    • ซอร์สของ u4004 emulator สำหรับบอร์ด Linux/4004
  • ไลเซนส์คือ ใช้ฟรีสำหรับการใช้งานที่ไม่ใช่เชิงพาณิชย์ และการใช้งานเชิงพาณิชย์ต้องใช้ไลเซนส์แยกต่างหาก
  • ไม่ว่าจะใช้งานแบบใด ในทั้ง source และ binary form ต้องให้เครดิตผู้สร้างต้นฉบับ

2 ความคิดเห็น

 
y15un 2024-09-21

คนเขียนต้นฉบับคือคนนั้นเองที่เพิ่งถูกพาตัวลงจากเวทีในงาน DEF CON เพราะเรื่องแบดจ์ครั้งนี้ ผมจะไม่เข้าข้างฝ่ายไหน แต่ถึงอย่างนั้นฝีมือของเขาก็น่าทึ่งจริง ๆ

 
GN⁺ 2024-09-21
ความคิดเห็นจาก Hacker News
  • โอ้โห เมื่อก่อนผมคิดว่า NetBSD สมัยใหม่บน m68030 15MHz, บัสหน่วยความจำ 16 บิต, RAM 10MB ก็นับว่าช้าแล้ว แต่นี่บ้าคลั่งยิ่งกว่าอีก
    มันแสดงให้เห็นชัดมากว่าในช่วงปลายยุค 80 ถึงต้นยุค 90 คอมพิวเตอร์เริ่มมีที่เก็บข้อมูลถาวร, พื้นที่แอดเดรสแบบเปิด, และ MMU จนแทบจะไปถึงการประมวลผลสมัยใหม่แล้ว
    แม้แต่ Amiga 3000 หรือคอมพิวเตอร์ i80486 ก็สามารถรันสิ่งเดียวกับคอมพิวเตอร์สมัยใหม่ได้ และแม้ตอนนี้จะรันได้เร็วขึ้นมากหรือมีของอย่าง GPU ที่สมัยนั้นยังไม่มี แต่ในเชิงฟังก์ชันแล้วก็ไม่ได้ต่างกันมาก
    ชอบที่ Dmitry แสดงให้เห็นว่าสามารถนิยามคำว่า ใช้งานได้จริง แบบกว้างแค่ไหน

    • ไม่แน่ใจว่าในอเมริกาเป็นแบบนั้นไหม แต่ในสหภาพโซเวียตช่วงยุค 70–80 หมากรุกทางจดหมาย ได้รับความนิยมมาก
      คือส่งตาเดินกันทางไปรษณีย์จริง ๆ และบางเกมกินเวลาหลายเดือนหรือหลายปี
      พอกว่าคำตอบจะกลับมา บางทีก็ลืมแผนเดิมไปแล้ว เลยเพิ่มความยากให้อีกแบบหนึ่ง และโปรเจกต์นี้ก็แทบจะเป็น Linux ทางจดหมาย
      กว่าผลลัพธ์ของคำสั่งจะออกมา คุณอาจลืมไปแล้วว่ารันคำสั่งนั้นไปทำไม
    • 15MHz m68030, บัสหน่วยความจำ 16 บิต, RAM 10MB นี่ Mac LC II หรือเปล่า? :)
      ที่จริงไม่ใช่ปลายยุค 80 หรือต้นยุค 90 ด้วยซ้ำ แต่ราวปลายยุค 60 ก็ทำได้แล้ว
      ดูแล้วน่าจะพอร์ต Linux ไปยัง IBM Model 67 [1] ได้เหมือนกัน และ GCC ก็รองรับ instruction set นั้นอยู่แล้ว เลยน่าจะไม่ยากนัก
      MMU ก็เพียงพอ ข้อจำกัดที่หนักหน่อยคือมี core memory เร็ว ๆ ได้สูงสุดแค่ 2MB แต่ก็น่าจะอยู่ระดับใกล้กับเครื่อง 68030 นั้น แค่ช้ากว่านิดหน่อย
      ทั้ง virtualisation แบบสมบูรณ์และการแบ่งเขตหน่วยความจำ/อินพุตเอาต์พุตที่ฮาร์ดแวร์บังคับใช้ ถูกคิดค้นตั้งแต่ยุคแรก ๆ แล้ว แต่กว่าจะลงมาสู่มินิคอมพิวเตอร์และไมโครคอมพิวเตอร์ก็ใช้เวลา และกว่าซอฟต์แวร์กระแสหลักจะนำไปใช้ก็ยิ่งนานกว่านั้นมาก
      [1] https://en.wikipedia.org/wiki/IBM_System/360_Model_67
    • นี่ก็คือแนวคิดของ Turing completeness โดยพื้นฐาน
      ระบบใดก็ตามที่เป็นทัวริงสมบูรณ์ย่อมรันอะไรก็ได้ อาจจะช้ามากแต่ก็ยังรันได้
      ถ้ามีเวลามากพอ แม้แต่ ChatGPT ก็รันบน 4004 ได้
    • มัลติคอร์ เป็นความต่างเชิงฟังก์ชันที่ค่อนข้างใหญ่เลย
      เหมือนเอารถยนต์ไปติดกับล้อ แล้วมีล้อเพิ่มมาอีกสามล้อ
  • ป้ายเข้างาน Hackaday Supercon 2002 (https://hackaday.com/2022/10/12/the-2022-supercon-badge-is-a...) ทำ CPU 4 บิต เสมือนขึ้นมา พร้อมแผงควบคุมที่ให้ป้อนคำสั่งเองแล้วสั่งรันหรือ step execution ได้โดยตรง
    บนแผงควบคุมมีหน้าจอที่ดูหน่วยความจำได้ทีละบิตหนึ่งหน้า และมันสนุกมากที่เอามาทำเกมยิงอวกาศบนสิ่งนั้น
    การเอาสถาปัตยกรรม Voya4 ไปเทียบกับ 4004 ก็น่าสนใจเหมือนกัน มีจุดประนีประนอมคล้ายกันอยู่บ้าง แต่ Voya4 ได้ประโยชน์จากประสบการณ์ด้าน instruction set ของ CPU ตลอด 50 ปีที่ผ่านมา
    แต่แนวทางของ dimitygr ใช้กับป้ายนี้ไม่ได้ เพราะทั้งหน่วยความจำและ RAM ต่างก็อยู่ภายใน PIC24 ที่ใช้ทำ CPU emulator อยู่แล้ว
    อนึ่ง ทุกวันนี้ก็ยังมีการผลิตและใช้งาน CPU 4 บิตอยู่ รีโมตอินฟราเรดที่ผลิตจำนวนมากหลายรุ่นถูกโปรแกรมด้วย MCU 4 บิต ดู datasheet ได้ที่ https://www.emmicroelectronic.com/sites/default/files/produc...

    • ปี 2022 ต่างหาก
  • เวลาโดนถามว่ารันอะไรสักอย่างบนเครื่องที่แรงไม่พอได้ไหม ผมมักยก ตัวอย่าง AVR ขึ้นมา ตอนนี้มีตัวอย่างใหม่ไว้ส่งลิงก์แล้ว
    พอมองจากความถี่และการใช้พลังงาน ก็ชวนสงสัยว่ามันแผ่ RF ออกมามากแค่ไหน และจะตรวจจับหรือถอดรหัสได้จาก waterfall ของ SDR หรือไม่
    ยังอ่านไม่จบ แต่ถึงจุดนี้เห็นคำว่า “soubroutine” แล้ว น่าจะเป็นคำพิมพ์ผิด

  • โอ้โห นี่คงไม่ใช่โปรเจกต์ที่จบแบบประหยัดแน่ ๆ ต้องยกความดีให้พวกนักสะสมใน eBay
    และนี่ก็น่าจะเป็นสถานการณ์เดียวที่ผมอาจเลือก LCD แทน VFD
    ถ้าปล่อยคอมไพล์เป็นปี ๆ พอจบแล้ว VFD คงมีอาการเบิร์นอินเละเทะไปหมด

    • ส่วนตัวคิดว่าเป็นโปรเจกต์ระดับควรได้ ปริญญาดุษฎีบัณฑิตกิตติมศักดิ์ เลย
      น่าเสียดายที่บุคลากรในมหาวิทยาลัยดูเหมือนจะไม่ได้อ่าน HN กันมากนัก
  • ว้าว ยอดเยี่ยมมาก
    ถ้าดูบิตสูงของ PC ก็จะเห็นได้เลยว่าตอนนี้กำลังรันอะไรอยู่
    ป.ล. ถึงอย่างนั้นมันก็ยังเร็วกว่าโหลดเคอร์เนลผ่าน virtual ISO บน IPMI ห่วย ๆ ของเซิร์ฟเวอร์ที่อยู่อีกฝั่งอินเทอร์เน็ต ;D

    • ระหว่างบูต ถ้าดู LED ไปพร้อมกับรัน nm กับ vmlinux ก็แมปเข้ากับ ฟังก์ชันของเคอร์เนล ได้ง่ายมาก
      พอเข้า user space แล้ว ยังแยกได้ด้วยว่าอันไหนคือไบนารีหลัก (ต่ำกว่า 0x01000000 มาก) และอันไหนคือ shared library (โหลดไว้ที่แอดเดรสสูงแถว 0x77000000)
    • ที่พูดถึงการโหลดเคอร์เนลผ่าน virtual ISO บน IPMI ห่วย ๆ ของเซิร์ฟเวอร์ข้ามอินเทอร์เน็ต ทำให้นึกถึงตอนพยายามบูต blade server Dell M1000e ด้วย ISO ที่โฮสต์ผ่าน NFS จาก Raspberry Pi
      ทั้งตอนบูตและตอนรันช้าจนน่าทรมาน
  • เป็นบทความที่น่าสนใจมากจริง ๆ
    ผมเคยอ่านเรื่อง 4004 มาบ้างเลยรู้ว่าเป็นชิปประหลาดตัวหนึ่ง แต่ ระดับความพิกลพิการของมัน เกินกว่าที่จินตนาการไว้มาก
    ตอนนี้เลยอยากเห็นว่าถ้าเอาจำนวนทรานซิสเตอร์เท่ากันมาทำ CPU วันนี้จะทำได้ดีแค่ไหน
    มันไม่ได้มีจำนวนน้อยกว่า 6502 มากขนาดนั้น และถ้าเป็น 8 บิตก็น่าจะเขียนโปรแกรมง่ายขึ้นมาก

    • ถ้าทำจากทรานซิสเตอร์ ผมจะพอร์ต MIPS emulator ของตัวเองไปลงบนนั้น :)
  • ใช้เวลาถ่ายวิดีโอ 9 วัน และ 1 วินาทีของการจำลองกินเวลา 4 ชั่วโมง
    แล้วก็สงสัยเหมือนกันว่าทำไมถึงใช้ Windows 95

    • เป็น Windows 2000
      สำหรับวิดีโอต้องการโน้ตบุ๊กที่มี serial port จริง ไม่ใช่ USB
      เครื่องนี้ตรงเงื่อนไขและซื้อจาก eBay มาในราคา 20 ดอลลาร์
      ส่วนตัวคิดว่า Windows 2000 เป็น Windows ที่หน้าตาดีที่สุด เลยติดตั้งไว้ใช้ในวิดีโอเดโม
    • ขอท้วงเล็กน้อยนะ แต่โน้ตบุ๊กในวิดีโอดูเหมือน Windows 2000
  • เจ๋งมาก
    หวังว่าความรู้ของตัวเองจะเพิ่มขึ้นจนพอเข้าใจโปรเจกต์นี้ได้เกือบทั้งหมด แต่ตอนนี้ด้วยพื้นฐานวิทยาการคอมพิวเตอร์ที่มีอยู่อย่างจำกัด มันยากเกินไปสำหรับฉันจริงๆ
    แต่ไฮไลต์ที่ฉันเข้าใจได้อย่างถ่องแท้จริงๆ คือ “Section 14.b & 14.c - Getting the data...”
    แค่ไฟล์ 400,000 ไฟล์ ถ่ายรูปวันละประมาณ 275 รูปเป็นเวลา 4 ปีก็พอแล้ว
    ทั้งที่ประสิทธิภาพด้านการประมวลผล การจัดเก็บ และเครือข่ายมันล้นเหลือขนาดนี้ แต่แอปซิงก์สื่อที่คนใช้กันมากที่สุดกลับค้างหรือซิงก์ช้า AirDrop ก็ล้มเหลว แถมยังอยู่ในยุคที่ไม่มีฟังก์ชัน UI อย่าง ‘เลือกทั้งหมด’ อีก เป็นยุคที่แปลกจริงๆ ที่เราอาศัยอยู่ :)

    • สงสัยว่า Dmitry เคยพิจารณาใช้เครื่องมือซิงก์อย่าง MobiusSync หรือ Syncthing เพื่อคัดลอกรูปไปยังพีซีต่อเนื่องทันทีที่ถ่ายหรือไม่
  • งานแบบนี้ควรมีอะไรอย่าง รางวัลโนเบล

    • ที่ใกล้เคียงที่สุดน่าจะเป็น Ig Nobel Prize: https://en.wikipedia.org/wiki/Ig_Nobel_Prize
    • ในสายคอมพิวติ้งก็มี Turing Award ที่พอเทียบได้
      อาจเพิ่มสาขาสำหรับการยกย่องการประยุกต์ใช้วิทยาการคอมพิวเตอร์แบบแปลกๆ พิสดารๆ ก็ได้
  • ในส่วน “Why MIPS?” มีบอกว่า “บางตัวช้าตั้งแต่ต้นเพราะรูปแบบการอ้างแอดเดรสที่แย่ (RISCV)” แล้ว รูปแบบการอ้างแอดเดรสของ RISC-V มีปัญหาอะไร?

    • จริงๆ แล้วใกล้เคียงกับการเป็นปัญหาเรื่อง รูปแบบคำสั่ง มากกว่ารูปแบบการอ้างแอดเดรส
      ในคำสั่งบางส่วนของ RISC-V บิตของ immediate จะไม่ได้ถูกเก็บไว้แบบต่อเนื่อง
      ในคำสั่งของ MIPS บิตของค่าที่ใช้กับการบวก immediate การโหลดค่าคงที่ การ branch ฯลฯ จะถูกเก็บเรียงตามลำดับเสมอ
      แต่ใน RISC-V บิตจะถูกสลับปะปนกันเป็นบางครั้ง
      ตัวอย่างเช่น ใน unconditional branch บิตของ destination offset จะถูกเก็บในลำดับ bit 19, bits 9-0, bit 10, bits 18-11
      ในฮาร์ดแวร์ แค่ต่อสายให้ถูกต้องก็แทบไม่มีต้นทุนในการจัดเรียงใหม่ แต่ในซอฟต์แวร์จำเป็นต้องจัดการบิตจำนวนมากเพื่อแก้ให้ถูกต้อง
      เหตุผลที่ RISC-V ออกแบบแบบนี้ก็เพื่อทำให้การออกแบบฮาร์ดแวร์ง่ายขึ้น
    • ถ้าไม่ได้พยายามอีมูเลตบนฮาร์ดแวร์ที่ประสิทธิภาพต่ำสุดขั้ว ก็คงแทบไม่เป็นปัญหาอะไร