Cùng với xu hướng đó, các chương trình boot loader hiện nay đang hướng đến việc hỗ trợ nhiều nền tảng khác nhau như các hệ điều hành.. Đề tài này nghiên cứu chương trình boot loader hỗ t
TỔNG QUAN VỀ ĐỀ TÀI
Hình thành vấn đề
Vào những thập kỷ đầu của thế kỷ 21 này, các hệ thống nhúng đang phát triển mạnh mẽ, với tính năng gần như tương đương với những chiếc máy tính cá nhân, đặc biệt là điện thoại thông minh và các hệ thống hỗ trợ trên xe hơi
Với thị trường tiềm năng ấy, các hệ điều hành hiện giờ cũng đang hướng đến việc hỗ trợ đa nền tảng Tuy nhiên, khác với máy tính, với những đặc thù về nguồn điện cung cấp và yêu cầu về thời gian, các hệ thống nhúng cần một quá trình khởi động riêng phức tạp hơn
Cùng với xu hướng đó, các chương trình boot loader hiện nay đang hướng đến việc hỗ trợ nhiều nền tảng khác nhau như các hệ điều hành Đề tài này nghiên cứu chương trình boot loader hỗ trợ đa nền tảng cho hệ điều hành họ Linux, cũng như những chức năng mà một chương trình boot loader cần có để có thể khởi động hệ điều hành thành công.
Lý do chọn đề tài
Hiện tại có rất nhiều chương trình boot loader hỗ trợ boot hệ điều hành họ Linux, trong đó Uboot hiện đang được sử dụng rộng rãi nhất trên các hệ thống nhúng Tuy nhiên khi công nghệ phần cứng không ngừng phát triển và hệ thống nhúng ngày càng phức tạp, việc hiện thực Uboot cho hệ thống mới ngày càng trở nên khó khăn, nhất là phần hiện thực các trình điều khiển
Kế thừa những ưu điểm về tính dễ hiện thực và hiệu suất của Uboot, Barebox – với tên gọi cũ là Uboot v2, là sự kết hợp của Uboot và mô hình driver của nhân Linux kèm theo hỗ trợ các lệnh truy cập theo chuẩn POSIX File API, giúp những người phát triển đ quen thuộc với Linux dễ dàng nắm bắt và hiện thực hơn, đồng thời khắc phục nhược điểm về tính thiếu mô hình chuẩn của trình điều khiển thiết bị trong Uboot
Do kế thừa từ Uboot, những người đ từng làm quen với Uboot cũng sẽ dễ dàng nắm bắt được Barebox
Hơn nữa Barebox cũng có cả hệ thống filesystem - cái mà Uboot thiếu, nên người dùng Barebox cũng dễ dàng truy cập đến dữ liệu hơn mà không cần quan tâm dữ liệu đó trên thiết bị nào, RAM, thẻ SD hay e C,…
Hiệu suất của Barebox cũng tốt hơn Uboot đáng kể, qua thực nghiệm, hệ thống sử dụng Barebox chỉ cần 336 ms để boot (trên bo MX35 dùng CPU ARM) [1] trong khi thời gian boot trung bình khi sử dụng Uboot trên một hệ thống tương đương là 1.1 s [2]
Những boot loader hỗ trợ tốt nền tảng x86 thường không được thiết kế để hỗ trợ tốt cho hệ thống nhúng, còn những boot loader được thiết kế chủ yếu cho hệ thống nhúng thường chỉ hỗ trợ nền tảng x86 ở mức rất cơ bản Barebox được thiết kế chủ yếu cho các hệ thống nhúng nên sẽ có nhiều việc cần làm nếu muốn tạo một phiên bản Barebox hoàn chỉnh có thể boot được Linux trên x86
Hơn nữa với việc hiện thực Barebox trên x86, mọi người có thể dễ dàng làm quen với Barebox mà không cần một hệ thống nhúng và hệ điều hành Linux đặc biệt nào, do x86 là nền tảng phổ biến trên máy tính và những hệ điều hành Linux chạy trên nền tảng x86 đ có sẵn
Do đó luận văn này sẽ tập trung vào đề tài nghiên cứu và hiện thực Barebox trên nền tảng x86.
Phạm vi nghiên cứu
Đề tài này sẽ giới thiệu về Barebox cũng như phương pháp tạo một boot loader cho nền tảng x86 dựa trên Barebox Qua đó sẽ cung cấp tài liệu chi tiết hơn về cách hiện thực Barebox cũng như việc cải tiến chương trình boot loader sau này.
Đối tượng nghiên cứu
Chương trình Barebox boot loader và cách thức boot hệ điều hành Linux trên nền tảng x86.
Mục tiêu đề tài
Mục tiêu đề tài bao gồm hiện thực Barebox chạy trên nền tảng x86 bao gồm các trình điều khiển thiết bị, cấu hình lại Barebox tạo thành hệ thống hoàn chỉnh để có thể boot được Linux kernel
Phương pháp kiểm thử của phiên bản Barebox mới sẽ là feasibility checking, tức là chỉ kiểm tra các chức năng cơ bản và đảm bảo các trình điều khiển mới trong Barebox có thể hoạt động đúng đắn trong trường hợp bình thường và xử lý được những trường hợp lỗi cơ bản.
Ý nghĩa đề tài
Đề tài này sẽ giới thiệu về Barebox cũng như phương pháp tạo một boot loader cho hệ thống mới dựa trên Barebox
Barebox là chương trình boot loader rất phù hợp với những người mới tìm hiểu về boot loader, nhất là những người đ làm quen với hệ điều hành Linux do Barebox có mô hình device/ driver sao chép từ Linux kernel và hỗ trợ các lệnh truy cập theo chuẩn POSIX File API
Hơn nữa, do có hệ thống file, việc hiện thực các tính năng mới sẽ dễ dàng hơn vì độc lập với việc hiện thực các trình điều khiển điều đó sẽ làm chương trình luôn nhất quán và dễ bảo trì cũng như mở rộng
Qua đó sẽ cung cấp chi tiết hơn về cách hiện thực Barebox cũng như việc cải tiến chương trình boot loader sau này.
Kết cấu của đề tài
- Tổng quan về boot loader
- Trình bày cách hiện thực Barebox trên x86
CƠ SỞ LÝ THUYẾT
Tổng quan về boot loader
Trong hệ thống Linux, quá trình boot được xác định từ lúc hệ thống được bật lên, BIOS (basic input/output system) hoặc MaskROM được chạy, rồi đến bộ nạp khởi động (boot loader) được BIOS/MaskROM nạp lên, và kết thúc khi kernel (nhân Linux) lại được boot loader nạp lên và khởi tạo toàn bộ môi trường hệ điều hành
Hình 2.1 Quá trình boot linux cơ bản
BIOS - hệ thống xuất nhập cơ bản hoặc MaskROM, là chương trình (phần dẻo, firmware) được chạy đầu tiên khi hệ thống khởi động Chức năng chính của BIOS/MaskROM là chuẩn bị để các chương trình phần mềm (như boot loader) được lưu trữ trên các thiết bị lưu trữ (chẳng hạn như ổ cứng, ổ USB, eMMC, NAND, v.v…) có thể được nạp, thực thi và điều khiển hệ thống Quá trình này gọi là khởi động
Trên máy tính, khi BIOS khởi động sẽ đọc MBR (Masterboot record) của các thiết bị lưu trữ (512 byte đầu tiên) theo thứ tự ưu tiên do người dùng qui định (Ví dụ: ổ USB, ổ DVD, ổ cứng,…) Nếu BR nào được đánh dấu là boot được, BIOS sẽ thực thi đoạn lệnh được cài trong MBR (446 byte đầu trong MBR) để nạp boot loader lên
Hình 2.2 Cấu trúc của MBR [3]
Boot loader trên hệ thống nhúng thường gồm có 2 phần, phần đầu tiên được gọi là first-stage boot loader dùng để nạp phần còn lại của boot loader do MaskROM bị giới hạn về dung lượng nạp chương trình (do nhà sản xuất hệ thống qui định) Phần thứ 2 là second-stage boot loader và đây mới là chương trình boot loader thực sự
Ví dụ tiêu biểu về 2 phần này của boot loader chính là hệ thống của OMAP
Hình 2.3 Minh họa về boot loader của hệ thống OMAP
U-boot là boot loader thật sự của các hệ thống OMAP, tuy nhiên do kích thức tập tin u-boot.bin vượt quá sự dung lượng hỗ trợ của BIOS, nên cần phải có X-loader (thực chất là một bản U-boot đ được tinh gọn), BIOS sẽ nạp và chạy X-loader, sau đó tới lược X-loader nạp và chạy U-boot
Sau khi được boot loader nạp lên, đầu tiên nhân Linux sẽ tìm cách gán (mount) hệ thống file system (thư mục root /) với một thiết bị lưu trữ cụ thể được định nghĩa trong tham số boot (được truyền bởi boot loader: ví dụ root=/dev/ram0), nếu thành công tiến trình đầu tiên sẽ được chạy Tiến trình này là tiến trình init đầu tiên của nhân Linux, nó được thực thi bằng một tập lệnh chứa trong file mặc định là /sbin/init hoặc /etc/init nếu file đầu không tìm thấy (hoặc được định nghĩa bởi tham số boot: ví dụ init=linuxrc)
Tiếp theo nhân Linux (Linux kernel) xử lý tất cả các hoạt động của hệ điều hành, chẳng hạn như quản lý bộ nhớ, định thời, I/O, liên lạc giữa các luồng xử lý, và kiểm soát toàn bộ hệ thống Boot loader cần chuẩn bị sẵn môi trường cần thiết để nhân Linux có thể hoạt động được
Nội dung của đề tài sẽ không đào sâu vào hoạt động của nhân Linux mà sẽ tập trung vào những gì mà boot loader cần chuẩn bị cho nhân Linux hoạt động sau này.
Cơ sở lý thuyết
Barebox là một chương trình boot loader hỗ trợ cho những hệ điều hành dòng Linux (Ubuntu, Android,…), còn được gọi là U-boot-v2 do nó là sự kết hợp của U-boot và nhân hệ điều hành Linux: sự tinh gọn của U-boot và hệ thống makefile, mô hình driver model và hệ thống quản lý file của nhân Linux Nhờ đó với những người dùng đ quen với U-boot hay Linux, sẽ dễ dàng làm quen với Barebox
Barebox là một phần mềm mã nguồn mở với giấy phép GPLv2 nên người lập trình có thể lấy được mã nguồn mới nhất cũng như những tài liệu về Barebox dễ dàng trên trang chủ của nó.
Các kết quả nghiên cứu liên quan
Ở Việt Nam, vào đầu thế kỷ 21 này, do lĩnh vực phần mềm nhúng còn sơ khai, việc nghiên cứu về boot loader chủ yếu được thực hiện trong các trường đại học như nhóm BKIT Hardware club và phần lớn là hiện thực Uboot trên các hệ thống nhúng trên nền ARM như mini2440
Hiện tại những chương trình boot loader mã nguồn mở vẫn tiếp tục được nâng cấp Sau đây là những boot loader phổ biến dành cho hệ điều hành họ Linux:
- Uboot: boot loader mã nguồn mở được sử dụng rộng rãi trên hệ thống nhúng do ưu điểm chính của Uboot là nhanh và ổn định
- GRUB: boot loader mã nguồn mở, hỗ trợ tốt cho dòng Linux BSD, hỗ trợ nhiều hệ điều hành, nhiều hệ thống tập tin, cung cấp giao diện dòng lệnh lẫn menu
- LILO (Linux Loader): phần mềm mã nguồn mở không bị ràng buộc bởi GPL, chỉ hỗ trợ nền tảng x86
- SYSLINUX: phần mềm mã nguồn mở chỉ hỗ trợ nền tảng x86, hỗ trợ tốt cho việc tạo hệ thống boot trên các thiết bị di động như đĩa CD hay ổ USB, tuy nhiên nó lại không thích hợp cho việc khởi động Linux hoàn chỉnh từ ổ cứng do chỉ hỗ trợ FAT
- Redboot (Red Hat Embedded Debug and Bootstrap firmware): là phần mểm mã nguồn mở dùng cho hệ thống nhúng, hỗ trợ chạy và chức năng phát hiện lỗi cho các ứng dụng nhúng và hệ thống Linux
Bảng sau so sánh tính năng của Barebox với các boot loader phổ biến hiện tại
Bảng 2.1 Bảng so sánh tính năng các boot loader
Tên Barebox Uboot GRUB LILO SYSLIN
GPL 2.0 GPL GPL BSD license
Hỗ trợ đa hệ điều hành
Windows thông qua Windows Boot Manager
Hỗ trợ Windows thông qua Windows Boot Manager
Hỗ trợ Windows thông qua Windows Boot Manager
Hỗ trợ Windows thông qua Windows Boot Manager
PPC, ARM, AVR32, Blackfin, ColdFire, IXP, Leon2, m68k, MicroBlaze, MIPS, NIOS, NIOS2, PXA, x86, StrongARM , SH2, SH3, SH4, x86, PowerPC , Sun Ultra SPARC x86 x86 ARM,
68000, MIPS, PPC, SH, SPARC, SPARCLi te
FAT, VFAT, ext2, ext3, ext2, ext3, ext4,
Không FAT JFFS2 trợ nfs jffs2, cramfs, reiserfs, yaffs2, ubifs, nfs btrfs, zfs, ufs, minix, iso9660, udf, jfs, hfs, hfs+, afs, affs, sfs, xfs, reiserfs, tar, cpio, ntfs, FAT16, FAT32
Trong các boot loader trên, vì Barebox là chương trình mới nên sẽ có nhiều việc cần thực hiện để hoàn thành cho nền tảng x86
Barebox hỗ trợ được nhiều nền tảng, nên việc nghiên cứu về Barebox trên x86 sẽ tạo tiền đề cơ bản và kiến thức tổng quát cho việc hiện thực boot loader này trên những nền tảng khác
2.5 Quy trình và phương pháp nghiên cứu
Luận văn này được thực hiện từ việc nghiên cứu tổng quát về quá trình boot của hệ điều hành họ Linux
Việc hiện thực phiên bản mới của Barebox sẽ bắt đầu từ việc hiện thực các trình điều khiển thiết bị cơ bản để Barebox có thể chạy được Sau đó, phiên bản này sẽ được chỉnh sửa để có thể boot hệ điều hành Linux được cài đặt trên ổ đĩa USB.
Quy trình và phương pháp nghiên cứu
Luận văn này được thực hiện từ việc nghiên cứu tổng quát về quá trình boot của hệ điều hành họ Linux
Việc hiện thực phiên bản mới của Barebox sẽ bắt đầu từ việc hiện thực các trình điều khiển thiết bị cơ bản để Barebox có thể chạy được Sau đó, phiên bản này sẽ được chỉnh sửa để có thể boot hệ điều hành Linux được cài đặt trên ổ đĩa USB.
HIỆN THỰC VÀ THỰC NGHIỆM
Tổng quan về Barebox boot loader
3.1.1 Giới thiệu về Barebox boot loader
Mã nguồn mới nhất của Barebox có thể tải về ở trang chủ của Barebox [4] Hiện tại Barebox đ hỗ trợ cho những nền tảng sau:ARM, Blackfin, MIPS, NIOS2, PPC, x86 và sandbox (dùng để chạy mô phỏng trên Linux)
Do mã nguồn Barebox cập nhật mỗi tháng một lần [5] nên để cho việc thực hiện luận văn được dễ dàng, phiên bản Barebox tháng 3 năm 2012 sẽ được dùng để làm mã nguồn cơ sở
Hình 3.1 Trang chủ của Barebox
3.1.2 Những tính năng nổi bật của Barebox:
POSIX File API: Barebox sử dụng các lệnh truy cập API quen thuộc với người dùng từng sử dụng Linux như các lệnh open, close, read, write, lseek, …, cùng mô hình tập tin đại diện cho thiết bị
Shell: Barebox có các lệnh shell tiêu chuẩn như ls, cd, mkdir, echo, cat,…
Environment Filesystem: Cấu hình cho một hệ thống có thể được chỉnh sửa và lưu trữ trên thiết bị lưu trữ (ổ cứng,…) với lệnh nạp cấu hình “loadenv” và lệnh lưu cấu hình “saveenv”
Filesystem: Khi khởi động, hệ thống được gắn kết vào thư mục gốc “/”, theo sau bởi một hệ thống file thiết bị được gắn kết với thư mục “/dev” để có thể truy cập các thiết bị Các hệ thống tập tin khác có thể được thêm vào tùy thuộc mục đích sử dụng
Driver Model (sao chép từ mô hình Linux): Barebox theo mô hình trình điều khiển Linux: các thiết bị (device) có thể được quy định cụ thể trong một tập tin mô tả phần cứng, và trình điều khiển (driver) sẽ được liên kết cho các thiết bị này nếu chúng có cùng tên
Clocksource: Dùng mô hình clocksource của Linux
Kconfig/Kbuild: Hỗ trợ biên dịch cùng lúc nhiều cấu hình và loại bỏ việc sử dụng rất nhiều macro #ifdefs
Sandbox: Nếu phát triển các tính năng cho Barebox, mô hình "sandbox" biên dịch Barebox như một ứng dụng POSIX trong Linux: nó có thể được sử dụng như một lệnh bình thường và thậm chí có thể truy cập mạng Tập tin thiết bị trong hệ thống tập tin của Linux có thể được sử dụng để mô phỏng các thiết bị
Device Parameters: Có một mô hình tham số trong Barebox: mỗi thiết bị có thể chỉ định các thông số riêng của nó, tồn tại trong mọi trường hợp Các thông số có thể được thay đổi trên dòng lệnh với \ \ = " " Ví dụ, nếu muốn truy cập vào địa chỉ IPv4 cho eth0, có thể thực hiện với lệnh “eth0.ip 192.168.0.7” và “echo $ eth0.ip”
Getopt: Trong Barebox có hỗ trợ hàm getopt () Hàm này giúp lấy được dễ dàng hơn các tham số đầu vào theo sau các lệnh mà người dùng gõ vào
Trình soạn thảo tích hợp: Lệnh script có thể được sửa đổi với một trình soạn thảo tích hợp nhỏ Trình soạn thảo này có mọi tính năng cần thiết cho giao tiếp với người dùng (HyperTerminal trên Windows): di chuyển con trỏ, gõ ký tự, lệnh thoát và lưu
3.1.3 Các thành phần của Barebox
Hình 3.2 Các thành phần chính của Barebox
Phần ARCH bao gồm phần Platform (nền tảng CPU) đ được Barebox hỗ trợ sẵn cho những nền tảng phổ biến như: AR , x86, … Phần CPU do người phát triển thêm vào chủ yếu bao gồm trình điều khiển cho bộ định thời (timer) và cấu hình cần thiết cho CPU lúc mới khởi động như cấu hình về cache
Phần BOARD bao gồm tất cả các khai báo về device (thiết bị) cần thiết cho Barebox và cấu hình ban đầu cho chúng hoạt động (cấu hình về các chân GPIO, các vùng cấp nguồn, cấp xung nhịp, …)
Phần DRIVER bao gồm hiện thực về driver cho những thiết bị đ khai báo trong phần BOARD, Barebox sẽ gắn driver cho device nếu trường tên (name) của chúng trùng nhau Driver trong Barebox rất giống với driver trong Linux do có phần driver model bên trên, nên khi hiện thực một driver nào đó, người phát triển chỉ cần hiện thực những hàm căn bản là đủ (read, write, probe, remove, … ) phần kết nối với Lib và FS đ được Barebox thực hiện
Phần Lib và FS được Barebox lấy 1 phần từ nhân Linux là phần kết nối trung gian quan trọng, nhờ đó các API cung cấp cho các lớp trên rất dễ hiểu và trong sáng
Phần COMMAND cung cấp các hàm để đáp ứng các yêu cầu người dùng Các hàm này rất giống với các lệnh có trong Linux như ls, mkdir,… Ở đây có phần hiện thực cho các hàm quan trọng như bootm (dùng để boot nhân Linux định dạng uImage), bootz (boot cho định dạng zImage)
Hiện thực Barebox trên nền tảng x86
3.2.1 Quá trình thực thi Barebox trên nền tảng x86
Quá trình thực thi của Barebox trên nền tảng x86 được bắt đầu từ khi Barebox được BIOS nạp lên bộ nhớ Để làm được điều này, Barebox phải được ghi vào đầu ổ đĩa như sau:
Hình 3.9 Bố trí của Barebox trên ổ đĩa
BIOS sẽ nạp Barebox lên bộ nhớ theo bố trí như sau:
Hình 3.10 Bố trí của Barebox trên bộ nhớ [8]
Sau khi Barebox được nạp lên địa chỉ 0x7e00, phần đầu tiên được chạy chính là mã nguồn trong tập tin barebox-XXX\arch\x86\boot\boot_hdisk.S
MBR Vùng trống File thực thi của Barebox Phân vùng thứ 1
Trong tập tin boot_hdisk.S thì hàm được gọi đầu tiên chính là start_pre_uboot(), hàm này được hiện thực trong tập tin barebox-XXX\arch\x86\boot\prepare_uboot.c:
Thoát khỏi chế độ real mode realmode_switch_hook()
Thiết lập để Barebox truy cập được hơn 640KB
Enable the A20 gate() setup_gdt() reset_coprocessor()
Chuyển qua chế độ protected mode protected_mode_jump()
Hình 3.11 Hàm start_pre_uboot()
Tiếp theo, hàm protected_mode_jump() được hiện thực trong tập tin barebox- XXX\arch\x86\boot\pmjump.S, hàm này thực hiện 2 nhiệm vụ chính:
- Chuyển sang chế độ protected mode, chế độ sử dụng địa chỉ ảo, trong chế độ này ta không thể sử dụng các ngắt (interrupt) của BIOS được nữa, muốn sử dụng các ngắt này thì ta phải chuyển lại sang chế độ real mode
- Gọi hàm uboot_entry() để tiếp tục quá trình khởi tạo Barebox
Hàm uboot_entry() được hiện thực trong tập tin barebox-XXX\ arch\ x86\ boot\ main_entry.c như sau:
Xóa vùng BSS memset( bss_start, 0x00, bss_stop - bss_start); start_barebox()
Hàm tiếp theo được gọi là start_barebox(), phần này được hiện thực như nhau trên tất cả nền tảng, để biết thêm phần này xin tham khảo mục 3.1.4
Lệnh Linux16 chỉ được sử dụng trên x86 và chỉ hỗ trợ định dạng bzImage (tên tập tin thường là vmlinuz) Lệnh này như sau: const char *cmdline = getenv("bootargs") Đọc kernel_file lh = read_file(kernel_file, &image_size) lh->boot_flag != 0xaa55
Return error lh->setup_sects > 64 Return error lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0200
Return old version lh->loadflags & LINUX_FLAG_BIG_KERNEL Return not bzImage error memcpy((void*)LINUX_OLD_REAL_MODE_ADDR, lh, LINUX_SETUP_MOVE_SIZE); memcpy((void*)(LINUX_OLD_REAL_MODE_ADDR + LINUX_CL_OFFSET), cmdline, strlen(cmdline) + 1) memcpy((void*)LINUX_BZIMAGE_ADDR, ((void*)lh) + real_mode_size, image_size - real_mode_size) bios_start_linux(LINUX_OLD_REAL_MODE_SEGMT)
Trong đó các macro được định nghĩa như sau:
#define LINUX_FLAG_BIG_KERNEL 0x1
#define LINUX_OLD_REAL_MODE_ADDR
(LINUX_OLD_REAL_MODE_SEGMT memory layout và chỉnh lại như sau:
Hình 3.21 Chỉnh lại giá trị malloc area size Để thêm thư mục board mới vào hệ thống makefile, ta cần chỉnh sửa tập tin barebox-XXX\arch\x86\Makefile như sau:
Hình 3.22 Chỉ định thư mục cho bo myPC tại barebox-XXX\arch\x86\Makefile
3.2.5 Hiện thực trình điều khiển để tương tác với Barebox thông qua màn hình và bàn phím
Kiểm thử Barebox trên nền tảng x86
Phương pháp kiểm thử của phiên bản Barebox mới là feasibility checking: kiểm tra các chức năng cơ bản và đảm bảo các trình điều khiển mới trong Barebox hoạt động đúng đắn trong trường hợp bình thường và xử lý được những trường hợp lỗi cơ bản
3.3.1 Cấu hình phần cứng để chạy được Barebox
Do Barebox là boot loader cho hệ điều hành Linux nên cấu hình phần cứng yêu cầu để chạy Barebox và boot được Linux tùy thuộc vào cấu hình yêu cầu của bản Linux cần boot
Yêu cầu phần cứng tối thiểu đối với Barebox trên nền tảng x86 như sau:
- CPU: nền tảng x86 32bit hoặc 64 bit (Intel Pentium, Intel Celeron, Intel Atom, Intel Core 2, AMD Athlon, AMD Phenom,…)
- RAM: vùng malloc(32MB) + vùng chứa tập tin thực thi (khoảng 128 KB) + vùng stack(28KB)
3.3.2 Kiểm thử cho trình điều khiển màn hình và bàn phím
Các mục kiểm tra bao gồm:
- Màu của chữ là xanh lá, nền đen
- Hiển thị xuống dòng bình thường không bị lệch
- Khi hiển thị quá màn hình sẽ tự động đẩy các dòng trên lên
- Xử lý được khi nhấn các phím điều khiển như khoảng trắng (space), xuống dòng (Enter) Nhắc lệnh (Tab)
- Xử lý cho phím Shift: chuyển đổi ký tự cho các phím (Ví dụ từ ‘2’ thành
3.3.3 Kiểm thử cho trình điều khiển ổ đĩa
Các mục kiểm tra bao gồm:
- Kiểm tra các ổ đĩa được dùng trong hệ thống bằng lệnh ls/dev
- Kiểm tra tính đúng đắn của dữ liệu của một ổ đĩa bằng lệnh md
3.3.4 Kiểm thử cho các lệnh cơ bản của Barebox
Các lệnh kiểm tra bao gồm các lệnh cơ bản của Barebox:
- Các lệnh về tập tin , thư mục: cd, ls, mkdir, rmdir
- Các lệnh về phân vùng: addpart, delpart
- Các lệnh khác: sleep, devinfo, timeout
3.3.5 Kiểm thử boot Linux trên ổ đĩa USB
Trong luận văn này Barebox được dùng để boot phiên bản Slax Linux từ ổ đĩa USB Các mục kiểm tra bao gồm:
- Boot được Linux kernel bằng lệnh linux16
- Vào được chế độ đồ họa của Slax bằng lệnh startx sau khi boot được kernel
CHƯƠNG 4 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
Barebox là một chương trình boot loader hỗ trợ cho những hệ điều hành dòng Linux (Ubuntu, Android,…), còn được gọi là U-boot-v2 do nó là sự kết hợp của U- boot và nhân hệ điều hành Linux: sự tinh gọn của U-boot và hệ thống makefile, mô hình driver model và hệ thống quản lý file của nhân Linux Nhờ đó với những người dùng đ quen với U-boot hay Linux, sẽ dễ dàng làm quen với Barebox
Trong luận văn này, một phiên bản Barebox chạy trên nền tảng x86 đ được thêm vào một cấu hình board mới cho phép người dùng tương tác trực tiếp với máy tính thông qua bàn phím và màn hình Người dùng có thể tương tác với Barebox này dễ dàng bằng cách nhập lệnh thông qua bàn phím và theo dõi tiến trình của Barebox trên màn hình Việc tăng kích thước cho vùng nhớ malloc và sửa lỗi cho trình điều khiển ổ cứng đ giúp cho việc boot hệ điều hành Linux trên x86 thành công
Phiên bản Barebox mới này đ có thể boot được hệ điều hành Slax được cài đặt trên ổ đĩa USB
Hướng phát triển tiếp theo cho Barebox chính là việc hỗ trợ thêm các hệ thống file của Linux như ext2 và ext3 và hoàn thiện cơ chế boot để Barebox có thể boot được hệ thống Linux cài đặt hoàn chỉnh trên ổ cứng
[1] Barebox: Booting Linux Fast and Fancy http://archive.fosdem.org/2011/schedule/event/barebox (Tháng 3, 2012)
[2] Reducing Boot Time: Techniques for Fast Booting www.mvista.com/download/fetchdoc.php?docid1 (Tháng 3, 2012)
[3] Inside the Linux boot process http://www.ibm.com/developerworks/linux/library/l-linuxboot/ (Tháng 3, 2012)
[4] Trang chủ của Barebox http://barebox.org/ (Tháng 3, 2012)
[5] Trang lưu trữ mã nguồn các phiên bản Barebox http://barebox.org/download/ (Tháng 3, 2012)
[6] Barebox command reference http://wiki.barebox.org/doku.php?id=commands (Tháng 3, 2012)
[7] Trang giới thiệu về Barebox của Embedded Linux Wiki http://elinux.org/Barebox (Tháng 3, 2012)
[8] Linux Preparation on x86 http://wiki.barebox.org/doku.php?ideloper:x86 (Tháng 3, 2012)
[9] Video Monitor www.cs.uga.edu/~csx070/VideoMonitor.ppt (Tháng 3, 2012)
[10] Technical info - Keyboard maps: http://fjkraan.home.xs4all.nl/comp/trs80- 4p/dmkeilImages/trstech.htm (Tháng 3, 2012)
[11] The Art of Assembly Language Programming, chương 20: The PC
Keyboard http://flint.cs.yale.edu/cs422/doc/art-of-asm/pdf/ (Tháng 3, 2012)
[12] A to Z of C, chương 22: Programming the keys http://guideme.itgo.com/atozofc/ (Tháng 3, 2012)
[13] Professor G A Wainer, Computer Organization http://www.sce.carleton.ca/courses/sysc-3006/f11/Part19-KbdInts.pdf
[14] Redboot http://www.redhat.com/services/custom/embedded/redboot/
[15] The Syslinux Project http://www.syslinux.org/wiki/index.php/The_Syslinux_Project (Tháng 3, 2012)
[16] Boot loader showdown: Getting to know LILO and GRUB http://www.ibm.com/developerworks/library/l-bootload/index.html (Tháng 3, 2012)
A Mã nguồn board myPC: tập tin generic.c
(Chỉ phần thêm vào device cho driver mới)
… static int pc_console_init(void)
/* Register the serial port */ add_generic_device("serial_pc_console", -1, NULL, 0, 8,
IORESOURCE_MEM | 0, &serial_plat); return 0;
} console_initcall(pc_console_init);
B Mã nguồn trình điều khiển serial_pc_console
* (C) Copyright 2012, Bach Nguyen
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE See the
* GNU General Public License for more details
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#include static int VRAM_ADDRESS; static bool enable_ext_key; static char EXT_ASCII_Keys[89] = {
#define OB_FULL (1 priv = dev_request_mem_region(dev, 0); cdev = xzalloc(sizeof(*cdev)); dev->type_data = cdev; cdev->dev = dev; if (plat->f_caps) cdev->f_caps = plat->f_caps; else cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR; cdev->tstc = PC_console_tstc; cdev->putc = PC_console_putc; cdev->getc = PC_console_getc; cdev->setbrg = PC_console_setbaudrate;
PC_console_serial_init_port(cdev); console_register(cdev);
VRAM_ADDRESS = 0; enable_ext_key = false; return 0;
*/ static struct driver_d pc_console_serial_driver = {
* @return result of register_driver
*/ static int PC_console_serial_init(void)
{ return register_driver(&pc_console_serial_driver);
} console_initcall(PC_console_serial_init);
C Mã nguồn tập tin /barebox-XXX/scripts/setupmbr/setupmbrBK.c
(Chỉ phần chỉnh sửa so với tập tin /barebox-XXX/scripts/setupmbr/ setupmbr.c ) static int barebox_overlay_mbr(int fd_barebox, int fd_hd, int fd_linux, long pers_sector_count)
{ const void *barebox_image; const void *linux_image; void *hd_image; int rc; struct stat sb; struct stat sl; struct DAPS *embed; /* part of the MBR */ struct DAPS *indirect; /* sector with indirect DAPS */ off_t required_size; if (fstat(fd_barebox, &sb) == -1) { perror("fstat"); return -1;
} if (fstat(fd_linux, &sl) == -1) { perror("fstat"); return -1;
/* the barebox image won't be touched */ barebox_image = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd_barebox, 0); if (barebox_image == MAP_FAILED) { perror("mmap"); return -1;
/* the linux image won't be touched */ linux_image = mmap(NULL, sl.st_size, PROT_READ, MAP_SHARED, fd_linux, 0); if (linux_image == MAP_FAILED) { perror("mmap"); return -1;
} rc = check_for_valid_mbr(barebox_image, sb.st_size); if (rc != 0) { fprintf(stderr, "barebox image seems not valid: Bad MBR signature\n"); goto on_error_hd;
* the persistant environment storage is in front of the main
* barebox image To handle both, we need more space in front of the
*/ required_size = sb.st_size + pers_sector_count * SECTOR_SIZE;
/* the hd image will be modified */ hd_image = mmap(NULL, required_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd_hd, 0); if (hd_image == MAP_FAILED) { perror("mmap"); rc = -1; goto on_error_hd;
/* check for space */ rc = check_for_space(hd_image, required_size); if (rc != 0) goto on_error_space;
/* embed linux image into the disk drive image */ memcpy(hd_image + SECTOR_SIZE*2, linux_image, sl.st_size);
/* embed barebox's boot code into the disk drive image */ memcpy(hd_image, barebox_image, OFFSET_OF_PARTITION_TABLE);
* embed the barebox main image into the disk drive image,
* but keep the persistant environment storage untouched
* (if defined), e.g store the main image behind this special area
*/ memcpy(hd_image + ((pers_sector_count + 1) * SECTOR_SIZE), barebox_image + SECTOR_SIZE, sb.st_size - SECTOR_SIZE);
/* now, prepare this hard disk image for BIOS based booting */ embed = hd_image + PATCH_AREA; indirect = hd_image + ((pers_sector_count + 1) * SECTOR_SIZE);
* Fill the embedded DAPS to let the basic boot code find the
#ifdef DEBUG printf("Debug: Fill in embedded DAPS\n");
#endif rc = fill_daps(embed, 1, INDIRECT_AREA, INDIRECT_SEGMENT,
1 + pers_sector_count); if (rc != 0) goto on_error_space; debugout(embed, 1);
#ifdef DEBUG printf("Debug: Fill in indirect sector\n");
* fill the indirect sector with the remaining DAPS to load the
* whole barebox image at runtime
*/ rc = barebox_linear_image(indirect, sb.st_size, pers_sector_count); if (rc != 0) goto on_error_space;
* TODO: Replace the fixed LBA starting number by a calculated one,
* to support barebox as a chained loader in a different start
*/ rc = store_pers_env_info(embed, 1, pers_sector_count); if (rc != 0) goto on_error_space; on_error_space: munmap(hd_image, required_size); on_error_hd: munmap((void*)barebox_image, sb.st_size); munmap((void*)linux_image, sl.st_size); return rc;
} int main(int argc, char *argv[])
{ int rc = 0, c; char *barebox_image_filename = NULL, *hd_image_filename = NULL,
*linux_image_filename = NULL; int fd_barebox_image = 0, fd_hd_image = 0, fd_linux_image = 0; long barebox_pers_size = -1; if (argc == 1) { print_usage(argv[0]); exit(0);
/* handle command line options first */ while (1) { c = getopt(argc, argv, "l:m:d:s:hv"); if (c == -1) break; switch (c) { case 's': barebox_pers_size = strtol(optarg, NULL, 0); break; case 'm': barebox_image_filename = strdup(optarg); break; case 'd': hd_image_filename = strdup(optarg); break; case 'l': linux_image_filename = strdup(optarg); break; case 'h': print_usage(argv[0]); rc = 0; goto on_error; case 'v': printf("setupmbr for u-boot-v%s\n", UTS_RELEASE); printf("Send bug reports to
'barebox@lists.infradead.org'\n"); rc = 0; goto on_error;
} } if (barebox_image_filename == NULL) { print_usage(argv[0]); rc = -1; goto on_error;
} fd_barebox_image = open(barebox_image_filename, O_RDONLY); if (fd_barebox_image == -1) { fprintf(stderr, "Cannot open '%s' for reading\n", barebox_image_filename); rc = -1; goto on_error;
} fd_hd_image = open(hd_image_filename, O_RDWR); if (fd_hd_image == -1) { fprintf(stderr, "Cannot open '%s'\n", hd_image_filename); rc = -1; goto on_error;
} fd_linux_image = open(linux_image_filename, O_RDWR); if (fd_hd_image == -1) { fprintf(stderr, "Cannot open '%s'\n", linux_image_filename); rc = -1; goto on_error;
} if (barebox_pers_size < 0) barebox_pers_size = 0; rc = barebox_overlay_mbr(fd_barebox_image, fd_hd_image, fd_linux_image, barebox_pers_size); on_error: if (fd_barebox_image != -1) close(fd_barebox_image); if (fd_hd_image != -1) close(fd_hd_image); if (barebox_image_filename != NULL) free(barebox_image_filename); if (hd_image_filename != NULL) free(hd_image_filename); return rc;
D Quá trình khởi tạo của Barebox trên nền tảng ARM a- Hàm reset()
Hàm reset() trong file \barebox-XXX\arch\arm\cpu\start.c chính là hàm đầu tiên được chạy khi barebox.bin được nạp set the cpu to SVC32 mode arch_init_lowlevel() mmu_cache_flush disable MMU stuff and caches board_init_lowlevel() board_init_lowlevel_return()
Hàm arch_init_lowlevel() và hàm board_init_lowlevel() là 2 hàm dành cho người phát triển hiện thực, có thể có hoặc không tùy theo cấu hình của hệ thống
Nếu nền tảng ARM mà CPU trong SoC không phải là ARM chuẩn, người phát triển cần hiện thực hàm arch_init_lowlevel() để cấu hình CPU cho đúng (như các cấu hình cho cache, )
Hàm board_init_lowlevel() là hàm để kích hoạt các mô đun phần cứng cơ bản của hệ thống (như GPIO, CPG, RA ) đảm bảo cho các mô đun sau này hoạt động Tuy nhiên nếu các driver dành cho các mô đun sẽ khởi tạo hết các cấu hình hay chương trình chạy trước Barebox đ làm các công việc này thì ta không cần hiện thực hàm board_init_lowlevel() Để có thể boot được hệ điều hành sau này, CPU ARM cần phải ở chế độ supervisor và phải vô hiệu hóa cache, thêm nữa là với chương trình boot loader ta chỉ cần dùng địa chỉ vật lý là đủ nên ta sẽ tắt luôn MMU Tất cả các bước này đều được Barebox làm sẵn trong hàm reset() này b- Hàm board_init_lowlevel_return ()
Setup the stack relocate to link address if necessary call start_barebox with its absolute address
Hình 4.2 Hàm board_init_lowlevel_return()