顯示具有 kernel compile 標籤的文章。 顯示所有文章
顯示具有 kernel compile 標籤的文章。 顯示所有文章

2016年10月30日 星期日

如何編譯 ARM HF 核心

如何編譯 ARM HF 核心

最新版的 Linux 核心資訊在 kernel.org 中可以看到,目前為止第三版最新的核心版本為 linux-3.18.44,我們以此版本作為「虛擬 ARM」版的開機核心。我們所使用的「虛擬 ARM」版為 vexpress-a9,qemu 所支援的虛擬 ARM 資訊可以執行底下指令來觀看:

$ qemu-system-arm -machine help
Supported machines are:
akita                Sharp SL-C1000 (Akita) PDA (PXA270)
borzoi               Sharp SL-C3100 (Borzoi) PDA (PXA270)
canon-a1100          Canon PowerShot A1100 IS
cheetah              Palm Tungsten|E aka. Cheetah PDA (OMAP310)
collie               Sharp SL-5500 (Collie) PDA (SA-1110)
connex               Gumstix Connex (PXA255)
cubieboard           cubietech cubieboard
highbank             Calxeda Highbank (ECX-1000)
imx25-pdk            ARM i.MX25 PDK board (ARM926)
integratorcp         ARM Integrator/CP (ARM926EJ-S)
kzm                  ARM KZM Emulation Baseboard (ARM1136)
lm3s6965evb          Stellaris LM3S6965EVB
lm3s811evb           Stellaris LM3S811EVB
mainstone            Mainstone II (PXA27x)
midway               Calxeda Midway (ECX-2000)
musicpal             Marvell 88w8618 / MusicPal (ARM926EJ-S)
n800                 Nokia N800 tablet aka. RX-34 (OMAP2420)
n810                 Nokia N810 tablet aka. RX-44 (OMAP2420)
netduino2            Netduino 2 Machine
none                 empty machine
nuri                 Samsung NURI board (Exynos4210)
palmetto-bmc         OpenPOWER Palmetto BMC
raspi2               Raspberry Pi 2
realview-eb          ARM RealView Emulation Baseboard (ARM926EJ-S)
realview-eb-mpcore   ARM RealView Emulation Baseboard (ARM11MPCore)
realview-pb-a8       ARM RealView Platform Baseboard for Cortex-A8
realview-pbx-a9      ARM RealView Platform Baseboard Explore for Cortex-A9
sabrelite            Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)
smdkc210             Samsung SMDKC210 board (Exynos4210)
spitz                Sharp SL-C3000 (Spitz) PDA (PXA270)
sx1                  Siemens SX1 (OMAP310) V2
sx1-v1               Siemens SX1 (OMAP310) V1
terrier              Sharp SL-C3200 (Terrier) PDA (PXA270)
tosa                 Sharp SL-6000 (Tosa) PDA (PXA255)
verdex               Gumstix Verdex (PXA270)
versatileab          ARM Versatile/AB (ARM926EJ-S)
versatilepb          ARM Versatile/PB (ARM926EJ-S)
vexpress-a15         ARM Versatile Express for Cortex-A15
vexpress-a9          ARM Versatile Express for Cortex-A9
virt-2.6             QEMU 2.6 ARM Virtual Machine
virt                 QEMU 2.7 ARM Virtual Machine (alias of virt-2.7)
virt-2.7             QEMU 2.7 ARM Virtual Machine
xilinx-zynq-a9       Xilinx Zynq Platform Baseboard for Cortex-A9
z2                   Zipit Z2 (PXA27x)

其中有一行如下:

vexpress-a9          ARM Versatile Express for Cortex-A9

這是我們要玩的虛擬 ARM 開發板,請把 linux 核心放在 /usr/src/ 目錄下,其完整路徑為

/usr/src/linux-3.18.44.tar.xz


=======================底下流程請全部以一般使用者來執行========================

接下來在本地端要解開 linux 原始碼,並準備編譯。請在 ~/qemu_image/arm2 目錄新增 kernel 目錄

~/qemu_image/arm2 $ mkdir kernel
~/qemu_image/arm2 $ cd kernel
~/qemu_image/arm2/kernel $ tar xfva linux-3.18.44.tar.xz
~/qemu_image/arm2/kernel $ cd linux-3.18.44
~/qemu_image/arm2/kernel/linux-3.18.44 $ makerpi vexpress_defconfig
~/qemu_image/arm2/kernel/linux-3.18.44 $ makerpi menuconfig

此時會進入核心設定選單,請選擇

General setup  --->
        Kernel compression mode (XZ)  --->

System Type  --->
        [ ] Enable the L2x0 outer cache controller
        請把原有的 * 取消,否則開機會有問題

完全上述設定後離開設定畫面,然後執行:

