วิธีการคอมไพล์ kernel ของ raspberry pi

Posted by | August 4, 2013 | Raspberry pi, Tutorial | No Comments
kernel_compiler

วันนี้ทางผมจะเล่าถึง วิธีการคอมไพล์ kernel ของ raspberry pi กันต่อ
Kernel เป็นส่วนดูแลบริหารทรัพยากรของระบบ ระหว่าง ส่วนติดต่อกับฮาร์ดแวร์พื้นฐานตั้งแต่ หน่วยความจำ หน่วยประมวลผลกลาง และ อุปกรณ์อินพุตและเอาต์พุต กับ ส่วนของซอฟต์แวร์ โปรแกรม หรือ Application ที่รันในระบบปฏิบัติการ เป็นส่วนพื้นฐานของระบบปฏิบัติการ
โดยตัว Kernel ของ Raspberry pi หรือ Kernel ของระบบปฏิบัติการ Linux โดยทั่วไปจะถูกสร้างมาให้พอดีกับการใช้งาน เพื่อให้ทำงานได้เร็วใช้ resource น้อย โดยมาก การใช้งาน embedded system resource เราจะมีจำกัด และ อาจจำเป็นต้องเพิ่มเติมอุปกรณ์ ที่ไม่ได้เป็นมาตราฐานของ Raspberry pi อย่างเช่นจอ TFT หรือ ไอซี ADC, DAC ,Sensor บทความนี้ จะเป็น guide ให้เห็นเราได้เรียนรู้วิธีสามารถ kernel และ ปรับแต่ง kernel ขึ้นมาใหม่ เขาทำกันอย่างไงครับ

Kernel_Layout.svg

ภาพประกอบอธิบายการเชื่อมต่อของ kernel

สำหรับวิธีคอมไพล์ kernel เราต้องคอมไพล์บนเครื่องนั้นๆ จะดีที่สุด เพราะว่ามันต้องใช้ compiler ที่คอมไพล์ sorce code เป็น machine code ของเครื่องนั้น ในการคอมไพล์ kernel จะประกอบไปด้วยไฟล์ที่เกี่ยวข้องจำนวนมาก ถ้าคอมไพล์บน raspberry pi จะใช้เวลานานครับ 8-9 ชั่วโมง ในบทความตอนนี้จึงจะแนะนำ การคอมไพล์ ผ่าน cross compiler ให้คอมไพล์บนเครื่องคอมพิวเตอร์ปกติ แล้ว นำไปใช้งานบน raspberry pi ได้

สำหรับ cross compiler เป็นวิธีการคอมไพล์โปรแกรมโดยใช้เครื่องสถาปัตยกรรมอื่น คอมไพล์โปรแกรม (ไฟล์ binary) ในกรณีนี้เราคอมไพล์ ไฟล์ที่รันบนเครื่อง ARM v6 (raspberry pi) บนเครื่อง x86 ซึ่ง มันจำเป็นเพราะว่า พลังการประมวลผลในเครื่อง x86 มีมากกว่า ARM v6 มาก  มันจะช่วยให้คอมไพล์โปรแกรมได้เสร็จเร็วกว่ามากๆ

โดยเครื่องที่จะใช้คอมไพล์ จะเป็นเครื่องที่ติดตั้ง Ubuntu ไว้นะครับ จะเป็น xubuntu ,ubuntu หรือจะรันบน แบบในบทความที่ผ่านมา สามารถใช้งานได้นะครับเช่นกันครับ

1. เตรียม Source ทุกอย่างให้พร้อมก่อน

1. อันดับแรก เราต้อง Source Code ของ Kernel ก่อน

kernel ล่าสุด ->  https://github.com/raspberrypi/linux

วิธีการ download src ที่ยอดนิยม ใช้ git clone มายังเครื่อง

$ sudo apt-get install git
cd    [หรือ]    cd /home/xubuntu
git init
git clone --depth 1 git://github.com/raspberrypi/linux.git
git checkout rpi-3.2.27

2. จากนั้น ติดตั้ง compiler ของ ARM6 และ เครื่องมืออื่นในการ config kernel ใหม่ พิมพ์ตามนี้

