Build, chạy nhân Linux trong QEMU ARM

Chạy một bản Linux tối giản trên Qemu ARM Bài này sẽ làm một ví dụ để chỉ ra sự liên quan giữa các thành phần của một hệ thống Linux thông qua việc build, chạy Kernel trên board vexpress-a9 mô phỏng bằng Qemu. Đó là Kernel, Root file system, Busybox, Init. 1. “Chém” chút về quá trình khởi động của Linux Về cơ bản, quá trình khởi động Linux có 2 giai đoạn. Giai đoạn đầu là load kernel lên RAM và chạy Giai đoạn thứ hai là kernle sẽ tự động mount hệ thống file rồi các ứng dụng trên hệ thống file được mount. Bất cứ bản Linux nào, dù lớn, dù bé đều thì tối thiểu phải có 2 giai đoạn ở trên. ...

tháng 4 10, 2017

So sánh giữa Buildroot và Yocto Project

Bài này sẽ dịch lại Slide thảo luận giữa 2 diễn giả là Alexandre Belloni, Thomas Petazzoni từ Free Electrons tại Embedded Linux Conference 2016. So sánh giữa Buildroot và OpenEmbedded/Yocto Project 1. Điểm chung Đều là build-system cho Embedded Linux. Mục tiêu là có thể customize, build hoàn chỉnh một Embedded Linux System. Bao gồm: filesystem, toolchain, kernel, bootloaders Đều được build từ source Sử dụng cross-compilation Rất actively trong cả dự án đang maintained và phát triển. Được sử dụng rộng dãi trong công nghiệp. Tài liệu tốt, nhiều khóa đào tạo. Sử dụng Free Software (phần mềm tự do) 2. Khác nhau 2.1 Về tư tưởng chung Buildroot: Tập trung mạnh vào sự đơn giản Dễ sử dụng dễ hiểu và mở rộng Các trường hợp đặc biệt sẽ được thực hiện qua extension scripts. Sử dụng được ác công nghệ, ngôn ngữ đang tồn tại hiện nay: kconfig, make Minimallist : phương trâm càng nhỏ càng tốt Không phụ thuộc vào mục đích sử dụng Cộng đồng mở, nhưng có vendor hoặc tổ chức nào quản lý Yocto Hỗ trợ nhiều kiến trúc phổ biến OpenEmbedded: Chỉ hỗ trợ qemu Yocto Project : Thêm những nền tảng máy khác Chỉ cung cấp core recipes, sử dụng layer để mở rộng và thêm gói cũng như nền tảng phần cứng. Việc custom chỉ xảy ra ở các layer riêng biệt Hệ thống build đa năng: cố gắng linh hoạt nhất có thể để handle hầu hết các trường hợp sử dụng. Cộng đồng mở, nhưng vẫn được quản lý bởi Yocto Project Advisory Board, vốn được tạo bởi các công ty tài trợ OpenEmbedded là một dự án cộng đồng độc lập 2.2. Về output Buildroot Ouput chính là một root filesystem image Cũng có thể kèm toolchain, kernel image, bootloader đi kèm. Hỗ trợ nhiều định dạng: ext2/3/4, ubifs, iso9660, etc. Không có gói binary, không có hệ thống quản lý gói Nhiều người gọi là firmware generator Không thể update qua các gói Cần update toàn bộ hệ thống, như Android. Không nên tin tưởng việc update 1 phần. Yocto Project: Tạo bản phân phố, đầu ra là một loại các package. Hệ thống quản lý là tùy chọn cho hệ thống đích Có thể cài đặt, update chỉ 1 phần của hệ thống Cũng có thể sinh *root filesystem images thông qua cài đặt các tool tạo image. Hỗ trợ: ext2/3/4, ubifs, iso9660, etc…cũng có cả VM Images, vmdk, vdi qcow2 Cuối cùng, có thể tạo ra 1 disk image Cũng có thể sinh một SDK kèm theo image, cho phép app developer compile, test ứng dụng của họ mà không cần tích hợp chúng trong quá trình build. Nhưng SDK phải được đồng bộ với thay đổi của image. 2.3. Cấu hình (Configuration) Buildroot: Sử dụng lại kconfig từ Linux kernel Giao diện đơn giản thông qua {menu,x,b,g} config Toàn bộ configuration được lưu trong 1 file duy nhất .config/defconf Định nghĩa toàn bộ các khía cảnh của hệ thống: kiến trúc, kernel version/config, bootloader, user-space packages, etc. make menuconfig, make -> đơn giản Build cùng một hệ thống cho nhiều máy khác nhau: sẽ hoàn toàn riêng biệt Cần 1 tool để sinh defconfig từ nhiều fragements Có thể làm được những không quá dễ Quá trình build hoàn toàn tách biệt cho mỗi máy Yocto Project: Quá trình configuration được chia ra làm nhiều phần: Distribution configuration: cấu hình gói general, toolchain, chọn libc. Machine configuration: định nghĩa architecture, đặc tính machine, BSP. Image recipe: Quy định package nào sẽ được cài dặt trên hệ thống đích Local configuration: bản phân phối với máy build luôn, có bao nhiêu thread có thể sử dụng khi compiling, có hay không xóa bỏ code sau khi build. Cần biêt về nhiều lớp khác nhau mới có thể sử dụng chúng. Cho phép build cùng 1 image cho nhiều máy hoặc nhiều distribution hoặc nhiều ảnh cho 1 máy 2.4. Layers (Lớp) Buildroot: Không có khái niệm này Tất cả package được maintained từ các kho chính thức Cho phép chất lượng rất tốt nhờ được review bởi experts Sử dụng *BR2_EXTERNAL Cho phép lưu trữ định nghĩa package, cấu hình và các thông tin khác. Chỉ có 1 BR2_EXTERNAL Sử dụng cho các package custom hoặc proprietary package Chỉ có thể add, không cho phép override. Yocto Project: Cơ chế layer cho phép sửa/thêm package mới hoặc tạo ảnh mới Xóa bỏ sự ngăn cách giữa core build system, BSP và các chỉnh sửa Scales được, bên thứ 3 có thể cung cấp layer với BSPs của họ hoặc một tập recipes để handle những ứng dụng đặc trưng Sử dụng layer cùng nhau phải đảm bảo tính tương thích và dùng chung OE branch base. Cần để ý chất lượng layer, việc review vẫn chưa có tính hệ thống OpenEmbedded Metadata Index đưa ra danh sách các layer, recipe, máy hiện mà framework này hỗ trợ tại http://layers.openemdedded.org/layerindex Có cơ chế override cho phép điều chỉnh recipe dựa trên máy hoặc distro. 2.5. Về toolchain Tự build toolchain, dựa trên gcc, lựa chọn được thư viện C Libraries (glibc, uClibc, musl) Sử dụng các toolchain build sẵn từ bên ngoài: Có vẻ bên Buildroot thì dễ dàng hơn vì nó có sẵn bên trong Chỉ thực sự support tốt với những layer từ các vendor trong Yocto Project Buildroot: không có trong slide Yocto Project : không có trong slide 2.6 Về mức độ phức tạp Buildroot: ...

