Tìm hiểu về embedded linux

Giới Thiệu Về Embedded Linux

13/04/2020

Như tên gọi của nó, Embedded Linux gồm có 2 phần embedded và Linux. Điều kiện cần và đủ để tìm hiểu về chủ đề này là phải có kiến thức nền tảng về embedded và biết cách sử dụng Linux cơ bản.

Ngày nay, các thiết bị nhúng Linux hiện diện ở khắp mọi nơi từ chiếc smartwatch nhỏ bé đến Tivi hay chiếc điện thoại di động phức tạp, đến siêu máy tính, xe ô tô và cả tàu vũ trụ,… Những điều này làm cho embedded Linux trở thành một miền đất đầy hứa hẹn cho những ai đam mê và chinh phục nó.

Vậy điều gì làm các thiết bị nhúng Linux trở nên phổ biến như vậy:

  • Linux có những chức năng thiết yếu. Nó có scheduler tốt, hỗ trợ networh, USB, Wi-fi, Bluetooth, cùng nhiều thiết bị khác. Bạn có tự muốn viết lại các driver này không trong khi nó đã có sẵn và hoạt động rất tốt.
  • Linux được port vào nhiều kiến trúc vi xử lý, bao gồm các bộ vi xử lý phổ biến như ARM, MIPS, x86, PowerPC.
  • Linux là hệ điều hành mã nguồn mở, nghĩa là bạn có thể tự do lấy source code và chỉnh sửa cho phù hợp với yêu cầu của bạn. Bạn cũng có thể thêm bớt cách tính năng, những kỹ thuật mới rồi đóng góp cho cộng đồng cùng phát triển.
  • Linux có cộng đồng hoạt động rất sôi nổi. Kernel Linux phát hành mới mỗi 10-12 tuần, các bản phát hành được đóng góp từ các lập trình viên từ khắp nơi trên thế giới. Một cồng đồng hoạt động sôi nổi nghĩa là bạn cũng được hỗ trợ về hardware, protocol,…
  • Giấy phép mã nguồn mở, một điều tuyệt với cho các sản phẩm việc tự do phát triển.

Bốn thành phần quan trọng của embedded Linux:

  • Toolchain: chứa trình biên dịch và các công cụ cần thiết để tạo code cho thiết bị. Những thứ khác đều phụ thuộc vào toolchain.
  • Bootloader: Nó cần thiết cho quá trình khởi tạo và tải, boo Linux kernel.
  • Kernel: trái tim của hệ thống, có nhiệm vụ quản lý tài nguyên và giao tiếp với hardware.
  • Root filesystem: chứa các thư viện và chương trình được chạy sau khi quá trình khởi tạo kernel hoàn thành.

Ngoài ra, còn có các thành phần khác góp phần tạo nên embedded Linux, nhưng chúng ta chỉ đề cập đến các thành phần thiết yếu.

Linux giải quyết tốt các vấn đề về viễn thông, robustness và các giao tiếp phức tạp khác. Tuy nhiên không phải vấn đề nào nó cũng giải quyết được và  phần cứng nào nó cũng hoạt động được.

“Đọc sách nhiều là tốt, nhưng sẽ tốt hơn nếu bạn đọc đúng sách, vào đúng thời điểm, tại đúng nơi và theo đúng cách.” Bạn nên tìm một tài liệu để có thể đồng hành cùng quá trình học tập. Nếu bạn chưa tìm ra tài liệu nào thì quyển sách “Mastering Embedded Linux Programming” sẽ là một người thầy tuyệt vời giúp bạn chinh phục thế giới Linux rộng lớn. Hiện tại, quyển sách đã được tái bản lần hai với nội dung cập nhật theo phiên bản Linux mới, hứa hẹn sẽ cung cấp nhiều kiến thức bổ ích.

Học tập là một quá trình suốt đời chứ không phải ngày một ngày hai, học embedded Linux cũng vậy, đó là một hành trình đầy vất vả và gian nan.

