<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Nebez</title><link>https://virgool.ir/feed/@nebez</link><description>Software Developer | Android &amp; Kotlin  &#xA;Building practical software and exploring Rust and computer systems through hands-on projects.  &#xA;🌐 https://nebez.ir/</description><language>fa</language><pubDate>2026-11-11 10:17:54</pubDate><image><url>https://files.virgool.ir/upload/users/4916574/avatar/vLZpOB.jpg</url><title>Nebez</title><link>https://virgool.ir/@nebez</link></image><item><title>ساخت یک بوت لودر از صفر</title><link>https://virgool.ir/@nebez/ساخت-یک-بوت-لودر-از-صفر-xegwozjy9aiw</link><description>قسمت اول مدت زیادی بود که یک سؤال ذهنم را درگیر کرده بود:داخل یک پردازنده چه اتفاقی دراه رخ میده و کدهایی که ما می‌نویسیم چطور در پایین‌ترین سطح اجرا می‌شوند؟البته از قبل میدونستم کدهایی که با زبان‌های سطح بالا مثل Java، Python، Kotlin و ... می‌نویسیم، در نهایت باید به زبان قابل فهم برای پردازنده تبدیل میشه.برای مثال در زبان Java، کدی که می‌نویسیم ابتدا توسط Compiler به Bytecode تبدیل  و سپس توسط Java Virtual Machine (JVM) اجرا شده و در نهایت به دستورهای قابل فهم برای پردازنده تبدیل می‌شوند.یعنی پشت اجرای ساده‌ترین برنامه‌ها، پردازنده در کسری از ثانیه به طرز وحشتانکی میلیاردها عملیات روی صفر و یک‌ها انجام می‌دهد.واقعاً شگفت‌انگیزه!همین کنجکاوی باعث شد خودم را به چالش بکشم و وارد دنیای جدیدی شوم؛ دنیایی که خیلی پایین‌تر از زبان‌هایی مثل Java و Python قرار دارد.شروع مسیر یادگیریاولین کاری که کردم این بود که سراغ منابع مختلف رفتم. مثل همیشه اولین مقصد هم یوتوب بود.اولین ویدیویی که با عنوان:How to build an Operating System from scratchپیدا کردم را با هیجان زیاد پلی کردم.همون ابتدای کار فمیدم هیچی میتوجه نمیشم و با احترام کامل ویدیو رو قطع کردم 😄خب متوجه شدم برای ساخت یک سیستم‌عامل از صفر، هنوز مسیر زیادی دارم و بهتره از مفاهیم پایه‌تر شروع کنم.شروع کردم به مطالعه مقاله‌ها، مشاهده ویدیوهای آموزشی و بررسی منابع مختلف تا اینکه فهمیدم بسیاری از آموزش‌های مربوط به معماری کامپیوتر و سیستم‌عامل، از معماری‌های ساده‌تر و قدیمی‌تر مثل x86 8086 شروع می‌شوند.اولین آشنایی با Intel 8086خبر خوب این بود که قرار نبود میلیون‌ها صفر و یک را دستی داخل یک فایل متنی بنویسم تا یک برنامه ساده بسازم.اما خبر نه‌چندان خوب این بود که باید Assembly یاد می‌گرفتم 😄ابتدا شروع کردم به جمع‌آوری اطلاعات درباره پردازنده Intel 8086.Intel 8086 یک پردازنده 16 بیتی بود که در سال 1978 توسط شرکت Intel معرفی شد و یکی از مهم‌ترین پردازنده‌های خانواده x86 به حساب می‌آید.برای یادگیری این معماری، ابزارهای آموزشی مثل emu8086 برای ویندوز وجود دارند که به ما اجازه می‌دهند کد Assembly بنویسیم، آن را اجرا کنیم و Registerها و Flagهای پردازنده را مرحله‌به‌مرحله مشاهده کنیم.واقعا برام موضوع جالبی بودفکر کن بتونی ببینی پردازنده دقیقاً چه دستورهایی را اجرا می‌کنه، مقدار Registerها چگونه تغییر میده و وضعیت CPU در هر لحظه چیه!اما ...من اصلاً نمیدونستم Register چیه، Flag چیه، Memory Addressing یعنی چه و این چیه اون چیه؟؟؟!!!برای همین چند روز زمان گذاشتم تا ابتدا معماری x86 را بهتر درک کنم.البته باید اعتراف کنم، برای کسی که تازه از دنیای:print(&#34;hello world&#34;)وارد دنیای پردازنده شده، دیدن ساختار داخلی CPU کمی ترسناکه 😄نگاهی ساده به ساختار 8086 credit: ElectronicsMind - Intel 8086 Microprocessor Architectureپردازنده 8086 از بخش‌های مختلفی تشکیل شده است، اما برای شروع می‌توانیم مهم‌ترین بخش‌ها را بررسی کنیم.Execution Unit (EU)واحد اجرا مسئول تفسیر و اجرای دستورهاست.این بخش شامل قسمت‌هایی مثل:ALU (Arithmetic Logic Unit) برای انجام عملیات محاسباتی و منطقیRegisterهای عمومیRegister مربوط به FlagهاBus Interface Unit (BIU)واحد ارتباط با باس مسئول ارتباط CPU با حافظه و دریافت دستورها از RAM .این بخش شامل:Segment RegisterهاInstruction Pointer (IP)منطق تولید آدرس حافظهRegistersRegisterها حافظه‌های بسیار کوچک و بسیار سریع داخل CPU اند و نزدیک به خود پردازنده اند.پردازنده برای انجام عملیات‌هایی مثل محاسبات، انتقال داده و اجرای دستورها، نمی‌تواند همیشه مستقیماً با RAM کار کند؛ چون سرعت RAM کمتر از سرعت CPU است.به همین دلیل CPU از Registerها به عنوان یک فضای کاری بسیار بسیار سریع استفاده می‌کنه تا داده‌هایی که بیشتر به آن‌ها نیاز دارد، نزدیک به واحد پردازش قرار بگیرند.در برنامه‌نویسی سطح پایین (Low-Level Programming)، Registerها یکی از مهم‌ترین ابزارهای ارتباط مستقیم با CPU هستند.بعضی Registerها برای نگهداری داده، بعضی برای آدرس‌دهی حافظه، بعضی برای مدیریت Stack و بعضی برای کنترل روند اجرای برنامه استفاده می‌شوند.در واقع ما قرار است با همین خانه‌های کوچک داخل CPU، اجرای برنامه را مرحله‌به‌مرحله کنترل کنیم.اولین اجرای کد Assemblyبعد از اینکه یک دید کلی نسبت به معماری پردازنده پیدا کردم، به خودم گفتم:«تا وقتی دست به کد نشوم، این مفاهیم را واقعاً درک نمی‌کنم.»برای همین تصمیم گرفتم اولین برنامه Assembly خودم را بنویسم.ابتدا سراغ emu8086 رفتم، اما خیلی با محیطش ارتباط نگرفتم و ترجیح دادم از ویرایشگر محبوب خودم یعنی Vim استفاده کنم.برای آماده‌سازی محیط توسعه، ابزارهای مورد نیاز رو توی لینوکس نصب کردم:Ubuntu / Debian: &#xA;&#xA;- sudo apt update&#xA;- sudo apt install nasm qemu-system-x86 gdb binutils&#xA;&#xA;Fedora:&#xA;- sudo dnf install nasm qemu-system-x86 gdb binutils&#xA;&#xA;برای اطمینان از نصب : &#xA;&#xA;- nasm -version&#xA;- qemu-system-i386 --version&#xA;- gdb --versionWindows&#xA;- choco install nasm qemu gdb&#xA;&#xA;برای اطمینان از نصب : &#xA;&#xA;&#xA;nasm -version&#xA;qemu-system-i386 --version&#xA;gdb --versionابزارهای اصلی که استفاده کردم:NASM برای تبدیل Assembly به فایل BinaryQEMU برای اجرای Bootloader در محیط شبیه‌سازی‌شدهGDB برای Debug کردن CPU و بررسی RegisterهاBinutils برای بررسی فایل‌های Binaryاز روشن شدن سیستم تا اجرای اولین Bootloaderحالا که یک آشنایی اولیه با CPU و معماری 8086 پیدا کرده بودم، وقت آن رسیده بود بفهمم وقتی یک سیستم روشن می‌شود دقیقاً چه اتفاقی می‌افتد.چطور کامپیوتری که هنوز هیچ برنامه‌ای اجرا نکرده، می‌تواند اولین کد را اجرا کند؟اینجا بود که با مفهوم Boot Process آشنا شدم.Bootloader چیست؟به زبان ساده، Bootloader یک برنامه کوچک است و در اولین مراحل روشن شدن سیستم اجرا می‌شود و وظیفه دارد سیستم را برای اجرای مراحل بعدی آماده کند.در سیستم‌عامل‌های واقعی، Bootloader معمولاً وظیفه دارد Kernel را از حافظه ذخیره‌سازی پیدا کرده و آن را داخل RAM بارگذاری کند.اما برای شروع یادگیری، تصمیم گرفتم یک Bootloader بسیار ساده بنویسم که فقط یک کار انجام دهد:نمایش یک کاراکتر روی صفحه نمایش.شاید ساده به نظر برسد، اما همین کار ساده یعنی من دارم اولین کدی را اجرا می‌کنم که قبل از وجود هر سیستم‌عاملی، مستقیماً توسط CPU اجرا می‌شود.هنگام روشن شدن کامپیوتر چه اتفاقی می‌افتد؟به صورت خلاصه روند Boot شدن یک سیستم مبتنی بر BIOS به این شکل است:Power On&#xA; |&#xA;&#xA;   ↓&#xA;&#xA;CPU Reset&#xA;&#xA;   |&#xA;&#xA;   ↓&#xA;&#xA;BIOS starts executing&#xA;&#xA;   |&#xA;&#xA;   ↓&#xA;&#xA;POST (Power-On Self Test)&#xA;&#xA;   |&#xA;&#xA;   ↓&#xA;&#xA;Find Boot Device&#xA;&#xA;   |&#xA;&#xA;   ↓&#xA;&#xA;Load Bootloader into RAM&#xA;&#xA;   |&#xA;&#xA;   ↓&#xA;&#xA;Jump to Bootloader Code&#xA;&#xA;   |&#xA;&#xA;   ↓&#xA;&#xA;Bootloader executes&#xA;حالا کمی دقیق‌تر این مراحل را بررسی کنیم.1. روشن شدن سیستموقتی دکمه Power را فشار می‌دیم، CPU از حالت Reset خارج می‌شه و اجرای اولین دستورهای خود را آغاز می‌کند.2. اجرای BIOSدر سیستم‌های قدیمی مبتنی بر BIOS، کنترل اولیه به Firmware سیستم منتقل می‌شود.BIOS مخفف:Basic Input/Output Systemاست و وظیفه دارد سخت‌افزارهای اصلی سیستم را بررسی و آماده کند.در این مرحله تستی به نام:POST (Power-On Self Test)انجام می‌شود که مواردی مثل:RAM&#xA;Keyboard&#xA;Display&#xA;Storage Devicesرا بررسی می‌کند.3. پیدا کردن Boot Deviceبعد از موفقیت POST، BIOS طبق ترتیب Boot مشخص‌شده دنبال یک دستگاه قابل بوت می‌گردد.برای مثال:Hard Drive&#xA;USB&#xA;CD/DVD4. پیدا کردن Bootloaderدر سیستم‌های BIOS سنتی، BIOS اولین سکتور دستگاه Bootable را بررسی می‌کند.این سکتور باید دارای یک امضای مخصوص در دو بایت آخر خود باشد:0x55AAکه به آن:Boot Signatureگفته می‌شود.اگر این امضا وجود داشته باشد، BIOS متوجه می‌شود که این سکتور شامل کد قابل اجرا برای Boot است.سپس این 512 بایت را به آدرس مشخصی از حافظه RAM منتقل می‌کند:0x7C00و کنترل اجرای برنامه را به CPU می‌سپارد.از این لحظه به بعد، کدی که ما نوشته‌ایم شروع به اجرا می‌کند.اولین Bootloader منبعد از اینکه مفهوم Boot Process را فهمیدم، وقت آن بود که اولین کد خودم را بنویسم.هدف خیلی ساده بود:فقط نمایش حرف:&#xA;Nروی صفحه.کد:[bits 16]&#xA;org 0x7c00&#xA;&#xA;mov ah, 0x0e&#xA;&#xA;mov al, &#39;N&#39;&#xA;&#xA;int 0x10&#xA;&#xA;times 510 - ($ - $$) db 0&#xA;&#xA;dw 0xAA55&#xA;بررسی کداین Bootloader ساده در حالت:16-bit Real Modeاجرا می‌شود.مشخص کردن حالت پردازنده[bits 16]به Assembler می‌گوید که کد ما برای پردازنده 16 بیتی نوشته شده است.محل قرارگیری Bootloaderorg 0x7c00به Assembler اعلام می‌کند که این کد قرار است در آدرس 0x7C00 در حافظه اجرا شود.این همان آدرسی است که BIOS معمولاً Boot Sector را در آن قرار می‌دهد.قرار دادن مقدار در Registerهاmov ah, 0x0e&#xA;mov al, &#39;N&#39;در این قسمت مقدارهای مورد نیاز را داخل Registerهای CPU قرار می‌دهیم.برای درک ساده‌تر، می‌توان آن را شبیه مقداردهی متغیرها در زبان‌های سطح بالا تصور کرد:int value = 0x0e;اما تفاوت مهم اینه که در Assembly ما با متغیرهای ساخته‌شده توسط Compiler کار نمی‌کنیم، بلکه مستقیماً Registerهای واقعی داخل CPU را کنترل می‌کنیم.در اینجا:مقدار 0x0E داخل Register مربوط به AH قرار می‌گیرد.کاراکتر N داخل Register مربوط به AL قرار می‌گیرد.مقدار 0x0E یک Service Number برای BIOS است که مشخص می‌کند قصد داریم یک کاراکتر را در حالت Teletype Mode نمایش دهیم.فراخوانی BIOS Interruptint 0x10این دستور یک:BIOS Video Interruptرا فراخوانی می‌کند.کنترل به سرویس‌های ویدیویی BIOS منتقل می‌شود تا عملیات نمایش کاراکتر انجام شود.تکمیل Boot Sectorیک Boot Sector باید دقیقاً 512 بایت باشد.برای همین:times 510 - ($ - $$) db 0فضای باقی‌مانده فایل را با صفر پر می‌کند تا بوت لودری که نوشتیم دقیقا 512 بایت باشد.و در پایان:dw 0xAA55امضای Boot را قرار می‌دهد تا BIOS بتواند این سکتور را به عنوان Bootloader معتبر شناسایی کند به بهش مجیک نامبر هم میگن تا تایید شود این یک بوت لودر است.Build و اجرای Bootloaderبعد از نوشتن کد، فایل را با نام:boot.asmذخیره کردم.سپس با استفاده از NASM آن را به فایل Binary تبدیل کردم:nasm -f bin boot.asm -o boot.binو برای اجرا از QEMU استفاده کردم:qemu-system-i386 -fda boot.bin&#xA;یا از دستوری&#xA;qemu-system-x86_64 -fda boot.binو نتیجه؟خروجی بوت لودر روی شبیه ساز qemuیک حرف ساده روی صفحه ظاهر شد:Nاما برای من این فقط یک کارکار نبود.این اولین باری بود که کدی که خودم نوشته بودم، بدون وجود سیستم‌عامل و بدون هیچ Runtime یا Framework، مستقیماً توسط CPU اجرا می‌شد.همین لحظه بود که فهمیدم چرا دنیای Low-Level Programming اینقدر جذاب است.در پایین‌ترین سطح، دیگر خبری از لایه‌های آماده نیست.اینجا شما، CPU، حافظه و چند دستور ساده Assembly هستید.ادامه مسیراین تجربه فقط یک شروع کوچک بود.با نوشتن همین Bootloader ساده، علاقه من به دنیای Low-Level Programming بیشتر شد و تصمیم گرفتم مسیر یادگیری را ادامه بدهم.لینک اولین بوت لودر من در گیت هاب : https://github.com/Nebez-Berzency/simple-bootloader</description><category>Nebez</category><author>Nebez</author><pubDate>Sun, 02 Aug 2026 01:26:40 +0330</pubDate></item></channel></rss>