$ sudo apt-get install gcc-arm-linux-gnueabi make ncurses-dev

3. ดาวน์โหลด tools ตัวล่าสุดของ raspberry pi tools นี้จะเกี่ยวข้องการ compresse image ของ kernel

$ cd    [หรือ]    cd /home/xubuntu
git clone https://github.com/raspberrypi/tools

ตอนนี้เราจะมี kernel source และ tool คอมไพล์เลอร์ ลงมาที่เครื่อง ubuntu เราล่ะ

2. Setting Cross-Complier

1. เซ็ทตัวแปร

  • เซ็ทตัวแปร KERNEL_SRC ที่ชี้ไปยังที่เก็บ kernel src ในที่นี้เราเก็บไว้

    $ KERNEL_SRC=/home/xubuntu/linux
  • เช็ทตัวแปร CCPREFIX ให้ชี้ไปยังที่เก็บ เครื่องมือ คอมไพล์เลอร์ ตัวล่าสุด

    $ CCPREFIX=/home/xubuntu/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-

2. จากนั้นเข้าไปที่ kernel source ที่โหลดมา แล้วทำการ clean หนึ่งรอบ

$ cd \home\xbuntu\linux
make mrproper

3. จากนั้น cp ไฟล์ kernel config จาก Raspberry Pi มา สำหรับมือใหม่การ copy config.gz ทำได้สายทาง
วิธีแรก ก๊อปปี้ผ่าน network โดยใช้คำสั่ง scp อันนี้เราต้องหา IP ของ raspberry ให้เจอ แล้วพิมพ์คำสั่ง

$ cd \home\xbuntu\linux
scp pi@[RPI IP]://proc/config.gz .

ตัวอย่าง

$ scp pi@192.168.1.6://proc/config.gz .

super tip สำหรับคนที่หา IP ของ raspberry pi ไม่เจอ ใช้ nmap สแกนหาได้ครับ

$ sudo apt-get install nmap
sudo nmap -sV -p 22 192.168.1.0-25

วิธีที่สอง อาจจะสะดวกว่า ก๊อปปี้จาก sd-card ของ raspberry pi เลย ไฟล์จะอยู่ที่

/proc/config.gz ใน sd-card แล้ว ก๊อปปี้ เข้าไปไว้ใน directoty ของ kernel source

จากนั้น แตกไฟล์ config.gz ให้เป็น .config

$ zcat config.gz > .config

3. Config Kernel และ การคอมไพล์

1. ตอนนี้ไฟล์ที่ต้องใช้พร้อมแล้ว คือต้องมี kernel source ,คอมไพล์เลอร์ และ มี config ไฟล์เดิม จากนนี้ไป เป็นการปรับแต่ง config kernel
ถ้าเราต้องการ config kernel แบบตัวเก่า (ในกรณี update version แล้วอยากได้ kernel image ใหม่)

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make oldconfig

สำหรับคนที่อยากปรับแต่ง

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make menuconfig

กด [enter] แล้วจะขึ้นเมนูให้เราเลือก config kernel ดังภาพ
สิ่งที่สำคัญ มันจะต้องขึ้นว่า Linux/Arm นะครับ ไม่งั้น อาจจะเป็นการคอมไพล์ kernel ของเครื่อง x86 ไปแทน
kernel_compiler
เราสามารถเลือกได้ว่าจะเอาอุปกรณ์ตัวไหนออก จะเอาตัวไหนเพิ่ม โดยการกด [space bar] จะขึ้นเป็น เครื่องหมายดอกจัน (*) กด [space bar] อีกครั้งมันจะเปลี่ยนเป็น [M] ,[ ] ตามลำดับ
2. หลังจาก ที่เรา config kernel ใหม่ได้ดังใจแล้ว จะ build  kernel ใหม่โดยการพิมพ์

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make

เราสามารถใช้ parallel make ได้ โดยใช้ flag -j ในกรณีเครื่องเป็น duocore ให้ใช้ flag -j3 ถ้าเป็น quad core ให้ใช้ flag -j5 ให้เอาจำนวน core +1 ครับ

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} make -j3

