编译linux内核分区,Ubuntu编译内核及grub的一些笔记
最近心態不穩定,不怎么想發表文章,但看了看之前寫了的筆記,想想還是整理出來吧,其實我寫文章,也有一部分原因是為了心里的慰藉——當年游戲打不過別人,關注點便轉向其它方面。這里整理的是以前編譯內核、引導啟動過程的步驟及問題的解決。
內核編譯
安裝Ubuntu默認沒有基本的開發環境,需要自己去安裝。比如編譯內核要安裝gcc,還要裝ncurses庫:
1
2apt-get install build-essential
apt-get install libncurses5-dev libncurses5
Ubuntu編譯內核的步驟十分簡單,只要下面幾個命令:
1
2
3
4
5make menuconfig(默認不需要也行)
make bzImage
make modules
sudo make modules_install
sudo make install
在最后一步,會自動去更新grub配置,不用再自己生成內核的img,再自己拷貝內核文件到/boot目錄了。不過,默認的配置會編譯很多很多的模塊,編譯時間久,無意間看了一下,竟然有4000個左右——懶人不動手,就得花時間等。
對于內核模塊的編譯,一般選擇在源碼樹外的目錄進行編譯,這時,要自己寫Makefile——而且這個Makefile還不是很簡單,其實,如果將其放到內核樹中編譯,可能會變得簡單一些。實際上,我就體會到這種做法的好處。最近做的東西是基于x86平臺的,它不像ARM那樣可以直接在uboot下載內核文件啟動。我要將內核文件拷貝到系統的/boot目錄,然后再重啟設備,這過程很麻煩。為了方便調試,將驅動以ko形式在系統運行時加載、調試。通過后再將其編譯進內核。這時,驅動的源碼是放到內核樹中的,所以不用再重新寫Makefile。
比如,編寫字符模塊hello,把需要的代碼放到driver/char/hello目錄,再修改char目錄的Kconfig和Makefile。
Kconfig為配置的文件,通過它,make menuconfig才能識別出來。
1
2
3
4
5
6config HELLO
tristate "Hello world"
default y
---help---
God help those whom help themself.
保存配置文件后,其中的HELLO變成CONFIG_HELLO,再修改Makefile
1obj-$(CONFIG_HELLO) += hello/
這樣編譯時就會找到hello目錄。另外,還要在hello目錄加上一個Makefile來指定編譯哪些文件,編譯后的模塊名稱:
如:
1
2
3
4
5
6#
# Makefile for the hello drivers.
#
obj-$(CONFIG_HELLO) += Hello.o
Hello-objs := hello.o hello_drv.o
第一行指定了編譯后模塊名稱(如果make menuconfig時選擇“M”的話),編譯得到的將是Hello.ko文件,第二行指定了要編譯哪些文件。注意第一行的Hello必須與第二行的Hello-objs中的“Hello”一致,否則會編譯不通過,會有如下提示:
1make[3]: *** No rule to make target `drivers/char/hello/hello.o', needed by `drivers/char/hello/built-in.o'. ?Stop.
我因為這個問題而花費了好幾分鐘。 進行上面操作后,編譯模塊就十分簡單了,不需要額外的Makefile(因為已經寫有了),編譯單個模塊,以I801驅動模塊為例:
1make CONFIG_I2C_I801=m -C /home/latelee/kernel_source/linux-3.17.1 M=/home/latelee/kernel_source/linux-3.17.1/drivers/i2c/busses/ modules
如果進入kernel source目錄,就可以簡化成:
1make CONFIG_I2C_I801=m -C . M=drivers/i2c/busses modules
對于上面所說的模塊,則是:
1make CONFIG_HELLO=m -C . M=drivers/char/ modules
Grub啟動
Ubuntu默認是啟動圖形界面的,可以通過修改grub配置文件,改為text模式啟動。修改/etc/default/grub,把splash改成text,再運行update-grub命令,即可完成。
如果直接改/boot/grub/grub.cfg的話,也是可以的,但下次重新安裝內核又會再次使用/etc下的配置,因此,還是要改配置文件。
有一次,啟動硬盤后,出現錯誤信息:
1
2error: file '/grub/i386-pc/normal.mod' not found.
grub rescue>
在網上找了解決方法,如下
1、使用live cd進入系統
2、掛載根分區硬盤(假設”/“分區是sda1)
1mount /dev/sda1 /mnt
3、安裝grub
1sudo grub-install /dev/sda --root-directory=/mnt
如果系統進入了grub,但由于路徑錯誤不能正常啟動,可以在grub命令行用命令來啟動。實際上,我就遇到過幾次,因為連接著顯示器,錯誤信息一閃而過,就變黑屏了,看不及看清楚。最終有同事提示下才發現問題所在。因為我的vmlinuz文件在/分區,會引用全路徑/boot/vmlinuz,而我的grub配置文件是另一個硬盤的配置,是/boot分區,直接用/vmlinuz。——這也是同時多進程工作的弊端,有時會分不清到底自己在搞哪一塊。我也同時因為同時在secureCRT中連接多個Linux(一同個窗口,一個連設備ssh,一個連虛擬機ssh,一個連服務器ssh)而無意間把服務器關機了,幸好影響不大。
下面是grub啟動linux的命令示例:
1
2
3
4grub>
grub>linux /vmlinuz-3.17.1 root=/dev/sda2
grub>initrd /initrd-3.17.1
grub>boot
最后,附上一個很簡單但能正常啟動的grub.cfg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15set default=0 # 第一個啟動項
set timeout=10 # 超時時間
menuentry 'My Ubuntu --first' {
set root='hd0,msdos1'
echo "vmlinuz...."
linux ? /vmlinuz-3.17.1 root=/dev/sda2 ro ?console=tty0 console=ttyS2,115200n8
}
menuentry 'My Ubuntu --second' {
set root='hd0,msdos1'
echo "vmlinuz...."
linux ? /vmlinuz-3.17.1_nof75111 root=/dev/sda2 ro ?console=tty0 console=ttyS2,115200n8
}
發行版本的grub.cfg有很多內容,其實就包括上一篇文章說到的uuid,我一度擔心因為在Grub中要配置,而每個硬盤的分區id不同,則要分別改配置文件,結果用dd命令拷貝后無須擔心這個問題了。
李遲,發表于2014年11月04日晚上
總結
以上是生活随笔為你收集整理的编译linux内核分区,Ubuntu编译内核及grub的一些笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下后缀为so的文件怎么打开,l
- 下一篇: linux脚本判断流程控制,linux