Amirreza Hosseini
Amirreza Hosseini
خواندن ۱۶ دقیقه·۳ سال پیش

آموزش کامل تعمیر و نصب مجدد بوت لودر Grub2


اگه به تازگی شروع به یاد گیری سیستم عامل های خانواده Gnu/Linux کرده باشید ، احتمالا برای شما هم پیش اومده که بعد از نصب ویندوز در کنار لینوکس یه دفعه دیدین که دیگه به لینوکس تون دسترسی ندارین.و مستقیم وارد ویندوز میشین . شاید هم همین موضوع و درگیری با Bootloader ها باعث شده باشه که قید نصب کردن لینوکس در کنار ویندوز رو بزنید . و فقط روی ماشین مجازی از linux استفاده کنید. این مشکل ممکنه علت های مختلفی داشته باشه. ولی اصل ماجرا مربوط به خراب شدن بوت لودر Grub2 میشه.

در این مطلب به بررسی حالت های مختلف تعمیر بوت لودر Grub2 در لینوکس می پردازیم. پس تا انتها با من همراه باشید تا جواب همه سوالاتتون در این باره رو بگیرین. و به راحتی مشکلتون رو حل کنید.

تمامی مواردی که توی این مقاله گفتم ، به صورت کامل توی این ویدیو که لینکشو این پایین گذاشتم داخل یوتیوب توضیح دادم و میتونید ازش استفاده کنید :)

تعمیر گراب

اول از همه باید بدونیم که یک سیستم عامل لینوکسی چجوری boot میشه و بالا میاد. بعدش راحت تر می تونیم اون رو تعمیر کنیم.

مراحل بوت شدن یک سیستم عامل Linux Based :

بلا فاصله بعد از اینکه شما کامپیوتر رو روشن می کنید به ترتیب یکسری مراحل به ترتیب طی میشه که می تونید اون ها رو در تصویر زیر مشاهده کنید.

مراحل Boot شدن یک سیستم عامل لینوکسی
مراحل Boot شدن یک سیستم عامل لینوکسی

فرآیند power-on self-test یا POST :

بعد از روشن شدن کامپیوتر فرآیند Post یا Power on Self test شروع میشه. توی این مرحله سلامتی سخت افزار های مهم کامپیوتر تست میشه. و اگه همه چیز اوکی باشه و قطعات مشکل خاصی نداشته باشن وارد مرحله بعد میشیم.

فرآیند Post توسط BIOS و یا UEFI انجام میشه. BIOS و  UEFI نام firmware هایی هستند که بعد از روشن شدن کامپیوتر شما کنترل سخت افزار رو به دست می گیرن . و سعی میکنن که سیستم رو طبق تنظیماتی که براشون مشخص کردیم Boot کنن. حالا این بستگی به Motherboard شما داره که ازBIOS پشتیبانی میکنه یا UEFI .

بوت لودر ‌Bootloader  :

بعد از این که فرآیند Boot از روی یکی از Device هایی که از قبل توی BIOS یا UEFI مشخص کردیم (cdrom , hard disk   removable devices ,...)  شروع شد ، نوبت به Bootloader میرسه.

بوت لودر یا‌‌‌‌‌‌ Boot manager سعی میکنه که Kernel ( همون هسته سیستم عامل ) رو لود کنه. اما سوال اصلی اینجاس که خود Bootloader سرو کلش از کجا پیدا میشه ؟
اگه توی حالت BIOS باشین Bootloader از روی MBR هارد دیسک شما ( اولین سکتور هارد دیسک ) لود میشه. اما اگه توی حالت UEFI باشین بوت لودر از داخل پارتیشن ESP لود میشه و...

البته این مراحل رو به صورت دقیق تر توی ویدیو توضیح دادم .

لازمه که بدونین توی دنیای Gnu/Linux بوت لودر های مختلفی وجود داره. اما معروف تر هاشون همینایی هستن که براتون نام می برم :

  • بوت لودر GNU GRUB : گراب یا GRand Unified Bootloader دو تا ورژن ۱ و۲ داره. که این روزا بیشتر ورژن ۲ اون رو می بینیم و توی این مقاله هم روی همین ورژن بحث می کنیم.
  • بوت لودر Lilo یا Linux Loader : یک بوت لودر خیلی قدیمه و امروزه کمتر ازش استفاده می شه.

