ابوالفضل کاظمی
ابوالفضل کاظمی
خواندن ۱۲ دقیقه·۵ سال پیش

آشنایی با MBR و ساختار پارتیشن‌ها

آیا تا به حال این سوال برایتان پیش آمده است که حداکثر تعداد پارتیشن بر روی یک هارد چه تعداد است؟ یا اینکه بعد از روشن کردن کامپیوتر چه اتفاقی افتاده و از کجا مشخص می‌شود که از روی کدام پارتیشن سیستم‌عامل بارگذاری شده و شروع به اجرا شدن می‌کند؟ آیا به این نکته توجه نموده‌اید که کوچکترین واحد ذخیره‌سازی اطلاعات بر روی دیسک چقدر است؟ آیا این مقدار برابر یک بایت بوده و یا مقدار بیشتری دارد؟ (شاید مقدار کوچک‌ترین واحد ذخیره‌سازی اطلاعات به نظر بی اهمیت برسد ولی در سرعت خواندن/نوشتن و میزان فضای هرز ایجاد شده بر روی دیسک تاثیر زیادی دارد) در این مقاله قصد داریم به این سوالات و سوالات دیگری پیرامون این موضوع پاسخ گوییم.

مشاهده‌ی ویدئو مرتبط با مقاله: چند جلسه‌ای فرصت ارائه‌ی مطالبی در کلاس آزمایشگاه سیستم‌عامل دانشگاه علم‌وصنعت که توسط دکتر فردباستانی ارائه میشد را داشتم و یکی از این جلسات به شرح روال بوت شدن لینوکش و ساختار MBR گذشت که مرتبط با مطالب این مقاله است. اگر علاقه داشتید می‌تونید فیلم این جلسه را در آپارات مشاهده کنید.

برگردیم به ادامه‌ی مقاله! داده‌های ذخیره شده بر روی هارددیسک در بلوک‌هایی به اندازه‌ی ۵۱۲بایت ذخیره می‌شوند که به این بلوک‌ها sector گفته می‌شود. این مقدار، کوچکترین میزان فضایی است که داده‌ای بر روی هارددیسک اشغال می‌کند. یعنی اگر شما حتی یک حرف یک بایتی مثل A‌ را ذخیره کنید، مقدار فضایی که اشغال کرده‌اید برابر با ۵۱۲بایت می‌باشد. البته قضیه به اینجا ختم نمی‌شود و مقدار دقیق فضای اشغال شده ۵۱۲بایت نیست. علت این امر این است که شما به صورت مستقیم و با استفاده از interrupt داده‌ای بر روی دیسک ذخیره نکرده و از سیستم‌عامل (در واقع با استفاده از SystemCall‌های مربوط به کار با سیستم‌فایل) کمک گرفته و از لایه‌ی File System عبور کرده و سپس داده را بر روی دیسک و در یک کلاستر ذخیره می‌کنید. هر کلاستر مجموعه‌ای از چند سکتور بوده و کوچکترین فضای ذخیره‌سازی است که توسط سیستم‌فایل ارائه می‌شود. این موضوع باعث می‌شود که مقدار فضای اشغال شده از ۵۱۲بایت بیشتر شده و مضربی از ۵۱۲بایت باشد. در بسیاری از سیستم‌های فایل امروزی مثل NTFS, Ext4 مقدار پیش‌فرض اندازه‌ی کلاستر برابر 4KB می‌باشد. البته به این نکته هم دقت کنید که این مقدار برای پارتیشن‌ها با اندازه‌های مختلف می‌تواند متفاوت بوده و حتی شما می‌توانید در زمان Format کردن یک پارتیشن مقدار آنرا خودتان مشخص کنید.

