Muốn tự build distro linux cho một máy tính nhúng như thế nào ? Hẳn là các bạn có dùng qua các kit như Raspberry Pi, Orange Pi thì không thể không cài một hệ điều hành cho nó trước khi sử dụng. Vậy người ta đã tạo ra cái phiên bản hệ điều hành (file .img) đó như thế nào ? Và mình có thể tạo ra một file ảnh như vậy để bỏ vào Raspberry Pi và tận hưởng thành quả không ?

Giới thiệu

Tất nhiên mọi việc đều bắt nguồn từ thắc mắc mà ra, mình có dạo quanh ARMVN có thấy một số bài viết về linux, nhưng vấn đề là muốn thử làm 1 bản trên phần cứng thực tế mà không biết chọn cái nào, nhiều lúc mấy cái board mà các anh giới thiệu một là không bán nữa, hai là bán mà mình cũng ko có điều kiện mua được. Đành phải sử dụng cây nhà lá vườn, nhà có gì thì dùng đấy thôi. May mắn tình cờ lại đọc được bài viết build image cho Raspberry Pi nên thử luôn. Đúng ra là phải viết riêng một bài nhưng sau một hồi tìm kiếm thì có người đã viết hay hơn rồi nên dựa trên bài viết và sự đồng ý của anh minatu mình viết lại một chút để cho người mới tiếp cận có thể dễ làm hơn chút. Bản gốc các bạn có thể tham khảo tại đây . Ở bài viết này mình tập trung qua một số khái niệm và từng bước thực hiện cũng như kết quả để phù hợp hơn với các bạn mới bắt đầu

Distro linux ?

Chúng ta có thể xem qua khái niệm ở wiki thì distro là một hệ điều hành, hiểu nôm na thì nó cũng giống như là win xp, win7, win 10, khác cái là mấy bản win chúng ta xài phải trả tiền (VN thì hầu hết xài win free không bằng cách này thì cách khác) còn mấy cái dính tới linux thì hầu hết là free. Ở các distro linux có thể được cài phần mềm này hoặc phần mềm khác tùy vào phiên bản khác nhau, nhưng đều dựa trên nhân linux hay còn gọi là linux kernel. Chỉ với linux kernel này thì ai cũng có thể tự build được riêng một bản distro phục vụ cho nhu cầu của mình

Vì sao lại có nhu cầu làm distro riêng này ? Có 5 lý do chính mà mình thấy được

  • Miễn phí
  • Chạy được trên một hệ thống ít tài nguyên, tuơng thích được nhiều phần cứng khác nhau mà ít đòi hỏi phải nâng cấp
  • Bảo mật
  • Tốc độ
  • Hỗ trợ từ cộng đồng

Nếu các bạn quan sát hình trên thì ta có thể thấy Linux kernel đóng vai trò quan trọng thế nào trong một hệ thống, nó như là cầu nối giữa anh hardware và chị software có thể hoạt động trơn tru được, thiết nghĩ nếu không có anh vịt ở giữa thì không biết bảy ngàn tám trăm năm nữa 2 anh chị này có đuợc gặp nhau không

Yocto ?

Yocto cho phép tạo ra một bản Linux có thể tùy biến được để người dùng có thể build cho nhiều target (board, mcu,.. ) khác nhau.

Yocto sinh ra để giải quyết 2 vấn đề

  • Tìm xây dựng một distro phù hợp nhất với yêu cầu hệ thống sao cho ít tốn công sức nhất.
  • Đồng thời với việc tạo distro thì cũng sinh ra 1 môi trường phát triển cho môi trường đích luôn.

Bản thân Yocto không có source, nó cung cấp các tool, giống như một bộ khung (framework) cho người phát triển tùy biến dễ dàng nhất có thể.

Poky là một hệ distro linux ở dạng tham chiếu của Yocto Project.

Bitbake ?

Bitbake là một công cụ cốt lõi của Yocto Project. Nó bao gồm 1 bộ thông dịch các script được viết trong các file recipe (công thức tạo phần mềm), và thực hiện các lệnh trong đó. Nó mô tả lại và tự động hóa qúa trình người ta đưa một phần mềm vào một distro.

Về việc đưa một phần mềm vào distro, ta có thể thấy nó bao gồm vài bước chính. Từ việc tải source code (ở đây là tải source code chứ không phải các gói đã được build sẵn đâu nhé, nó gần giống với ArchLinux, Gentoo và hoàn toàn khác với Ubuntu) , thực hiện các bản patch (sửa source hoặc kịch bản build đề phù hợp mục đích sử dụng), biên dịch, cuối cùng là tích hợp vào distro (kèm theo các thông số cấu hình).

Mục đích của bitbake là tạo ra một quy trình tự động mà đầu vào là các file kịch bản, bitbake sẽ tự làm các công việc còn lại. Ý tưởng của bitbake thực sự rất hay, dù rằng để áp dụng thực tế một cách trơn tru thì cần khá nhiều công sức để hiểu cách nó làm việc với các công cụ truyền thống.