لود شدن initramfs :

بعد از اینکه کرنل لینوکس لود شد نیاز داره که به پارتیشن Root دسترسی پیدا بکنه. تا بتونه یکسری service ها و برنامه ها رواجرا بکنه. و بعدشسیستم عامل بالا میاد. اما کرنل به تنهایی این توانایی رو نداره و نمیتونه پارتیشن Root رو باز کنه. و قبلش نیاز داره یکسری module ها رو روی خودش نصب کنه.
این ماژول های ضروری از قبل توی یک فایل فشرده به نام initrd یا initramfs ذخیره شدن . پس initrd به صورت موقت در RAM لود میشه تا کرنل بتونه ماژول های مورد نیاز خودش رو از داخل اون لود کنه. حالا Kernel لینوکس میتونه به محتوای پارتیشن Root دسترسی پیدا کنه.

اجرا شدن init system :

بعد از اینکه مراحل بالا طی شد ، Kernel کرنل اولین process رو از آدرس/sbin/init اجرا میکنه. PID  این پراسس 1 هست. اسمش هم init هست. init مادر تمامی process ها و service های سیستم ما حساب میشه.

بعد از اینکه init یا بهتر بگم init system ما اجرا میشه مسئولیت مدیریت کردن پراسس ها و سرویس ها میوفته گردن اون. و بقیه چیزا رو هم init برای ما بالا میاره.
در دنیای لینوکس init system های مختلفی داریم مثل : sysv init , upstart , systemD

ران لول ها Runlevels :

بعد از اینکه init system اجرا شد ، همه process ها و daemon هایی که لازم هست اجرا میشن. و در نهایت سیستم عامل لینوکسی ما بالا میاد . اما اینکه init system از کجا متوجه میشه که کدوم سرویس ها و پراسس ها رو باید اجرا کنه مربوط میشه به بحث runlevel ها .

ران لول ها حالت های مختلفی هستن که سیستم عامل ما میتونه توی اون حالت ها کار کنه . مثلا زمانی که شما از محیط گرافیکی ( GUI ) استفاده می کنید در ران لول 5 قرار دارید. یا به عنوان مثال توی Runlevel 3 محیط گرافیکی نداریم. و در حالت text mode هستیم و ...

و درواقع init system متوجه میشه که توی هر Runlevel باید چه service هایی رو اجرا کنه. مثلا وقتی میخایم توی ران لول 5 بیاییم بالا میفهمه که باید Display Manager رو هم اجرا کنه .

حالا بهتر می تونیم فرآیند Boot شدن یک سیستم عامل لینوکسی رو درک کنیم. پس بریم سراغ تعمیر Grub 2.

بوت لودر Grub2 :

وقتی که گراب ۲ میاد بالا به احتمال زیاد با یه همچین صفحه ای روبه رو میشین که بهش میگیم منوی گراب .

اگه Grub Menu به شما نمایش داده نشد باید قبل از اینکه سیستم بالا بیاد کلید shift رو نگه دارین تا منو بهتون نمایش داده بشه. البته این برای زمانی هست که در حالت Bios بوت شدین . اگر هم توی حالت UEFI بودین و این صفحه رو ندیدین باید کلید ESC رو نگهدارین.

منوی گراب
منوی گراب


حالا هر کدوم از این گزینه ها رو که انتخاب کنید ، همون سیستم عامل ( یا کرنل ) براتون بالا میاد.

روی هرکدوم شون هم که برید و کلید E رو از روی کیبورد بزنید ، می تونید تنظیمات مربوط به اون گزینه رو ببینید و حتی اونا رو ویرایش کنید. درواقع Grub این کار ها و تنظیمات رو اجرا میکنه و سیستم عامل بوت میشه و...

بریم یه نگاهی به این تنظیمات بندازیم.

به عنوان مثال جلوی عبارت set root پارتیشن Root مشخص شده.