اولین sector هارددیسک (اولین 512bytes اشغال شده) که مهمترین سکتور نیز است، با عنوان (Master Boot Record - MBR) شناخته می‌شود که پس از روشن شدن کامپیوتر و بارگذاری BIOS خوانده شده و اطلاعاتی دارد که برای پیدا کردن سیستم‌عامل، بارگذاری آن و دسترسی به اطلاعات پارتیشن‌ها مورد نیاز است و در صورتیکه این سکتور خراب شده و یا قابل دسترسی نباشد، با خطایی مواجه شده و امکان شروع به کار سیستم‌عامل وجود نخواهد داشت. در این ۵۱۲بایت، مقدار ۶۴بایت برای ذخیره‌ی اطلاعات پارتیشن‌ها در نظر گرفته شده است که با استفاده از آن امکان تعریف ۴ پارتیشن وجود داشته و برای هر پارتیشن ۱۶ بایت اطلاعات ذخیره می‌شود. پس با توضیحات ارائه شده مشخص می‌شود که بر روی هر دیسک ۴ پارتیشن بیشتر نمی‌توان ایجاد نمود. (مگر در حالت استفاده از درایو منطقی که در ادامه در مورد آن صحبت خواهد شد) از این ۴ پارتیشن یکی می‌تواند به عنوان پارتیشن Extended معرفی شده (و یا اصلا وجود نداشته باشد) و مابقی، پارتیشن‌های Primary می‌باشند. در MBR کد مربوط به پیدا کردن سیستم‌عامل و بارگذاری BootLoader آن در ۴۴۶ بایت ابتدایی سکتور نوشته شده و از Offset شماره ۴۴۶ مقدار ۶۴ بایت اطلاعات پارتیشن‌ها را در بر می‌گیرد. دوبایت آخر MBR نیز (510==64+446) همیشه مقدار 0xAA55 را در بر می‌گیرند.

نکته: این ساختار در کامپیوترهایی وجود دارد که از BIOS و MBR استفاده می‌کنند و در کامپیوترهایی که UEFI و GPT دارند وجود ندارد.

در شکل ۱ نحوه‌ی استخراج داده‌ی MBR‌ و نمایش آن به صورت Hex در لینوکس، قابل مشاهده است. دستور dd امکان کپی‌برداری از اطلاعات دیسک را فراهم می‌کند و همانطور که در شکل ۱ نمایش داده شده است مقدار ۵۱۲بایت از ابتدای دیسک اول (sda) کپی شده و در فایلی به نام mbr.img ذخیره می‌شود. (نام دیسک‌های sata, scsi در لینوکس با sd شروع شده و پس از آن، اولین دیسک sda، دومی sdb و... نام‌گذاری می‌شوند)

دستور xxd نیز برای hex dump استفاده می‌شود که بایت‌های یک فایل را در مبنای ۱۶ نمایش می‌دهد. در سمت چپ Offset هرخط، در وسط مقدار در مبنای ۱۶ و در سمت راست مقدار ASCII اطلاعات نمایش داده شده است. در اطلاعات نمایش داده شده عبارت GRUB‌ مشاهده می‌شود که از آن می‌توان برداشت کرد که این MBR مربوط به سیستمی لینوکسی می‌باشد! در خط آخر (از Offset شماره 1f4==500 تا 1ff==511) و در مکان دو بایت آخر (یعنی در مکان‌های 510 و 511) مقدار 0xAA55 مشاهده می‌شود. (این مقدار که Signature مربوط به MBR است را من به صورت Little-Endian نوشتم که بایت با ارزش کمتر در Offset کمتر قرار می‌گیرد) در صورت عدم وجود این مقدار در انتهای MBR خطای Missing Operating System داده خواهد شد.

شکل ۱) استخراج MBR و نمایش آن در لینوکس
شکل ۱) استخراج MBR و نمایش آن در لینوکس

همانطور که در بخش قبلی به آن اشاره شد، از Offset شماره ۴۴۶ اطلاعات پارتیشن‌ها ذخیره می‌شود که به ۴ بخش ۱۶ بایتی تقسیم می‌شوند. از جمله اطلاعاتی که در ۱۶بایت مربوط به هر پارتیشن قرار می‌گیرد و برای ما اهمیت دارد موارد زیر می‌باشند:

  • بایت اول (شماره‌ی صفر) Active بودن پارتیشن را مشخص کرده و می‌تواند دو مقدار 0x80 و 0 را داشته باشد. مقدار 0x80 که تنها به پارتیشن‌های Primary داده می‌شود، بیانگر پارتیشنی است که سیستم‌عامل بر روی آن نصب شده و باید Boot Loader سیستم‌عامل از روی آن بارگذاری شود. این مقدار تنها برای یک پارتیشن باید ست شده و در غیر این صورت در زمان بارگذاری سیستم‌عامل با خطای Invalid Boot Partition مواجه می‌شویم.
  • بایت شماره‌ی ۴ نوع پارتیشن را مشخص می‌کند. به عنوان مثال مقدار 0 برای خالی بودن، 0x05 برای Extended و 0x07 برای NTFS و 0x83 برای Linux‌ مورد استفاده قرار می‌گیرند.
  • بایت‌های شماره‌ی ۸ تا ۱۱ برای (Logical Block Addressing - LBA) مورد استفاده قرار می‌گیرند. (چهاربایت که اولین بایت، کمترین ارزش و آخرین بایت، بیشترین ارزش را دارد) از این مقدار برای Offset شروع پارتیشن استفاده می‌شود و تعداد سکتوری (دقت شود که سکتور و نه بایت) را مشخص می‌کند که از ابتدای دیسک باید رد کنیم تا به ابتدای پارتیشن برسیم.
  • بایت‌های شماره‌ی ۱۲ تا ۱۵ نیز اندازه‌ی پارتیشن به تعداد سکتور را مشخص می‌کنند.