Thực hiện

Mục đích

Thực hiện build một bản distro cho Raspberry Pi dùng Yocto dựa trên bản distro có sẵn của Yocto là Poky, thực chất nó là quá trình build lại Poky để sử dụng được cho Raspberry Pi, cụ thể ở đây là chip 900MHz quad-core ARM Cortex-A7

Chuẩn bị

  • Máy tính sử dụng ubuntu (mình dùng bản 16.04), có ổ cứng trống nhiều 1 chút (~30GB)
  • Raspberry Pi và các đồ dùng liên quan như thẻ nhớ, nguồn, …
  • Modul USB2UART để log lại khởi động của Raspberry PI
  • Một chút kiến thức cơ bản về ubuntu

Cấu hình

Trước khi bắt đầu thì cần phải cài các gói cần thiết

$ sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \build-essential chrpath socat libsdl1.2-dev xterm

Tạo thư mục chứa Yocto và các thư mục khác có liên quan tới build và tải poky

$ mkdir raspberrpi_krogoth
$ cd raspberrpi_krogoth
$ git clone -b krogoth git://git.yoctoproject.org/poky.git

Tuy nhiên bản Poky này mặc định không hỗ trợ Raspberry Pi, muốn có cho Pi thì ta phải add thêm vào Poky bằng cách

$ cd poky
$ git clone -b jethro git://git.yoctoproject.org/meta-raspberrypi

Chờ tải xong là coi như đi được 1 đoạn đường rồi.
Quay về lại thư mục raspberrpi_krogoth và chạy command

$ cd ..
$ source poky/oe-init-build-env build

Do poky chia các gói phần mềm thành các layer, mà RPI thì không có sẵn, nên ta phải khai báo thêm vào trong 2 file là bblayers.conflocal.conf trong thư mục raspberrpi_krogoth/build/conf, 2 file này bạn có thể dùng editor nào sửa cũng được, hoặc là vi, hoặc nano, hoặc click chuột mở bằng Text editor có sẵn của ubuntu
bblayers.conf thì cần thêm vào

/home/xxx/raspberrypi_krogoth/poky/meta-raspberrypi \

local.conf thì cần thêm vào raspberrypi để build xong có file image cho Raspberry, nếu không chọn thì hệ thống tự động build cho qemu

MACHINE ?= "raspberrypi"

Tiếp tục thay đổi cài đặt mkknlimg

Mở file raspberrpi_krogoth/poky/meta-raspberrypi/recipes-kernel/linux/linux-raspberrypi.inc
Tìm đến hàm do_rpiboot_mkimage() sửa thành như sau:

${STAGING_DIR_NATIVE}/usr/libexec/mkknlimg --dtok ${KERNEL_OUTPUT} ${KERNEL_OUTPUT}

Build

Tiếp tục quay lại Terminal ngay sau lệnh source poky/oe-init-build-env build sẽ có thông báo về bitbake
Gõ lệnh sau để thực hiện build

$ bitbake rpi-basic-image

Khi bắt đầu build không có lỗi sẽ có kết quả dạng như sau:

Việc còn lại là chờ đợi, việc chờ đợi này tùy thuộc vào máy tính của bạn thế nào ? RAM nhiều không ? CPU khỏe không, có xài SSD không ? Nếu không thì bạn cứ yên tâm ngủ 1 giấc, vì build xong cũng mất cả buổi rồi. Mình tranh thủ chờ build viết hướng dẫn cho các bạn luôn 😀

Kết quả

Sau khi build xong sẽ có file image tại đường dẫn

raspberrpi_krogoth/build/tmp/deploy/images/rpi-basic-image-raspberrypi-20170216035601.rootfs.rpi-sdimg

Ghi file image

Ở đây để cho đơn giản với các bạn chưa quen lệnh command bên ubuntu cũng như tránh format nhầm ổ đĩa khi dùng lệnh thì mình khuyên dùng Windisk32  trên windows để cài file bin vào thẻ nhớ cho nhanh và an toàn. File rpi-basic-imageđược copy từ bên ubuntu sang.

Lưu ý: Nhớ format định đạng thẻ nhớ về dạng FAT32 trước.

Bỏ thẻ nhớ vào Raspberry PI, kết nối với PL2303 và Putty với baud 115200 sẽ có thông báo log như sau, đăng nhập với user là root và không cần pass

Tạm kết

Vậy là mình đã hoàn thành được chặng đường đơn giản nhất là build một distro cho Raspberry PI dựa trên Yocto. Nếu các bạn có một thắc mắc là linux là gì ? Mấy cái ubuntu với linux nó khác gì nhau thế nào ? Muốn hiểu sâu hơn về Distro, Yocto và Bitbake và Linux thì không còn cách nào tốt hơn là gặp anh Google thân yêu. Bài này chỉ là bước tham khảo đầu tiên để bạn làm quen với con đường đầy chông gai phía trước. Cũng chưa chắc, biết đâu lại có một bài hướng dẫn nào tốt hơn nữa thì sao ?