جلوی عبارت linux هم محل قرار گیری Kernel لینوکس در درون دیسک ما مشخص شده . و در جلوی اون دوباره پارتیشن Root مشخص شده. و بعدشم پارامتر های کرنل نوشته شدن. به زبان خیلی ساده پارامتر های کرنل بر روی حالت بوت شدن لینوکس ما تاثیر میزارن. مثلا استفاده از پارامتر quiet باعث میشه که لاگ های مربوط به بوت شدن سیستم عامل به ما نمایش داده نشن و فقط یک صفحه گرافیکی رو ببینیم.

و در خط آخر جلوی عبارت initrd آدرس محل قرار گیری فایل initramfs مشخص شده.


حالا توی همین صفحه اگر کلید F10 رو فشار بدید سیستم با همین تنظیمات فعلی ( به همراه هر تغییری که داده باشین ) boot میشه. و با زدن کلید ESC هم میتونید دوباره بیاین توی منوی اصلی گراب.

تمام این تنظیمات و منو ها توی فایل grub.cfg در دایرکتوری /boot/grub ذخیره شدن و هردفعه از اونجا خونده میشن.

توی منوی اصلی گراب هم اگه کلید C رو از روی کیبورد فشار بدین وارد Shell گراب میشین.

در داخل Grub Shell دستورات مختلفی در اختیار داریم. و میتونیم سیستم عامل رو به صورت دستی و با وارد کردن دستورات مورد نیاز Boot کنیم.

Grub Shell
Grub Shell


حالا که بریم سراغ تعمیر بوت لودر Grub 2 در حالت های مختلف .

حل مشکل عدم نمایش منوی گراب و ورود به grub shell :

این مشکل وقتی به وجود میاد که فایل /boot/grub/grub.cfg پاک بشه یا خراب بشه. زمانی که مشکلی برای این فایل به وجود بیاد گراب نمی تونه منو ها رو لود کنه. و به همین دلیل شما رو به شل گراب هدایت میکنه تا بتونید دستوران لازم رو وارد کنید و سیستم عامل رو بوت کنید.

برای تعمیر گراب از داخل Grub Shell مراحل زیر رو دنبال کنید.

تشخیص پارتیشن Root :

اول از همه باید پارتیشن root رو به grub معرفی کنیم. برای این که خودمون بفهمیم پارتیشن root کدوم یکی از پارتیشن ها هست از دستور ls استفاده می کنیم.


همونطور که میبینین با زدن دستور ls تمامی هارد دیسک ها و پارتیشن ها به ما نمایش داده میشه. اگه حالت هاردتون gtp باشه اینجا جلوی hd0 کلمه gpt رو می بینید . و اگر هم mbr باشه عبارت msdos رو می بینید.

همونطور که در تصویر بالا می بینید برای اینکه محتویات هر پارتیشن رو هم ببینیم میتونیم دوباره از همون پارتیشن ls بگیریم.

حالا با نوشتن عبارت

set root=(hdX,msdosX)


و زدن اینتر پارتیشن Root رو برای گراب مشخص می کنیم. که در اینجا (hd0 , msdos2) پارتیشن روت سیستم من هست.

مشخص کردن محل ذخیره سازی Kernel :

حالا باید محل ذخیره شدن کرنل ( فایل vmlinuz ) در داخل هارد دیسک رو برای بوت لودر گراب مشخص کنیم. فایل کرنل معمولا در مسیر /boot قرار داره. و میتونید با استفاده از دستور ls محل دقیقشو مشخص کنید. البته ممکن هست شما پارتیشن boot رو جدا کرده باشین . در این صورت باید بفهمین پارتیشن Boot کدوم یکی از پارتیشن های شما هست. و آدرس دقیق فایل vmlinuz رو پیدا کنید .

همون طور که جلوتر گفتم برای مشخص کردن محل ذخیره سازی کرنل توی گراب از دستور linux استفاده می کنیم. و جلوی اون آدرس کرنل رو وارد می کنیم. بعد از اون هم با استفاده از عبارت root پارتیشن Root رو مشخص می کنیم. در ادامه هم هر کدوم از پارامتر های کرنل رو که نیاز داشته باشیم وارد می کنیم.