Linux không dành cho những ai thiếu kiên nhẫn, không phải lúc nào việc học tập cũng xuôi chèo mát máy, sẽ có lúc bạn gặp phải những vần đề nan giải thử thách lòng kiên nhẫn của bạn. Những lúc như thế, bạn sẽ càng chứng tỏ năng lực của mình với khả năng tìm tòi, giải quyết các vấn đề. Hãy nhờ đến sự trợ giúp từ thầy cô, bạn bè và cả cộng đồng mạng rộng lớn.

Linux thay đổi không ngừng. Linux liên tục, liên tục được cập nhật để fix bug tồn tại, cải thiện hiệu năng hoạt động,… Vì thế, bạn cũng cần cập nhật các kiến thức liên tục để có thể làm việc một cách hiệu quả.

Không có con đường tắt nào để học embedded Linux cả. Hãy bắt đầu từ nền tảng, mọi thứ sẽ trở nên dễ dàng. Một ngôi nhà to cao, cần một nền móng vững chắc, bạn cũng vậy, đừng đốt cháy giai đoạn mà phá hỏng một “ngôi nhà”.

Nếu bạn đã quen với các vi điều khiển, bạn có thể làm được rất nhiều thứ từ chúng. Giả sử khi mua một kit SSTM32F1, bạn sẽ có bộ nhớ Flash, RAM, một bộ vi xử lý một hoặc hai lõi và một vài các thiết bị ngoại vi. Các board này thường có các phần mềm đi kèm để bạn có viết code, nạp và chạy “bare-metal” trên các kit này mà không cần một hệ điều hành thật sự. Tức là, tất cả điều này được đóng gói lại thành một board mạch sao cho thân thiện trong quá trình sử dụng và phát triển của của bạn.

Kiến trúc này hơi khác so với các bộ vi xử lý có khả năng chạy Linux. Thông thường, các vi xử lý này thường nhồi nhét gần như mọi thiết bị ngoại vi mà bạn có thể nghĩ ra và phần nhiều bạn chưa từng nghe qua. Đổi lại chúng thường xuyên thiếu RAM và dung lượng lưu trữ. Trên hết, việc khởi chạy một thiết bị thế này thường là một cài đặt có liên quan đến boot ROM, thành phần chịu trách nhiệm tải bootloader của bạn.

Soucre: //www.thirtythreeforty.net/

Từ đó, bootloader sẽ tải Linux, nó sẽ cấu hình phần còn lại của các thiết bị ngoại vi và chạy một loạt chương trình cài sẵn. Mạng, logic và giao diện người dùng đều sẵn sàng giống như một hệ thống Linux. Đối với ứng dụng, môi trường trông giống hệt hệ thống Linux trên máy tính – tất cả các API đều giống nhau, hệ thống file trông bình thường và nó có thể nói chuyện với thế giới bên ngoài bằng các giao thức mạng thông thường.

Soucre: //www.thirtythreeforty.net/

Tất cả điều này được lưu trữ trong một file system image nhỏ, có thể nhỏ tới 4 MB, tùy thuộc vào nhu cầu của thiết bị. Nhưng đây là một điểm mấu chốt, mọi thành phần phần mềm chạy trên Linux gần giống với phiên bản mà bạn chạy trên máy tính! Linux cung cấp tất cả sự trừu tượng mà các ứng dụng cần để thực thi, vì vậy công việc của bạn được giảm xuống để có thể bộ tải khởi động và nhân Linux được chuyển sang phần cứng của bạn.

  • Phần cứng trong Embedded Linux
    • Vi xử lý
    • Bộ nhớ RAM
    • Bộ nhớ lưu trữ
  • Phần mềm trong Embedded Linux
    • Bootloader
    • Boot ROM
    • Kernel
    • File System

Phần cứng trong Embedded Linux

Hầu như tất cả các thành phần này có thể thay thế. Các lựa chọn được đưa ra cho mỗi trong số này chiếm một phần lớn trong các quyết định thiết kế bạn đưa ra trong khi chọn một hệ thống nhúng.