در شکل ۲ بخش‌های توضیح داده شده و مابقی بخش‌های تشکیل دهنده‌ی MBR نمایش داده شده است.

شکل ۲) ساختار پارتیشن‌ها در MBR
شکل ۲) ساختار پارتیشن‌ها در MBR

برای درک دقیق‌تر موضوع بیایید از شکل ۱ کمک گرفته و سکتور شروع و اندازه‌ی پارتیشن اول را محاسبه کرده و سپس با خروجی دستور fdisk مقایسه کنیم. طبق توضیحات ارائه شده، سکتور شروع از روی مقدار LBA‌ محاسبه می‌شود که ۸ بایت از ابتدای اطلاعات پارتیشن جلوتر بوده و طول آن ۴ بایت است. همچنین شروع اولین پارتیشن از Offset با مقدار ۴۴۶ می‌باشد که این نتیجه را می‌رساند که باید 8+446==1C6 بایت از ابتدای MBR به جلو رفته و از آنجا 4 بایت را برای محاسبه‌ی مقدار LBA‌ برداریم. با دقت در مقدار Offset نمایش داده شده در شکل ۱ متوجه می‌شویم که اطلاعات مورد نیاز ما در خط سوم از پایین قرار دارد. این خط دارای Offset با مقدار 1C2 می‌باشد که ۴ بایت عقب‌تر از مقدار مورد نیاز ما برای شروع LBA یعنی همان 1C6 است. پس بایت پنجم از این خط شروع LBA را دارد. نکته‌ی دیگری که حائز اهمیت است این موضوع است که اولین بایت کم ‌ارزش‌ترین است و ارزش بایت بعدی ۲۵۶ برابر بایت قبلی می‌باشد. (هر بایت ۸ بیت بوده و در نتیجه pow(2,8)==256 برابر بایت قبلی ارزش دارد) در این بخش ۴ بایت مربوط به LBA مقدار 0x00080000 داشته و با محاسبه‌ی زیر به این نتیجه میرسیم که ۲۰۴۸ سکتور باید از ابتدای دیسک به جلو حرکت کنیم تا به ابتدای پارتیشن اول برسیم.

به طریق مشابه برای بدست آوردن اندازه‌ی پارتیشن باید به ابتدای بایت 446+12==1CA رفته و ۴بایت را برداشته و اندازه‌ی پارتیشن را بدست آورد. (در خط سوم از پایین، چهاربایت ستون‌های ۵و۶ در شکل ۱ که مقدار 0x00008018 را تشکیل می‌دهند)

اجرای دستور fdisk بر روی فایل mbr.img و بررسی صحت این اطلاعات در شکل ۳ نمایش داده شده است. دقت شود که به دلیل کپی نگرفتن از تمامی اطلاعات دیسک، اطلاعات پارتیشن‌های Extended کامل نبوده و fdisk خطایی می‌دهد. (در ادامه با ساختار کامل این پارتیشن‌ها و دلیل این خطا آشنا می‌شویم)

شکل ۳) چک کردن اطلاعات پارتیشن‌ها با دستور fdisk
شکل ۳) چک کردن اطلاعات پارتیشن‌ها با دستور fdisk

تا اینجای بحث توضیح دادیم که ۴ بخش برای اطلاعات ۴ پارتیشن وجود دارد که یکی از این ۴تا می‌تواند از نوع Extended باشد. این نوع پارتیشن امکان ایجاد Logical Drive را فراهم می‌کند. از دید سیستم‌عامل و کاربر نهایی Logical Driveها نیز مشابه پارتیشن‌های دیگر بوده و فقط افزودن تعداد درایوها و رسیدن به تعداد درایور بیشتر از ۴ را فراهم می‌کنند.(البته منهای اینکه نمی‌توانند Active بوده و برای بوت سیستم‌عامل مورد استفاده قرار گیرند!!) روال کار به این شکل است که یک لیست پیوندی ایجاد شده که این پارتیشن Extended به عنوان Headعمل کرده و اشاره کننده به اولین Logical Drive است. (مقدار LBA این پارتیشن به ابتدای اولین سکتور از اولین درایو اشاره کرده و Size آن اندازه‌ی کلیه‌ی درایوها در مجموع و فضایی که تشکیل می‌دهند را مشخص می‌کند)