مثلا پارتیشن روت من (hd0,msdos1) بوده.

linux   (hd0,msdos1)/vmlinuz-5.4.0-81-generic root=/dev/sda2 ro  quiet splash

مشخص کردن محل ذخیره شدن initrd برای گراب :

حالا باید محل ذخیر initrd رو هم به گراب بگیم . initrd یا initramfs هم در دایرکتوری /boot قرار داره.
با وارد کردن عبارت initrd و در ادامه آدرس فایل initrd این کار رو هم انجام میدیم.

initrd (hd0,msdos1)/initrd.img-5.4.0-81-generic

بوت کردن سیستم عامل و ساختن فایل grub.cfg :

اگه تا اینجای کار رو درست پیش رفته باشید ، می تونید با وارد کردن دستور boot و زدن اینتر سیستم عامل رو بوت کنید.

بعد از اینکه سیستم شما بالا اومد باید فایل grub.cfg رو هم دوباره بسازین تا هر دفعه مجبور نباشین برای بوت شدن سیستم این دستورات رو توی گراب وارد کنید.

برای این کار ترمینال رو باز کنید و این دستور رو با دسترسی root اجرا کنید :

grub-mkconfig -o /boot/grub/grub.cfg

حالا فایل grub.cfg ساخته شده و تمام.

می تونید با خیال راحت سیستم رو restart کنید و منوی گراب مثل روز اول به شما نمایش داده میشه و به هر سیستم عامل دیگه ای هم که در کنار لینوکس نصب کرده باشین دسترسی دارین.

نکته : توی بعضی از توزیع ها مثل centos به جای دایرکتوری grub و دستورات و پکیج هایی که اسمشون با grub شروع میشه grub2 رو داریم.

حل مشکل عدم نمایش Grub Menu و ورود به Grub Rescue Shell :

این مشکل زمانی به وجود میاد که Grub نمیتونه به دایرکتوری /boot/grub دسترسی پیدا کنه. ممکنه این دایرکتوری وجود داشته باشه اما محتویاتش خراب شده باشن یا کلا پاک شده باشه.
وقتی این اتفاق میوفته بدون اینکه منوی گراب بهتون نشون داده بشه مستقیم میوفتین توی grub rescue shell .

Grub Rescue Shell
Grub Rescue Shell


متاسفانه توی این shell دستورات و امکانات خیلی محدودی در اختیار داریم. و نمی تونیم مثل حالت قبل با وارد کردن دستورات مختلف سیستم رو بوت کنیم. اما نگران نباشید. چون این مشکل هم راه حل خودشو داره :)


دقت کنید روشی که میخام برای تعمیر حالت Grub rescue بگم فقط در صورتی کار میکنه که محتویات دایرکتوری grub مشکلی نداشته باشن !!!

در غیر این صورت باید گراب رو دوباره نصب کنید که جلو تر بهتون یاد میدم.

برای تعمیر  بوت لودر Grub 2 در این حالت باید ابتدا آدرس دقیق دایرکتوری grub رو وارد کنیم. خوشبختانه اینجا هم دستور ls کار میکنه. و میتونیم ازش استفاده کنیم.

با استفاده از دستور set prefix محل دایرکتوری grub رو مشخص می کنیم.

مثلا:

set prefix=(hd0,msdos1)/grub2

حالا باید با استفاده از کامند insmod ماژول normal رو نصب کنیم :

insmod normal

اگه تا اینجا مراحل رو درست انجام داده باشین نباید هیچ اروری دریافت کنید.

حالا باید  دستور normal رو وارد کنیم. و گراب به حالت normal و معمولی بر میگرده. و اگه محتویات فایل grub.cfg درست باشه منوی گراب بدرستی بهتون نمایش داده میشه. وگرنه باید مثل حالت قبل با استفاده از grub shell سیستم رو بوت کنید.

خب حالا اگه کلا دایرکتوری grub حذف یا ناقص شده بود باید چیکار کنیم؟ توی اینجور مواقع باید گراب رو دوباره نصب کنیم. که در ادامه یادتون میدم.