~/qemu_image/arm2/kernel/linux-3.18.44 $ makerpi uImage LOADADDR=0x60000000 -j 8

作完之後其訊息如下:

..
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-3.18.44
Created:      Mon Oct 31 11:22:50 2016
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    2437760 Bytes = 2380.62 kB = 2.32 MB
Load Address: 60000000
Entry Point:  60000000
  Image arch/arm/boot/uImage is ready


接著可以用 qemu 來試開機,請執行:

~/qemu_image/arm2 $ qemu-system-arm -M vexpress-a9 -m 256 -nographic -kernel
./kernel/linux-3.18.44/arch/arm/boot/zImage

此時會進入核心開機畫面,但是因為我們還沒有給這個核心 rootfs 的緣故,因此開機開到一半會出現底下錯誤:

VFS: Cannot open root device "(null)" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
1f00          131072 mtdblock0  (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.18.44 #2
[<80014824>] (unwind_backtrace) from [<800116d0>] (show_stack+0x10/0x14)
[<800116d0>] (show_stack) from [<80477c64>] (dump_stack+0x98/0xac)
[<80477c64>] (dump_stack) from [<80475b10>] (panic+0x9c/0x200)
[<80475b10>] (panic) from [<805ec228>] (mount_block_root+0x1d0/0x260)
[<805ec228>] (mount_block_root) from [<805ec3c0>] (mount_root+0x108/0x110)
[<805ec3c0>] (mount_root) from [<805ec520>] (prepare_namespace+0x158/0x19c)
[<805ec520>] (prepare_namespace) from [<805ebeb4>] (kernel_init_freeable+0x244/0x254)
[<805ebeb4>] (kernel_init_freeable) from [<80473f60>] (kernel_init+0x8/0xe8)
[<80473f60>] (kernel_init) from [<8000e500>] (ret_from_fork+0x14/0x34)
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)


這是正常的,請按 Ctrl+a 然後再按 x 即可離開 qemu 模擬畫面,之後我們將會為此虛擬 ARM 主機加上 rootfs 及 bootloader 使其可以開機。

2013年9月30日 星期一

Linux 核心編譯及相關知識

=== 編譯設定時請先注意核心版本是否正確,並確定是否有 64-bit kernel 選項 ===

設定核心參譯參數:

設定參數有三種選項,分別是:

1. M -> 編譯成模組,可即時載入/移除模組,舉例來說:搖桿的驅動程式是 joydev.ko,一般人電腦並沒有連接 USB 搖桿,因此我們無需隨時載入 joydev.ko 這個驅動程式模組,等到我們有接上 USB 搖桿時再來載入即可。
2. * -> 編譯並內嵌至核心,無法移除
3.   -> 不編譯此模組


驅動程式模組操作:

1. lsmod -> 觀看目前有那些驅動程式模組已載入至記憶體,其輸出如下:

herman@debian:~$ lsmod
Module                  Size  Used by
joydev                 17232  0
nvidia               9384645  29
drm                   211810  2 nvidia
nfsv3                  29787  1
rpcsec_gss_krb5        26504  0
nfsv4                 158090  0
nfsd                  192007  2
auth_rpcgss            39085  2 nfsd,rpcsec_gss_krb5
oid_registry           12419  1 auth_rpcgss
nfs_acl                12511  2 nfsd,nfsv3
nfs                   105982  3 nfsv3,nfsv4
lockd                  55577  3 nfs,nfsd,nfsv3
fscache                37551  2 nfs,nfsv4
sunrpc                160406  24 nfs,nfsd,rpcsec_gss_krb5,auth_rpcgss,lockd,nfsv3,nfsv4,nfs_acl

..
..

其中 Module 欄位是目前已載入至記憶體中之模組,Size 是該模組大小,Used by 是指該模組是否有被其它模組使用,舉例來說,如果我們執行:

lsmod|grep usb

會得到以下輸出:

usb_storage            48020  0
scsi_mod              158157  5 sg,usb_storage,libata,sd_mod,sr_mod
usbcore               134854  4 uhci_hcd,usb_storage,ehci_hcd,ehci_pci
usb_common             12440  1 usbcore

其中 usbcore 是 USB 驅動程式之主模組,它會被其它 USB 相關驅動程式模組所使用,例如 usb_storage 是用來驅動 USB 儲存裝置之模組,它必須有 usbcore 才能使用。

2. modprobe -> 載入驅動程式模組

請先執行 lsmod|grep joydev 看看目前是否有載入 joystick 之驅動程式模組。接著我們可以使用 root 權限來載入 joydev 驅動程式模組:

# modprobe joydev

載入後可以再執行一次 lsmod|grep joydev 來看目前是否有載入 joystick 之驅動程式模組,理論上其輸出如下:

joydev                 17232  0

這表示我們已成功載入 joydev 驅動程式模組。

