پورت کردن Mac OS X روی Nintendo Wii!
خلاصهٔ کاملتر
وقتی یه نفر توی Reddit نوشته بود «صفر درصد شانس داره این اتفاق بیفته»، این مهندس دقیقاً همون کار رو کرد: Mac OS X 10.0 Cheetah رو بهصورت native روی Nintendo Wii راه انداخت. قبل از این، لینوکس، NetBSD و ویندوز NT هم روی ویی پورت شده بودن، ولی حالا نوبت اولین نسخه macOS بود.
اولین سوال این بود که آیا اصلاً ممکنه؟ ویی از پردازنده PowerPC 750CL استفاده میکنه که تکاملیافتهی همون PowerPC 750CXeایه که توی مکهای G3 بهکار میرفت. این شباهت خانوادگی یعنی CPU از نظر معماری کاملاً سازگاره. از نظر RAM هم ویی ۸۸ مگابایت داره (۲۴ مگ MEM1 و ۶۴ مگ MEM2) که اگرچه کمتر از ۱۲۸ مگ پیشنهادی Cheetahه، ولی با تست روی QEMU ثابت شد که سیستم با ۶۴ مگ هم بالا میاد.
از نظر نرمافزاری، هسته Mac OS X یعنی Darwin و کرنل XNU متنبازه. بنابراین اگه بشه این بخش رو تغییر داد و روی ویی راه انداخت، بقیهی اجزای بستهکد مثل Quartz و Finder بدون پچ اضافهای اجرا میشن.
مکهای PowerPC از Open Firmware بهعنوان اولین لایه نرمافزاری استفاده میکنن که وظیفهاش شناسایی سختافزار، ساختن device tree و لود کردن بوتلودر BootXه. BootX هم کرنل XNU رو لود میکنه و کنترل رو بهش میده. اما از اونجایی که XNU بعد از شروع بهکار هیچ وابستگی به Open Firmware یا BootX نداره، پورت کردن هر کدوم از اونها اتلاف وقت بود. پس تصمیم گرفته شد یه بوتلودر سفارشی از صفر نوشته بشه.
بوتلودر سفارشی بهاسم wiiMac بر پایهی ppcskel ساخته شده. وظیفهاش اینه که سختافزار ویی رو initialize کنه، کرنل رو از SD کارت بخونه، یه device tree بسازه و کنترل رو به کرنل بده. کرنل XNU توی فرمت Mach-O ذخیره میشه و بوتلودر باید load commandهاش رو پردازش کنه تا بخشهای مختلف فایل رو در آدرس درست حافظه قرار بده.
برای پاس دادن کنترل به کرنل، آدرس entry point بهصورت یه تابع cast میشه و صدا زده میشه:
(*(void (*)())kernel_entry_point)(boot_args_address, MAC_OS_X_SIGNATURE);بعد از اجرای این خط، صفحه سیاه شد و لاگهای debug قطع شدن — که خودش نشانهی خوبی بود! ولی سوال اینجا بود که کرنل تا کجا پیش میره؟ چون کرنل XNU در اولین قدمهاش همه تنظیمات بوتلودر رو override میکنه و امکان debug سریال رو هم از بین میبره.
راهحل خلاقانه این بود که کرنل بهصورت binary پچ بشه: دستوراتی جاگذاری بشن که LED جلوی پنل ویی رو روشن کنن. اگه LED روشن میشد، یعنی کرنل تا اون نقطه رسیده. این کار با نوشتن یه مقدار به یه آدرس حافظه خاص انجام میشه، که در اسمبلی PowerPC اینطوریه:
lis r5, 0xd80 ; load upper half of 0x0D8000C0 into r5
ori r5, r5, 0xc0 ; load lower half of addressاین پروژه نشون میده که با ترکیب دانش معماری سختافزار، بوتلودر نویسی، پچ کرنل و درایور نویسی، میشه کارهایی کرد که خیلیها «غیرممکن» میدونن. کد بوتلودر wiiMac روی GitHub در دسترسه و هر کسی میتونه خودش این تجربه رو داشته باشه.
نکات کلیدی:
- Nintendo Wii از PowerPC 750CL استفاده میکنه که معماریاش با مکهای G3 سازگاره
- Mac OS X 10.0 Cheetah با ۶۴ مگابایت RAM هم بالا میاد (کمتر از حداقل رسمی ۱۲۸ مگ)
- یه بوتلودر سفارشی (wiiMac) از صفر نوشته شده که جایگزین Open Firmware و BootX میشه
- کرنل XNU در فرمت Mach-O ذخیرهست و باید load commandهاش پردازش بشن
- برای debug کرنل از تکنیک پچ باینری و روشن کردن LED فیزیکی ویی استفاده شده
- کد بوتلودر در مخزن wiiMac روی GitHub موجوده