مشکل اجرا نشدن grub :

بعضی وقتا هم ممکنه اصلا هیچ اثری از گراب نبینید. مثلا اگه اول روی هاردتون لینوکس نصب کنید و بعدش در کنارش ویندوز نصب کنید ، وقتی سیستم رو ریستارت می کنید احتمالا می بینید دیگه خبری از گراب نیست . و مستقیم وارد بوت لودر Windows میشین و به لینوکس تون دسترسی ندارین.

به غیر از این در بعضی مواقع هم ممکنه فقط یک صفحه مشکی براتون باز بشه و بالا سمت چپ نوشته باشه Grub. بدون هیچ prompt و چیز دیگه ای. مثل تصویر زیر :


توی این حالت ها هم برای تعمیر Grub باید اون رو دوباره نصب کنید.

نصب دوباره بوت لودر Grub2 :

برای اینکه گراب رو از اول نصب کنیم باید از این دستور استفاده کنیم :

grub install  /dev/sdX

اما وقتی کلا لینوکس ما بالا نمیاد و همه چی ترکیده باید چیکار کنیم ؟

چاره کار boot کردن یک iso لینوکس به صورت Live هست. هیچ فرقی هم نمیکنه چه توزیعی باشه. من اینجا از یک linuxmint استفاده کردم.

بعد از اینکه لینوکس live بوت شد یک ترمینال باز کنید و مراحل زیر رو انجام بدین.

mount کردن پارتیشن ها و Directory های مورد نیاز :

اول باید پارتیشن های مورد نیاز مون رو mount کنیم تا به اطلاعات اونا دسترسی داشته باشیم.

ابتدا پارتیشن root سیستم رو mount می کنیم.

mount /dev/sda2 /mnt

در مرحله بعد اگه پارتیشن boot رو قبلا جدا کرده باشین باید اون رو هم توی /mnt/boot مونت کنید. اگر هم جدا نکرده باشین که نیاز نیازی نیست.

mount /dev/sda1 /mnt/boot

اینجا یه نکته خیلی مهمی وجود داره : اگه توی حالت UEFI بوت شده باشین باید پارتیشن ESP رو هم باید توی /mnt/boot/efi مونت کنین. درواقع دایرکتوری efi یک mount point برای پارتیشن ESP هست.

حالا فقط دایرکتوری های dev و sys و proc باقی میمونن. این دایرکتوری ها در پارتیشن root وجود دارن. اما مشکل اینجاس که محتوای اونا توی RAM ذخیره مشه نه توی هارد. یعنی وقتی سیستم رو خاموش میکنین محتویات این دایرکتوری ها هم از بین میرن.

الان مثلا اگه از /mnt/dev یک ls بگیرین می بینید که خیلی از device های ما ازجمله hard disk ها رو نشناخته.

حالا برای حل این مشکل باید محتویات dev و sys و proc که توی لینوکس  live ما وجود داره رو بریزیم توی /mnt/dev و /mnt/sys و /mnt/proc تا بتونیم از اونا استفاده کنیم . پس این دستورات رو وارد کنید.

mount /dev --bind /mnt/dev mount /sys --bind /mnt/sys mount /proc --bind /mnt/proc

chroot کردن و نصب Grub

حالا آماده ایم که chroot کنیم توی /mnt . با انجام chroot یجورایی انگار پریدیم توی همون سیستم عامل مون که بالا نمیاد و داریم درستش می کنیم.

chroot /mnt

حالا کافیه گراب رو دوباره روی هارد نصب کنیم. و می تونیم از دستور  grub-install استفاده کنیم. دقت کنید که اینجا فقط هارد دیسک رو مشخص می کنیم نه پارتیشن.

grub-install /dev/sda

نکته : اگه توی حالت Bios بودین و یک درصد دیدن کامند grub-install کار نمیکنه احتمالا مجبور باشید پکیج grub-common رو دوباره نصب کنید. اگر هم توی حالت uefi بودین و دیدن این کامند کار نمیکنه برای حل این مشکل باید پکیج grub-efi رو دوباره نصب کنید.

ساختن فایل grub.cfg