3. rmmod -> 移除驅動程式模組

若我們要移除 joydev 模組的話,請以 root 權限執行底下指令:

# rmmod joydev

再以 lsmod|grep joydev 來看目前是否有載入 joystick 之驅動程式模組。



編譯核心參數設定

請以 root 權限在 /usr/src/linux 目錄下執行底下指令:

/usr/src/linux # make menuconfig

接著可以進行參數設定

1. General setup  --->
        Kernel compression mode (Gzip)  --->
                XZ
   目的:使用最高壓縮率之壓縮演算法以節省空間。

   [*] Enable loadable module support  --->

   目的:開啟可載入模組設定

        [*]   Module versioning support
        支援其它版本核心所編譯出來的模組,萬一有相容性的問題則無法支援。



2. Processor type and features  --->
        Processor family (Generic-x86-64)  --->
                Processor family (Core 2/newer Xeon)
   目的:把 CPU 由 Generic-x86-64 改為 Core 2/newer Xeon 可以加強在本機的
         效能,因為本機 CPU 是 Core 2 Duo (hint: cat /proc/cpuinfo)


         (512) Maximum number of CPUs

   目的:支援最高 512 顆 CPU。

   Bus options (PCI etc.)  ---> 設定電腦內部匯流排,例如 PCI、ISA .. etc.

3. Executable file formats / Emulations  --->
        [*] IA32 Emulation
        <*>   IA32 a.out support

   目的:在 64 位元 Linux 底下執行 32 位元 Linux 程式,例如 Adobe Reader 只出 32
        位元版 (i386 版),打開此參數可以讓我們所編譯的 Linux 核心支援此程式
        執行。

    --- Networking support  設定網路相關硬體及軟體
          Networking options  ---> 不要動,以免網路無法動作
    [ ]   Amateur Radio support  ---> 業餘無線電支援,請關閉,我們不需要。
    < >   CAN bus subsystem support  --->
    < >   IrDA (infrared) subsystem support  --->
    <M>   Bluetooth subsystem support  --->
    -*-   Wireless  ---
    < >   WiMAX Wireless Broadband support  --->
    < >   NFC subsystem support  --->


4. Device Drivers  ---> 此目錄底下有相當多的參數可以設定,請將不要的模組移除以
        減少空間。
        < > Parallel port support  --->  關閉,我們現在的電腦已經沒有 RS232
                的平行埠介面了。

        <M>   Loopback device support
        (8)     Number of loop devices to pre-create at init time
        < >     Cryptoloop Support
        loopback device 可以用來掛載光碟片的 ISO 檔,簡單來說它是 Linux 上的
        虛擬光碟。舉例來說,假設我們要掛在 debian 安裝 iso 檔,其檔名是:
        debian-7.1.0-amd64-CD-1.iso 的話,我們可以使用 root 的權限執行:
        # mount -o loop debian-7.1.0-amd64-CD-1.iso /mnt
        將此光碟片掛載至 /mnt 目錄下,此時系統會出現底下訊息:
        mount: warning: /mnt seems to be mounted read-only.
        這表示 /mnt (光碟片) 是唯讀目錄,無法寫入。我們可以使用 ls /mnt
        來觀看是否是光碟片內容。
        因此 Loopback device 參數一定要設定,否則將無法使用虛擬光碟。

        < > ATA/ATAPI/MFM/RLL support (DEPRECATED)  --->
        此參數有個 DEPRECATED 的單字,因此通常不再支援,除非你的電腦有接很老舊
        的裝置,否則可以不必編。


        <M> Serial ATA and Parallel ATA drivers  --->
        支援 SATA 介面,問題在於:我們如何知道本機 SATA 介面卡為何 ?

        lspci 可以看到底下資訊:

00:1f.2 IDE interface: Intel Corporation NM10/ICH7 Family SATA Controller [IDE mode] (rev 01)

        上述資料告訴我們本機的 SATA 介面是 Intel 的 NM10/ICH7 晶片,若想知道該晶
片使用那個模組的話,請執行:lspci -v,其輸出如下所示:

00:1f.2 IDE interface: Intel Corporation NM10/ICH7 Family SATA Controller [IDE mode] (rev 01) (prog-if 80 [Master])
        Subsystem: Giga-byte Technology Device b002
        Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 19
        I/O ports at 01f0 [size=8]
        I/O ports at 03f4 [size=1]
        I/O ports at 0170 [size=8]
        I/O ports at 0374 [size=1]
        I/O ports at f000 [size=16]
        Capabilities: <access denied>
        Kernel driver in use: ata_piix

============

            IEEE 1394 (FireWire) support  --->  取消,目前此介面幾乎沒人使用
        [ ] Macintosh device drivers  --->      取消,目前此介面幾乎沒人使用

