Các file thành phần trong boot linux
Giới thiệuQuá trình khởi động hệ thống nhúng Linux bao gồm một số giai đoạn. Nhưng dù cho bạn khởi động trên máy tính để bàn x86, hay trên một máy tính nhúng lõi ARM thì quy trình này nó giống nhau một cách đáng ngạc nhiên. Bài viết này phân tích quá trình khởi động một máy tính nhúng Linux mà cụ thể là từ board Beagle Bone Black. Từ khởi động ban đầu cho tới u-boot, kernel và sau cùng là các applications trên userspace. Show Tổng quan hệ thống nhúng LinuxDướì góc độ phần mềm, một hệ thống nhúng Linux có thể chia thành 4 cấp độ:
Ở̀ góc độ phần cứng, một hệ thống nhúng bao gồm các thành phần:
U-Boot BootloaderDas U-Boot (hay còn được gọi tắt là u-boot) là một bootloader có mã nguồn mở được sử dụng rộng rãi trong các hệ thống nhúng nhỏ. Nó hỗ trợ sẵn cho các kiến trúc, bao gồm 68k, ARM, Blackfin, MicroBlaze, MIPS, Nios, SuperH, PPC, RISC-V và x86. Chức năng chính của nó là khởi tạo phần cứng và load các thành phần khác của OS (linux kernel, rootfs, device tree) lên RAM và trao quyền lại cho linux kernel. Ưu điểm của u-boot sở hữu dựa trên các nguyên tắc thiết kế mà nhà phát triển nó đặt ra, bao gồm:
Để biết thêm chi tiết về các nguyên tắc thiết kế các bạn có thể tham khảo The 10 Golden Rules of U-Boot design. Boot ProcessBoot Proccess có thể chia thành nhiều giai đoạn (Stage). Tuy nhiên, thông thường sẽ chỉ gồm 2 giai đoạn chính là Single-Stage và Two-Stage. Dưới đây là quá trình mô tả của Two-Stage. Soc ROM BootloaderKhi hệ thống khởi động lần đầu tiên, hoặc reset. Quyền kiểm soát hệ thống sẽ thuộc về reset vector, nó là một đoạn mã assembly được ghi trước bởi nhà sản xuất chip (Manufaturer ). Sau đó reset vector sẽ trỏ tới địa chỉ vùng nhớ chứa các đoạn mã khởi động đầu tiên, cụ thể là boot rom. Nếu không có reset vector thì bộ xử lý sẽ không biết nên thực thi bắt đầu từ đâu. Chức năng chính của boot rom đấy chính là sao chép nội dung trong file "MLO" hay còn được gọi là Second Program Loader (SPL) - chương trình tải phụ vào IRAM và excute nó. Do bộ nhớ của boot rom khá nhỏ nên rom code cũng được giới hạn ở việc khởi tạo một số phần cứng cần thiết cho việc load SPL lên hệ thống như: MMC/eMMC, SDcard, NAND flash. Các phần cứng này được gọi chung là boot device. Lấy ví dụ load lên từ SDcard: Rom code lựa chọn boot device (load từ thẻ nhớ, flash vv..) phụ thuộc vào việc cấu các pin thông qua switch/jump trên phần cứng. Second Program Loader (SPL)SPL - chương trình tải phụ. Nhiệm vụ chính của SPL đó chính là tiếp tục setup các thành phần cần thiết như DRAM controler, eMMC vv.. Sau đó load U-boot tới địa chỉ CONFIG_SYS_TEXT_BASE của RAM.
Note: Đối với Single-Stage sẽ không có SPL. U-BootSau khi được load vào RAM, u-boot sẽ thực hiện việc relocation. Di dời đến địa chỉ relocaddr của RAM (Thường là địa chỉ cuối của RAM) và nhảy đến mã của u-boot sau khi di dời. Lúc này u-boot sẽ kiểm tra xem file uEnv.txt có tồn tại hay không. Nếu có thực hiện load nó vào RAM ở bước tiếp theo. Bản thân uEnv.txt là một bootscript, nó định nghĩa các tham số cấu hình, kernel parameters. Các tham số này mặc định đã được cấu hình trong u-boot. Tuy nhiên chúng ta có thể thêm, sửa, xóa các cấu hình này thông qua file uEnv.txt. Việc load uEnv.txt là một sự tùy chọn (Optional), nghĩa là nó có thể có hoặc không. Tiếp theo u-boot sẽ tiếp tục load kernel, device tree vào RAM tại các địa chỉ mà đã được cấu hình từ trước ở trong mã nguồn u-boot hoặc trong file uEnv.txt. Sau cùng nó sẽ truyền toàn bộ kernel parameters và nhường quyền thực thi lại cho kernel. Đến đây ta có thể đặt ra một số câu hỏi: Tại sao lại phân chia ra Single-Stage/Two-Stage, thêm SPL vào làm gì, sao không load thẳng U-boot vào IRAM ngay từ đầu đi?
Tại sao phải thực hiện Relocation?
U-boot thực sự ở đâu? Sử dụng lệnh bdinfo trong trong u-boot command line ta có được các thông tin dưới đây: Như vậy, sau khi được load tới một địa chỉ thấp trên RAM u-boot u-boot sẽ được relocation tới địa chỉ relocaddr (0xDFF5D000).
Linux KernelSau khi nhận được quyền kiểm soát và các kernel parameters từ u-boot. Kernel sẽ thực hiện mount hệ thống file system (Rootfs) và cho chạy tiến trình Init trên RAM. Đây là tiến trình được chạy đầu tiên khi hệ thống khởi động thành công và chạy cho tới khi hệ thống kết thúc. Tiến trình Init sẽ khởi tạo toàn bộ các tiến trình con khác trên user space, các applications tương tác trực tiếp với người dùng. Lúc này, hệ thống của chúng ta đã hoàn toàn sẵn sàng cho việc sử dụng. Kết LuậnQuá trình khởi động của một hệ thống nhúng có thể chia ra thành nhiều giai đoạn:
Lưu ý rằng, số lượng giai đoạn khởi động trên các hệ thống linux embededed có thể khác nhau. Nó có thể chia thành nhiều giai đoạn hơn hoặc thậm chí chỉ một giai đoạn duy nhất. Đ̣iều ́này phụ thuộc rất nhiều vào bài toán thiết kế và chi phí đầu tư của đơn vị sản xuất. Tham khảo từ Pentester Academy TV: Embedded Linux Booting Process (Multi-Stage Bootloaders, Kernel, Filesystem) |