4. ขั้นตอนการสร้าง

1. Set environment variable ที่ชื่อ  MODULES_TEMP  เพื่อชี้ไปยังตำแหน่งที่จะติดตั้งไฟล์ kernel module ชั่วคราว

ตัวอย่าง

$ MODULES_TEMP=/home/xbuntu/modules/

2. จากนั้นสั่ง make kernal module ใหม่ด้วยคำสั่ง

$ ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} make modules_install

3. สั่งสร้างไฟล์ zImage ใหม่ โดยใช้เครื่องมือ ที่อยู่ใน directory tools

$ cd /home/xubuntu/tools
./imagetool-uncompressed.py ${KERNEL_SRC}/arch/arm/boot/zImage

จากขั้นตอนนี้ เราจะได้ ไฟล์ kernel.img ไฟล์นี้เป็น kernel image ของ kernel ที่ผ่านการคอมไพล์มาใหม่

5. ขั้นตอนการติดตั้ง

วิธีการติดตั้ง ทางผมใช้วิธี ก๊อบปี้ เข้า sd-card เลยครับ พังเป็นพัง วิธีคือ เอา sd-card ของ raspberry pi มาเสียบที่เครื่อง  จากนั้น ระบบ ubuntu จะ mount sd-card เป็นสองไดรพ์ /boot-partition-uuid  กับ /rootfs-partition-uuid จะเป็น ไดรฟ์ สองตัว ที่มี ไอดี ต่างกัน อยู่ใน /media

1. ก๊อปปี้ ไฟล์ kernel.img เข้าไปยัง /boot ของ sd-card

$ sudo rm /media/boot-partition-uuid/kernel.img
sudo cp kernel.img /media/[boot-partition-uuid]/

2. ก๊อปปี้ ส่วน kernel module ไปทับ module เดิมใน card ด้วย โดยในที่นี้ kernel module จะติดตั้งชั่วคราวใน MODULES_TEMP ซึ่งในตัวอย่างคือ /home/xbuntu/modules/

$ sudo rm -rf /media/rootfs-partition-uuid/lib/modules/
sudo rm -rf /media/rootfs-partition-uuid/lib/firmware/
cd /home/xbuntu/modules/
sudo cp -a ./fireware /media/[rootfs-partition-uuid/]/lib/
sudo cp -a ./modules /media/[rootfs-partition-uuid/]/lib/

3. หลังจาก ก๊อปปี้ เสร็จ ให้ทำการ sync sd-card ด้วยครับ

$ sync;
sync;

จบกระบวนการแล้ว จากนั้น นำ SD-Card ตัวใหม่ไปติดตั้งที่ Raspberry Pi ตอนนี้ ถ้า เครื่องบูตกลับมาได้ แสดงว่า kernel ที่เราสร้างใช้งานได้ ขอแสดงความยินดี เราได้ kernel ใหม่แล้วครับ

คำเตือน โปรดระวัง ถ้าไม่เข้าใจว่าขั้นตอนแต่ล่ะอย่างกำลังทำอะไร ยังไม่ควรทำนะครับ ควรกลับไปดูตัวอย่าง หรือ วีดีโอ ใน youtube เยอะก่อนครับ ถ้าทำอะไรผิคพลาดไป มีความเป็นไปได้สูงว่า ท่านจะ boot กลับเข้าไปใช้ kernel ใน raspberry pi ไม่ได้ ก็ถ้าเป็นแบบนี้ ก็ลงใหม่ครับ

เพิ่มเติม http://elinux.org/RPi_Kernel_Compilation
http://mitchtech.net/raspberry-pi-kernel-compile/

About chang

ชื่อ “ช้าง” ส่วนมากเขาจะเรียกว่า “พี่ช้าง” แล้ว มีความสนใจทางเทคโนโลยีทางคอมพิวเตอร์ อิเล็กทรอนิกส์ และ หุ่นยนต์ เป็นทั้งนักคิด นักประดิษฐ์ ชอบทดลองเล่น จนเดี่ยวนี้รู้สึกว่าจะเล่นมากกว่ามืออาชีพไปสักแล้ว