با زدن دستور قبلی گراب روی اولین هارد دیسک من نصب شد. بعدش باید فایل grub.cfg رو هم بسازیم.

grub-mkconfig -o /boot/grub

اگه همه این مراحل رو درست انجام داده باشین دیگه کار تمومه...

می تونید با زدن دستور exit از این shell خارج بشین و دوباره وارد سیستم live تون بشین. حالا باید تک تک چیزایی که mount کردین رو umount کنید.

umount /mnt/boot umount /mnt/boot/efi umount /mnt/dev umount /mnt/sys umount /mnt/proc

الان میتونید سیستم رو Restart کنید. و گراب هم به درستی کار میکنه.

با استفاده از روش های بالا میتونید به راحتی بوت لودر Grub2 رو تعمیر کنین.


حالا یک موضوع دیگه ای هم وجود داره که دونستنش خالی از لطف نیست . و اون هم بحث Chain loading هست.

Chain loading چیست ؟

عملیات Chain loading زمانی اتفاق میوفته که از منوی گراب یک سیستم عامل به غیر از linux (مثلا Windows ) رو انتخاب و بودت می کنیم. درواقع بعد از اینکه بوت لودر Grub بالا میاد ادامه کار رو میده دست یک بوت لودر دیگه مثل بوت لودر ویندوز . و از اینجا به بعد گراب از بازی خارج میشه و این بوت لودر Windows هست که بقیه کار هارو انجام میده و ویندوز رو میاره بالا .

نحوه انجام دادن Chain loading در Grub2 :

همونطور که در ابتدا گفتم ، شل گراب ( Grub Shell ) امکانات مختلفی رو به ما ارائه میده. شما می تونید عملیات Chain loading رو هم از داخل این Shell با وارد کردن دستور های مورد نیاز انجام بدین.

مشخص کردن پارتیشن درایو C :

اولین کاری که باید انجام بدیم اینه که بفهمیم Root ویندوز مون یا همون درایو C کردوم یکی از پارتیشن های ما هست. برای این کار هم دقیقا مثل زمانی که می خواستیم لینوکس رو روت کنیم از دستور ls استفاده می کنیم.
بعد از اینکه این پارتیشن رو تشخیص دادیم با استفاده از دستور set root اون رو یه عنوان پارتیشن روت معرفی میکنیم.

مثلا اگه آدرس درایو C تون (hd0 , gpt6) باشه باید به این صورت عمل کنید :

set root=(hd0,gpt6)

حالا از اینجا به بعد اگه توی حالت UEFI بوت شده باشید باید آدرس فایل bootmgfw.efi رو که در پارتیشن ESP و در داخل دایرکتوری Microsoft ذخیره شده رو هم به گراب بدید. پس مثل مرحله قبل پارتیشن ESP رو هم پیدا می کنید. سپس با استفاده از دستور chainloader این فایل رو به گراب معرفی می کنید. مثل تصویر زیر :

حالا اگه دستور boot رو وارد کنید ویندوزتون بالا میاد.

اگر هم در حالت BIOS بوت شده باشین نیازی به این کار نیست. و فقط کافیه دستور chainloader +1 رو وارد کنید. و بعدشم دستور boot رو بزنید . و به این ترتیب عملیات Chain loading به درستی انجام میشه.


توضیح دقیق همه این موارد به اضافه یکسری مباحث تکمیلی مثل آموزش اضافه کردن منوی دلخواه به grub رو می تونید توی ویدیو ابتدای مقاله ببینید.

پیشنهاد می کنم یه نگاهی هم به منابع این مطلب بندازین. لینکشونو آخر این مطلب براتون میزارم.

امیدوارم که براتون مفید بوده باشه و به دردتون خورده باشه  :)

هر سوالی در این مورد داشتید بپرسید. خوشحال میشم بتونم کمک تون کنم :


Youtube : youtube.com/@neuron_network

Instagram : neuron_network

امیررضا حسینی


منابع :

linuxتعمیر grubتعمیر گرابgrubتعمیر grub 2
امیررضا حسینی
شاید از این پست‌ها خوشتان بیاید