Vi xử lý

Tất nhiên, bộ xử lý của bạn sẽ xác định rất nhiều khả năng của hệ thống của bạn. Hầu hết các hệ thống Linux nhúng nhỏ, giá rẻ mà bạn làm việc sẽ sử dụng lõi ARM hoặc MIPS và hầu hết ngành công nghiệp đang phát triển hơn về phía ARM. [Hãy chú ý đến RISC-V; nó là một kiến trúc tập lệnh mã nguồn mở, sẵn sàng cho thời gian chính nhưng đã nhận được rất nhiều sự quan tâm của ngành.]

Trên đỉnh của kiến trúc, mỗi nhà cung cấp silicon thêm nhiều thiết bị ngoại vi khác nhau. Giống như anh em vi điều khiển, đây là những mẩu silicon nhỏ chỉ để thực hiện một chức năng, chẳng hạn như USB hoặc SPI. Chúng thường được cấu hình thông qua các thanh ghi memory-mapped và thông thường, các nhà sản xuất sẽ thêm nhiều sức chứa vào một sản phẩm mới bằng cách sao chép IP ngoại vi từ một phần cũ hơn hoặc bằng cách thêm nhiều bản sao của thiết bị ngoại vi vào phần mới.

Bộ nhớ RAM

Những bộ xử lý này thường không bán kèm với bộ nhớ mà được cung cấp riêng. Các loại bộ nhớ thông thường mà bạn có thể quen thuộc là: SDRAM thường được sử dụng ở cấp thấp, trong khi DDR được sử dụng cho các phần mạnh hơn. Bộ xử lý cung cấp một module để quản lý bộ nhớ; module này được khởi tạo bởi mã khởi động của nhà sản xuất hoặc bởi giai đoạn đầu tiên của bootloader.

Bộ nhớ lưu trữ

Lưu trữ, khác với bộ nhớ, là nơi không thể mã hóa và dữ liệu của bạn được lưu trữ. Trên các hệ thống nhúng, nó gần như chắc chắn sẽ là một dạng bộ nhớ flash. Ngay cả trong trường hợp hệ thống khởi động từ mạng, thông thường, điều này vẫn được hỗ trợ bởi bộ tải khởi động được lưu trữ trong flash.

Có nhiều loại bộ nhớ flash. Bạn có thể đã quen thuộc với các loại thẻ nhớ SD hoặc microSD. Ngoài ra, còn có eMMC, một loại phiên bản nhúng của SD, thường được hàn trên các board mạch. Do đó, thường thích hợp khi dùng trong quá trình học tập và nghiên cứu. Một loại bộ nhớ lưu trữ khác, có thể kể đến là NOR hay NAND, chúng không cần một trình điều khiển đính kèm để lưu trữ.

Phần mềm trong Embedded Linux

Nếu bạn đang phát triển một phần mềm nhúng cho hệ thống như thế này, bạn cần phải cung cấp cho nó một bộ tải khởi động [bootloader], hạt nhân [kernel] và hệ thống tập tin [file system]. Rất may, một khi Linux khởi động, nó thường hỗ trợ nhiều thiết bị ngoại vi trên hệ thống sử dụng các trình điều khiển một cách nhất quán, thay vì phải tự viết các trình điều khiển các vi điều khiển.

Bạn không cần phải quản lý tất cả các phần này cùng một lúc. Có các bản phân phối Linux nhúng cung cấp bộ công cụ hoàn chỉnh để giúp bạn xây dựng firmware image với tất cả những thứ này đi kèm.

Bootloader

Bootloader là chương trình đầu tiên mà kỹ sư hoặc hacker có quyền kiểm soát. Nó chỉ phức tạp khi cần để tải kernel và chạy nó. Trong thực tế, nó không quá phức tạp. Hệ thống Linux nhúng của bạn gần như chắc chắn sẽ sử dụng U-Boot, universal bootloader. Bootloader loại bỏ việc tải drivers của các thiết bị ngoại vi lên bộ nhớ, chỉ đủ để đọc kernel và bắt đầu thực thi kernel.