tháng 1 20, 2017

Thực hiện 4 Stage khi Compile bằng tay (Manual)

Ta đã có bài giới thiệu về 4 Stage khi Compiling rồi. Đầu ra của Stage trước sẽ là đầu vào của Stage sau. Trong compile thông thường dạng $gcc -o HelloWorld HelloWorld.c Với câu lệnh trên,ta sẽ không thấy kết quả của 3 Stage đầu tiên. Để hiểu rõ hơn, chúng ta hãy thử thực hiện các Stage bằng tay xem liệu ta có thể tạo ra file chạy như câu lệnh compile trên hay không. ...

tháng 1 8, 2017

4 Stage khi biên dịch HelloWorld.c

Gần đây, phải giải quyết giúp một vài vấn đề liên quan đến Cross-Compile. Có tìm hiểu kĩ một chú về Compiler, Linker, và Loader. Bài này xin nói về cơ bản về quá trình biên dịch một file source code (.c) sang dạng chạy được. Ví dụ: từ HelloWorld.c thành HelloWorld và chạy được như ví dụ dưới đây. HelloWorld.c #include int main() { print("Hello World \n"); return 0; } Kết quả chạy: ...

tháng 1 1, 2017

Một chút hiểu thêm về "Hello World" trong C.

Gần đây, gặp một số vấn đề về Loader-Linker giữa môi trường build và môi trường chạy trong Cross-Compiling. Có thể bất kì chương nào trong Linux cũng vậy. Nhưng chỉ xét một chường trình được build bằng C thì một chương trình sẽ được chạy 2 cách dưới đây 1. Chương trình hoàn toàn là tĩnh Không có symbol nào cần phải được (resolved) trước khi chạy. Không yêu cầu bất cứ một thư viện run-time nào. Kernel cứ thế load vào, rồi nhảy đến vị trí của Program Entry là chạy. Có kích thước lớn Để build được nó thì các thư viện phụ thuộc khi build cũng phải có phiên bản static. Lấy ví dụ HelloWorld #include int main(int argc, char *args[]) { printf("Hello, Ajinomoto \n"); return 0; } Khi build tĩnh bằng (hầu như phải có -static) ...