============

        -*- Network device support  ---> 設定網路介面
                < >   ARCnet support  --->
                [ ]   ATM drivers  --->
                      *** CAIF transport drivers ***
                      Distributed Switch Architecture drivers  --->
                -*-   Ethernet driver support  ---> 設定網路卡驅動程式

        我們以 lspci -v 可以看到以下訊息:

03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 02)
        Subsystem: Giga-byte Technology GA-EP45-DS5/GA-EG45M-DS2H Motherboard
        Flags: bus master, fast devsel, latency 0, IRQ 43
        I/O ports at d000 [size=256]
        Memory at e5010000 (64-bit, prefetchable) [size=4K]
        Memory at e5000000 (64-bit, prefetchable) [size=64K]
        [virtual] Expansion ROM at e5020000 [disabled] [size=64K]
        Capabilities: <access denied>
        Kernel driver in use: r8169
        因此可以看到本機電腦所使用之網路卡驅動模組是 r8169,廠牌為 Realtek。

                < >   FDDI driver support
                [ ]   HIPPI driver support
                < >   General Instruments Surfboard 1000
                {M}   PHY Device support and infrastructure  --->
                < >   Micrel KS8995MA 5-ports 10/100 managed Ethernet switch (NEW
                < >   PLIP (parallel port) support
                {M}   PPP (point-to-point protocol) support
                      USB Network Adapters  --->  沒有 USB 網卡則全部關掉
                [ ]   Wireless LAN  ---> 沒有 wifi 無線網卡則全部關掉
                      WiMAX Wireless Broadband devices  ---> 沒有 wimax 卡則關掉
                [ ]   Wan interfaces support  --->
                < >   IEEE 802.15.4 drivers  --->
                < >   VMware VMXNET3 ethernet driver
                [ ]   ISDN support  --->

    <M> Sound card support  --->        音效卡支援
        --- Sound card support
        [ ]   Preclaim OSS device numbers
        <M>   Advanced Linux Sound Architecture  --->
        < >   Open Sound System (DEPRECATED)  --->

        音效卡我們只保留 ALSA,我們的音效卡是:

00:1b.0 Audio device: Intel Corporation NM10/ICH7 Family High Definition Audio Controller (rev 01)

        因此其驅動程式如下:

            [*]   PCI sound devices  --->
                <M>   Intel HD Audio  --->
                <M>   Intel/SiS/nVidia/AMD/ALi AC97 Controller
                <M>   Intel/SiS/nVidia/AMD MC97 Modem

        Graphics support  --->          顯示卡支援

        我們的顯示卡是

01:00.0 VGA compatible controller: NVIDIA Corporation G96 [GeForce 9400 GT] (rev a1)
        由於我只裝官方驅動程式,因此把 nouveau 關掉,兩者會相衝。

            < > Nouveau (nVidia) cards
        其餘驅動程式可以關閉以簡省空間。


        {*} Hardware Monitoring support  --->
        硬體監測驅動程式,因為我們看不到主機板上面的晶片,因此建議全部編譯,
        讓電腦開機時自動偵測並載入相對應之驅動程式模式。

        我們可以使用 lm-sensors 這個套件來看主機板上面的溫度/電壓/風扇

        sensors-detect

        偵測完畢後會出現底下訊息,告訴我們要載入那些模組以驅動硬體監視驅動
        程式。

Now follows a summary of the probes I have just done.
Just press ENTER to continue:

Driver `it87':
  * ISA bus, address 0x290
    Chip `ITE IT8718F Super IO Sensors' (confidence: 9)

Driver `coretemp':
  * Chip `Intel digital thermal sensor' (confidence: 9)

To load everything that is needed, add this to /etc/modules:
#----cut here----
# Chip drivers
coretemp
it87
#----cut here----
If you have some drivers built into your kernel, the list above will
contain too many modules. Skip the appropriate ones!

Do you want to add these lines automatically to /etc/modules? (yes/NO)

Unloading i2c-dev... OK
Unloading cpuid... OK



    {M} Generic Thermal sysfs driver  --->      溫度管理

    <M> Multimedia support  --->        設定視訊/電視卡之驅動程式模組

    <M> VFIO Non-Privileged userspace driver framework  ---> 將 VGA pass 給 qemu
        --- VFIO Non-Privileged userspace driver framework
        <M>   VFIO support for PCI devices
        [*]     VFIO PCI support for VGA devices


5.        Firmware Drivers  --->        某些硬體需要 firmware (韌體) 才能動作,
        這些韌體在 Debian 的 firmware* 套件中。
        大部份常見會用到的韌體是無線網卡,例如 b43 (broadcom) 無線網卡之類。

2012年10月5日 星期五

編譯 ARM Linux 核心

編譯 ARM Linux 核心


檔案位置:
~/qemu_image/                   -> 所有虛擬 ARM 檔案目錄
        /kernel/                      -> 編譯 ARM Linux 核心目錄
                   /modules         -> 編譯 ARM Linux 核心模組目錄


0. 判別我們所要使用之 ARM CPU

我們的模擬目標為 Beagle Board,其 CPU 為 OMAP 3530,有關 Beagle Board 的詳細規格可以參考官方網站 (http://beagleboard.org/),而 OMAP 3530 是由德洲儀洲所生產之 ARM CPU,其資料可以參考德儀網站 (http://www.ti.com/product/omap3530?247SEM)。

OMAP 3530 是一顆 Cortex A8 的 ARM CPU,目前已被 Qemu ARM 完整支援,我們可以使用

qemu-system-arm -cpu ?

來觀看 Qemu ARM 版所支援之 CPU 清單,如下所示:

Available CPUs:
  arm1026
  arm1136
  arm1136-r2
  arm1176
  arm11mpcore
  arm926
  arm946
  cortex-a15
  cortex-a8
  cortex-a9
  cortex-m3
  pxa250
  pxa255
  pxa260
  pxa261
  pxa262
  pxa270
  pxa270-a0
  pxa270-a1
  pxa270-b0
  pxa270-b1
  pxa270-c0
  pxa270-c5
  sa1100
  sa1110
  ti925t
  any

因此我們可以使用 Qemu 來模擬 beagle board 平台,底下將介紹如何編譯 Linux 核心:

1. 下載 & 解壓縮

請切換至 ~/qemu_image/kernel 目錄,進行底下操作:

wget ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/v3.x/linux-3.2.30.tar.xz

tar xfva linux-3.2.30.tar.xz

此時會出現 linux-3.2.30 目錄

2. 設定編譯參數

cd linux-3.2.30

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- omap2plus_defconfig

** ARM 版之核心設定參數檔在 linux-3.2.30/arch/arm/configs 目錄 **

此時會出現以下訊息:

  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/zconf.lex.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#

這表示我們已經完成基本參數設定,接著我們要作細部微調。請執行:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig

如果出現底下錯誤的話,表示我們還沒有安裝 libncurses5-dev 這個函式庫:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig

 *** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 ***
 *** Install ncurses (ncurses-devel) and try again.
 ***
make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
make: *** [menuconfig] Error 2

請以底下指令安裝 libncurses5-dev 函式庫:

apt-get install libncurses5-dev


然後再重新執行底下指令即可:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig


請設定以下部份:

General setup  ---> Kernel compression mode (Gzip)  --->XZ

System Type  ---> TI OMAP2/3/4 Specific Features  --->
[*] OMAP3 BEAGLE board
[*] DEVKIT8000 board

File systems --->
<*> The Extended 4 (ext4) filesystem

設定完畢後請跳出 Linux 設定畫面,如此一來我們即完成 Linux 核心設定。

3. 編譯核心及核心模組

a. 編譯核心

time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage -j 4

假設在編譯時有底下訊息:

make: arm-linux-gnueabi-gcc: Command not found
scripts/kconfig/conf --silentoldconfig Kconfig
make: arm-linux-gnueabi-gcc: Command not found
  WRAP    arch/arm/include/generated/asm/auxvec.h
  WRAP    arch/arm/include/generated/asm/bitsperlong.h
  WRAP    arch/arm/include/generated/asm/cputime.h
  WRAP    arch/arm/include/generated/asm/emergency-restart.h
  WRAP    arch/arm/include/generated/asm/errno.h
  WRAP    arch/arm/include/generated/asm/ioctl.h
  WRAP    arch/arm/include/generated/asm/irq_regs.h
  WRAP    arch/arm/include/generated/asm/kdebug.h
  WRAP    arch/arm/include/generated/asm/local.h
  WRAP    arch/arm/include/generated/asm/local64.h
  WRAP    arch/arm/include/generated/asm/percpu.h
  WRAP    arch/arm/include/generated/asm/poll.h
  WRAP    arch/arm/include/generated/asm/resource.h
  WRAP    arch/arm/include/generated/asm/sections.h
  WRAP    arch/arm/include/generated/asm/siginfo.h
  WRAP    arch/arm/include/generated/asm/sizes.h
  CHK     include/linux/version.h
  UPD     include/linux/version.h
  HOSTCC  scripts/dtc/checks.o
  HOSTCC  scripts/dtc/data.o
  SHIPPED scripts/dtc/dtc-lexer.lex.c
  SHIPPED scripts/dtc/dtc-parser.tab.h
  SHIPPED scripts/dtc/dtc-parser.tab.c
  HOSTCC  scripts/dtc/dtc.o
  HOSTCC  scripts/dtc/flattree.o
  CHK     include/generated/utsrelease.h
  UPD     include/generated/utsrelease.h
  Generating include/generated/mach-types.h
  CC      kernel/bounds.s
/bin/sh: 1: arm-linux-gnueabi-gcc: not found
make[1]: *** [kernel/bounds.s] Error 127
make: *** [prepare0] Error 2
make: *** Waiting for unfinished jobs....

  HOSTCC  scripts/dtc/fstree.o
  HOSTCC  scripts/dtc/livetree.o
  HOSTCC  scripts/genksyms/genksyms.o
  HOSTCC  scripts/dtc/srcpos.o
  HOSTCC  scripts/dtc/treesource.o
  SHIPPED scripts/genksyms/lex.lex.c
  SHIPPED scripts/genksyms/keywords.hash.c
  SHIPPED scripts/genksyms/parse.tab.h
  SHIPPED scripts/genksyms/parse.tab.c
  HOSTCC  scripts/genksyms/lex.lex.o
  HOSTCC  scripts/dtc/util.o
  HOSTCC  scripts/dtc/dtc-lexer.lex.o
  HOSTCC  scripts/dtc/dtc-parser.tab.o
  HOSTCC  scripts/genksyms/parse.tab.o
  HOSTLD  scripts/dtc/dtc
  CC      scripts/mod/empty.o
/bin/sh: 1: arm-linux-gnueabi-gcc: not found
make[2]: *** [scripts/mod/empty.o] Error 127
make[1]: *** [scripts/mod] Error 2
make[1]: *** Waiting for unfinished jobs....

  HOSTLD  scripts/genksyms/genksyms
make: *** [scripts] Error 2
real    0m3.743s
user    0m4.576s
sys    0m0.304s

上面錯誤訊息是因為 arm-linux-gnueabi-gcc 這個指令找不到,我們可以切換至 /usr/bin 目錄來觀察 gcc cpp g++ 三個指令,如下所示:



root@debian:/usr/src# cd /usr/bin
root@debian:/usr/bin# ls -l arm-linux-gnueabi-gcc-4.7 arm-linux-gnueabi-cpp-4.7 arm-linux-gnueabi-g++-4.7
-rwxr-xr-x 1 root root 559672 10月 12  2012 arm-linux-gnueabi-cpp-4.7
-rwxr-xr-x 1 root root 562936 10月 12  2012 arm-linux-gnueabi-g++-4.7
-rwxr-xr-x 1 root root 558840 10月 12  2012 arm-linux-gnueabi-gcc-4.7



這個錯誤是因為編譯指令要的是 arm-linux-gnueabi-gcc、arm-linux-gnueabi-cpp 以及 arm-linux-gnueabi-g++ 三個檔案,而目前系統沒有,因此我們要手動建立連結:

root@debian:/usr/bin# ln -s arm-linux-gnueabi-cpp-4.7 arm-linux-gnueabi-cpp
root@debian:/usr/bin# ln -s arm-linux-gnueabi-g++-4.7 arm-linux-gnueabi-g++
root@debian:/usr/bin# ln -s arm-linux-gnueabi-gcc-4.7 arm-linux-gnueabi-gcc

接著再執行剛剛沒有成功的指令來編譯核心:

time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage -j 4

若是編譯過程中出現底下錯誤:

  SHIPPED arch/arm/boot/compressed/ashldi3.S
  AS      arch/arm/boot/compressed/lib1funcs.o
  AS      arch/arm/boot/compressed/ashldi3.o
  AS      arch/arm/boot/compressed/piggy.xzkern.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
"mkimage" command not found - U-Boot images will not be built
make[1]: *** [arch/arm/boot/uImage] Error 1
make: *** [uImage] Error 2


這表示編譯程式找不到 mkimage 這個指令,我們可以上 packages.debian.org 來查詢,得知此檔案在 u-boot-tools 套件中,因此要再安裝 u-boot-tools 套件,然後再下編譯指令。編譯完畢後會出現以下訊息,告訴我們 uImage 已經編譯完成。

Image Name:   Linux-3.2.30
Created:      Fri Oct  5 15:43:49 2012
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    2475104 Bytes = 2417.09 kB = 2.36 MB
Load Address: 0x80008000
Entry Point:  0x80008000
  Image arch/arm/boot/uImage is ready

我們可以執行底下指令來看  /arch/arm/boot/uImage 的屬性:

file arch/arm/boot/uImage

其輸出如底下所示:

file uImage
uImage: u-boot legacy uImage, Linux-3.2.30, Linux/ARM, OS Kernel Image (Not compressed), 2475104 bytes, Fri Oct  5 15:43:49 2012, Load Address: 0x80008000, Entry Point: 0x80008000, Header CRC: 0x3A120CB2, Data CRC: 0x1508ED43

b. 編譯核心模組

核心要正常工作必須要有相對應的核心模組,否則無法載入驅動程式,

# Compile Kernel Modules
time make -s ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules -j $CPU_CORE

# Install Kernel Modules
time make -s ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules_install INSTALL_MOD_PATH=../modules/ -j $CPU_CORE

cd ../modules
time tar cfa ../modules-$KERNEL_VERSION.tar.xz lib

編譯完成後我們會有一個名為 modules-核心編號.tar.xz 的檔案,此檔案可以用來取代原始 rootfs 中 /lib/modules 目錄中舊版的驅動核心模組。因此我們必須將舊版驅動核心模組移除,再放入我們剛剛編完之驅動核心模組。

4. 準備虛擬 SD card -> 請看講義

5. 將 /dev/loop1 掛載至 /mnt/sdcard1 目錄

mount /dev/loop1 /mnt/sdcard1

將以下檔案複製至 /mnt/sdcard1 目錄:

-rwxr-xr-x 1 root root   45444 2012-10-05 16:52 MLO
-rwxr-xr-x 1 root root 1370958 2012-10-05 16:52 u-boot
-rwxr-xr-x 1 root root  344872 2012-10-05 16:52 u-boot.bin
-rwxr-xr-x 1 root root  344936 2012-10-05 16:52 u-boot.img
-rwxr-xr-x 1 root root 2475168 2012-10-05 16:54 uImage

6.

qemu-system-arm -M beagle -m 256 -nographic -sd sdcard.img

此時即可看到 qemu 使用虛擬 sdcard 開機。


2012年5月23日 星期三

自編 Linux 核心


自編 Linux 核心

為什麼要自己編 Linux 核心 ?

缺點:程度還沒到那邊的人,編出來的核心有時候開機會當機。

優點:

1. 修正舊核心的 bug
2. 支援新的硬體
3. 針對自己主機的硬體進行最佳化
4. 關閉不必要的核心模組,精簡編譯完之核心大小

如何挑核心

Linux 有一個存放核心的官方網站 (https://www.kernel.org/),在此網站中會有各個版本的最新核心,我們為了要調整自己使用機器之效能,因此必須要自行編譯核心,在核心官方網站中有三個種類的核心可下載,分別是:

  • mainline - 目前開發版本,主要目的是加入新功能及測試,不建議在伺服器/嵌入式系統中使用,以免有未修正之 bug 導致機器不穩。
  • stable - 穩定版核心,可提供日常使用
  • longterm - 此版核心又稱為 LTS (Long Term Support - 長期支援) 核心,主要目的在於修正已知 bug,非常適合伺服器/嵌入式系統中使用。
我們要下載並安裝之核心為 longterm 版本,在官方網站中又有兩個版本的核心可以下載,分別是 3.X 以及 4.X 之核心,由於我們要在 Xeon 等級的 CPU 上執行此核心,因此可以挑選 4.X longterm 版本核心,以目前 (2016/10/3) 來說,我們選擇 4.4.23 版之 Linux 核心來進行編譯。


如何編核心

1. 安裝程式編譯環境
2. 安裝核心編譯環境
3. 下載核心
4. 編譯核心
5. 安裝核心
6. 重新開機 -> 正常開機(OK)
            -> 當機(以舊版核心重開,設法解決問題)

1. 安裝程式編譯環境

編譯 Linux 核心主要會使用到 GCC,在安裝 GCC 之前,我們可以看一下目前系統的 Linux 核心是由那一版的 GCC 所編譯完成,請執行:

$ dmesg | more

可以看到底下片段:

[    0.000000] Linux version 3.16.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01
-17)

此訊息告訴我們 Linux 核心是由 gcc 4.8.4 所編譯完成,因此如果我們安裝 GCC 的話,以 4.8.4 (以上) 為主。

請安裝

gcc-4.8
cpp-4.8
g++-4.8

這三個套件,其中每個套件各有兩個版本:

gcc
gcc-4.8
gcc-4.9

cpp
cpp-4.8
cpp-4.9

g++
g++-4.8
g++-4.9

我們可以在 /usr/bin 目錄中看到目前的版本為何,或是執行以下指令:
gcc -v
cpp -v
g++ -v

如果我們至 /usr/bin 目錄下執行

ls -l gcc* cpp* g++*

會看到以下輸出:

 lrwxrwxrwx 1 root root      7  3月  4 10:05 cpp -> cpp-4.8
-rwxr-xr-x 1 root root 772600 12月 20  2014 cpp-4.8
-rwxr-xr-x 1 root root 833080 12月 26  2014 cpp-4.9
lrwxrwxrwx 1 root root      7  3月  4 10:05 g++ -> g++-4.8
-rwxr-xr-x 1 root root 776696 12月 20  2014 g++-4.8
lrwxrwxrwx 1 root root      7  3月  4 10:05 gcc -> gcc-4.8
-rwxr-xr-x 1 root root 772600 12月 20  2014 gcc-4.8
-rwxr-xr-x 1 root root  24736 12月 20  2014 gcc-ar-4.8
-rwxr-xr-x 1 root root  24704 12月 20  2014 gcc-nm-4.8
-rwxr-xr-x 1 root root  24704 12月 20  2014 gcc-ranlib-4.8

這表示上述三個命令都聯結到 4.8 版,全部的聯結版本都要一致才行。檢查方式是執行:

$ gcc -v
$ g++ -v
$ cpp -v

來觀看版本編號,安裝完畢後請編譯 hello.c,指令如下:

gcc hello.c -o hello

再執行

./hello

如果出現 Hello world!! 即代表我們的程式編譯環境安裝 OK!!


2. 安裝核心編譯環境

請安裝以下套件才可編譯核心

kernel-package
libncurses5-dev
bzip2
xz-utils

3. 下載核心
國內 Linux 核心映站在:

linux.cdpa.nsysu.edu.tw (與底下那台合併了)
ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/v4.x/

ftp.isu.edu.tw


請將 Linux 核心下載至 /usr/src 目錄,我們以 4.4.23 為例,請下載

linux-4.4.23.tar.xz


附帶一提:xz 格式是目前壓縮率最高之非失真壓縮演算法
(失真壓縮演算法->jpg)

3.5 解壓縮

請在 /usr/src 目錄執行:

/usr/src/ # tar xfva linux-4.4.23.tar.xz

此時會出現一個 linux-4.4.23 的目錄,我們要建一個 link

/usr/src/ # ln -s linux-4.4.23 linux

4. 編譯核心

a. /usr/src # cd linux
a.5 複製已存在核心編譯參數,注意那個點!!

/usr/src/linux # cp /boot/config-3.16.0-4-amd64 .config

b. 設定編譯核心參數
/usr/src/linux # make menuconfig

 General setup  --->
    Kernel compression mode (XZ)  --->

 Processor type and features  --->
    Processor family (Core 2/newer Xeon)  --->

[*] Networking support  --->
    Networking options  --->
        [*] Network packet filtering framework (Netfilter)  ---
                 IP: Netfilter Configuration  --->   M
                 IPv6: Netfilter Configuration  ---> M

修改完畢後退出 Linux 核心編譯的設定畫面。


c. time make-kpkg --initrd --revision=1.0.lpm kernel_image -j8

編譯完成後,你會有一個檔案叫:
/usr/src/linux-image-4.4.23_1.0.lpm_amd64.deb

我們再來安裝此檔即可,安裝指令如下:

/usr/src # dpkg -i linux-image-4.4.23_1.0.lpm_amd64.deb



d. 我們編譯到一半如果出現錯誤的話,該如何解決 ? 例如:

  H16TOFW firmware/matrox/g200_warp.fw
  H16TOFW firmware/matrox/g400_warp.fw
make[1]: Leaving directory `/usr/src/linux-3.3.7'
/usr/bin/make -j2   ARCH=i386 \
                             -C Documentation/lguest
make: *** Documentation/lguest: 沒有此一檔案或目錄.  Stop.
make: *** [debian/stamp/build/kernel] Error 2

real    38m37.627s
user    65m58.119s
sys     5m21.180s

上述的問題是 LGUEST 不存在,因此我們看 .config 這檔案,將裡面的 LGUEST 設定
完全註記,再重新執行一次 make menuconfig (回到步驟 b)。


5. 安裝核心


/usr/src# dpkg -i linux-image-4.1.18_1.0.lpm_amd64.deb

其畫面如下:

選取了原先未選的套件 linux-image-4.1.18。
(讀取資料庫 ... 目前共安裝了 79198 個檔案和目錄。)
Preparing to unpack linux-image-4.1.18_1.0.lpm_amd64.deb ...
Done.
Unpacking linux-image-4.1.18 (1.0.lpm) ...
設定 linux-image-4.1.18 (1.0.lpm) ...
Running depmod.
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 4.1.18 /boot/vmlinuz-4.1.18
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 4.1.18 /boot/vmlinuz-4.1.18
update-initramfs: Generating /boot/initrd.img-4.1.18
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 4.1.18 /boot/vmlinuz-4.1.18
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.1.18
Found initrd image: /boot/initrd.img-4.1.18
Found linux image: /boot/vmlinuz-3.16.0-4-amd64
Found initrd image: /boot/initrd.img-3.16.0-4-amd64
done

如果安裝過程中有一些 missing firmware 的訊息,這是表示某些 firmware 沒有裝的意思,請直接安裝此套件,再重裝一次核心即可修正。

6. 重新開機 -> 正常開機(OK)
            -> 當機(以舊版核心重開,設法解決問題)