در هر Logical Drive اولین سکتور با نام (Extended Boot Record - EBR) شناخته شده و ساختاری مشابه MBR دارد که از ۴ بخش مربوط به پارتیشن‌ها، تنها ۲ بخش استفاده شده که بخش مربوط به پارتیشن اول، اطلاعات درایو فعلی را در بر گرفته و بخش دوم، اشاره‌گر به Logical Drive بعدی می‌باشد. در انتهای کار و پس از رسیدن به آخرین درایو، مقدار فیلد type (نوع پارتیشن در بایت شماره‌ی ۴) پارتیشن دوم EBR (که اشاره‌گر به درایو بعدی بود) برابر صفر خواهد بود. (همان NULL در انتهای لیست پیوندی ساده) این ساختار در شکل ۴ نمایش داده شده است.

شکل ۴) ساختار پارتیشن‌های Extended
شکل ۴) ساختار پارتیشن‌های Extended

نکته مهم: در Logical Driveها مقدار LBA مشخص شده در پارتیشن اول EBR، نسبت به درایو قبلی بوده و از ابتدای محل Extended و یا ابتدای دیسک نمی‌باشد. این نکته بر خلاف پارتیشن‌های Primary است که LBA مقدار Offset را از ابتدای دیسک مشخص می‌کند.

برای بررسی عملی توضیحات ارائه شده، با استفاده از دستور dd سکتور مربوط به EBR را خوانده و اطلاعات نمایش داده شده توسط آنرا بررسی می‌نماییم. اولین مرحله پیدا کردن آدرس شروع EBR است. برای اینکار از شکل ۳ و خروجی دستور fdisk -l mbr.img استفاده می‌کنیم. در خط دوم این خروجی اطلاعات یک پارتیشن Extended‌ نمایش داده شده است. همانطور که در این شکل مشاهده می‌شود اگر از ابتدای دیسک 411045886 سکتور را رد کنیم به ابتدای EBR می‌رسیم. با استخراج EBR‌ می‌توانیم اطلاعات آنرا مشابه کاری که با MBR انجام دادیم بررسی نموده و اندازه‌ی پارتیشن آنرا بدست آوریم. استخراج EBR و بررسی آن به کمک fdisk در شکل ۵ نمایش داده شده است.

شکل ۵) استخراج و بررسی EBR
شکل ۵) استخراج و بررسی EBR

در شکل ۵ مشخص است که درایو منطقی که درون Extended ایجاد شده است از نوع Swap بوده و شروع آن ۲سکتور بعد از شروع Extended می‌باشد (یعنی از سکتور 411045888 که برابر است با start_of_extended + start_of_partition ) جمع بندی نهایی و نمایش کلیه‌ی اطلاعات دیسک با استفاده از اجرای fdisk بر روی sda در شکل ۶ نمایش داده شده است.

شکل ۶) نمایش اطلاعات دیسک به صورت کامل
شکل ۶) نمایش اطلاعات دیسک به صورت کامل

در این مقاله سعی کردم ساختار MBR را معرفی کرده و نحوه‌ی ذخیره‌ی اطلاعات پارتیشن‌ها در آنرا شرح دهم. برای بررسی این موضوع و تست عملی یک کد پایتون ساده هم نوشته بودم که به‌همراه فایل‌های دیسک، MBR, EBR در github گذاشته‌ام و می‌تونید برای تست ازش استفاده کنید. کد نوشته شده تمامی شرایط رو در نظر نمی‌گیره و تمامی حالت‌های خطا در اون بررسی نشده ولی برای اینکه یک تستی انجام بدید و بررسی دقیق مطالب گفته شده رو ببینید مفیده. در آخر مقاله هم اسم یک کتاب خوب که برای نوشتن مقاله ازش کمک زیادی گرفتم رو می‌گذارم که علاقه داشتید بخونید. همچنین لازمه بگم که عکس مربوط به پارتیشن‌های Extended از سایت مایکروسافت گرفته شده.

امیدوارم مفید بوده باشه، موفق باشید.

Reference:

  • Linux Forensics (2015) - Philip Polstra
mbrlinuxbootgrub
شاید از این پست‌ها خوشتان بیاید