tháng 12 21, 2016

Lỗi về Case-sensive khi biên dịch C (gcc)

Khi phát triển các ứng dụng trên Linux, nhúng Linux, mình hầu như cài đặt và sử dụng một máy ảo (tạo bằng VMWare hoặc VirtualBox). Cài trình biên dịch GCC lên đó. Hầu như mình có thể làm mọi việc trên môi trường máy ảo đó trừ quản lý source. Vì cty mình vẫn sử dụng SVN với Client là Tortoise. Linux cũng có rất nhiều công cụ tuơng tự Tortoise nhưng để tránh những vấn đề không cần thiết, có thể làm phiền người khác liên quan đến tương thích SVN, mình vẫn chọn quản lý bằng Tortoise trên Windows. ...

tháng 12 1, 2016

"Data structure alignment" là gì? Tại sao phải hiểu nó khi code C.

Đây là một chủ đề hay, có rất nhiều resource bằng tiếng Việt khá dễ hiểu rồi. Bài này chỉ mô tả ngắn gọn một chút cùng với vài ví dụ thực nghiệm để hiểu các khái niệm về cơ bản về Data Structure Aligment. Giả sử ta có một cấu trúc sau: #include <stdint.h> typedef struct { uin8_t mem1; uin8_t mem2; uin32_t mem3; }ST_FOOL_1; typedef struct { uin8_t mem1; uin8_t mem2; uin8_t mem3; uin8_t mem4; uin8_t mem5; }ST_FOOL_2; Cấu trúc ST_FOOL_1 sẽ được miêu tả trong 6 byte? Cấu trúc ST_FOOL_2 sẽ được miêu tả trong 5 byte? Tùy theo tham số trong quá trình “Data structure alignment”, mà cấu trúc trên sẽ được chứa trong số bộ nhớ cần thiết khác nhau. ...

tháng 10 26, 2016

Phân biệt Build vs Host vs Target

Khái niệm Cross-compiling là rất phổ biến khi phát triển các hệ thống nhúng. Với người mới, hiểu rõ khái niệm là rất quan trọng. Bài này sẽ cố gắng phân biệt 3 khái niệm về môi trường. Đó là Host Enviroment, Build Enviroment, và Target Enviroment. Có thể dịch nôm na là Môi trường chủ, Môi trường biên dịch, và Môi trường chạy đích. Vì có thể dẫn đến hiểu nhầm hoặc không rõ nghĩa nên chúng ta nên sử dụng trực tiếp thì hơn. ...

tháng 8 3, 2016

2 cách sử dụng thư viện trong Linux

Mình đang gặp 1 vấn đề là 1 hàm F1() trong thư viện động mình viết (lib1.so) không hoạt động đúng như mong muốn. Trong hàm _F1()_có gọi một loại hàm F21(), F22(), F23()…F2n() từ 1 thư viện tĩnh (lib2.a) khác. Khi build không gặp lỗi, Khi biên dịch thư viện động này với 1 file sample.c để chưa main() để chạy thử và gọi hàm _F1() _từ thư viện động lib1.so. Kết quả vẫn mong muốn. ...

tháng 6 12, 2016

CMake - Một ví dụ đơn giản

Trong bài tôi đã giới thiệu qua về CMake. Như ta đã biết nó cung cấp tính tăng giúp việc sinh ra Makefile một cách hiệu quả. Nhất là đối với các dự án phức tạp. Nó cũng cung cấp thêm các bộ sinh khác để sinh cấu trúc quản lý source cho các IDE khác nhau như Visual Studio, KDE. Trong giới hạn, tôi sẽ nói về việc sử dụng CMake để build một simple project trên cả Windows và Linux. ...

tháng 8 16, 2015