Boot ROM

Boot ROM là một đoạn mã nhỏ được nhúng trong bộ xử lý, được cung cấp bởi nhà sản xuất. Nó rất, rất đơn giản và thông thường, nó ngay lập tức chạy bootloder từ các ổ lưu trữ khác nhau – thường thì thứ tự khởi động này được chỉ định trong bảng dữ liệu của bộ xử lý.

Kernel

Linux phải được port từng kiến trúc, từng bộ phận và từng board mạch khác nhau. Tất cả các driver được chuyển tới kernel. Có rất nhiều trong số chúng, nhưng vì xu hướng của các nhà sản xuất thường sử dụng lại IP, nên nó có thể quản lý được. Thông thường, một port bao gồm:

  • Architecture code: Mã kiến trúc cung cấp các routine cấp thấp cho những thứ rất cơ bản như tính toán thanh ghi, đồng bộ hóa, v.v. Port Linux sang kiến trúc hoàn toàn mới là một khối lượng công việc khổng lồ và bạn có thể sẽ không thể thực hiện việc này nhanh chóng.
  • Drivers: Trình điều khiển chiếm phần lớn mã nguồn kernel. Điều này là do Linux gửi trình điều khiển cho mọi thiết bị được Linux hỗ trợ trong một cây mã nguồn. Hầu hết chúng không cần thiết cho hệ thống nhúng của bạn – ví dụ: bộ định tuyến MIPS hoàn toàn không sử dụng để điều khiển cho Intel Quick Sync. Vì vậy, hầu hết các trình điều khiển này thậm chí không được biên dịch cho các hệ thống nhỏ.
  • The device tree: Cây thiết bị là một phần rất quan trọng của việc port. Nó giúp cho kernel biết cách phần cứng thực sự được kết nối với hệ thống. Cây thiết bị là một configuration file cho trình điều khiển Linux. Điều này có nghĩa là trình điều khiển Linux có thể sử dụng lại – nếu bạn thêm một entry vào device tree cho một thiết bị phần cứng trên hệ thống và biên dịch các drivers có liên quan, trình điều khiển sẽ tìm mục đó và tự thiết lập.

File System

Hệ thống tập tin rất quan trọng vì một số hệ thống nhúng tốt hơn các hệ thống nhúng khác – Hệ thống tập tin có thể giúp điều này. Nếu hệ thống đang sử dụng eMMC hoặc thẻ SD, thì nó trông giống như một thiết bị khối bình thường, và bạn có thể sử dụng ext2/3/4 tiêu chuẩn hoặc các công cụ như hệ thống tệp thân thiện với flash [f2fs]. Nếu bạn sử dụng rwa flash, bạn cần sử dụng nhiều hệ thống tập tin bí truyền được thiết kế cho raw flash, chẳng hạn như JFFS2 hoặc UBIFS.

Tiếp theo, hệ thống init chịu trách nhiệm quản lý vùng người dùng. Bạn có thể đã nghe nói về systemd? Nó được sử dụng trên các hệ thống nhúng lớn hơn. Tuy nhiên, nó quá lớn đối với các hệ thống thực sự nhỏ, thường sử dụng SysV init với tập lệnh shell đơn giản. Hầu hết các bản phân phối Linux nhúng đều cung cấp cái này.

Và cuối cùng, shell là thứ sẽ giúp bạn tương tác với hệ thống. Theo truyền thống, điều này được thực hiện qua kết nối nối tiếp UART, nhưng đôi khi bạn cũng có thể tương tác trên màn hình. Nếu bạn đưa hệ thống của mình đến một dấu nhắc lệnh shell, ít nhất chắc chắn rằng hệ thống của bạn đã hoạt động!

Chủ Đề