PDA

View Full Version : Hướng dẫn viết 1 chương trình boot đơn giản trên linux



lttq
09-02-2012, 07:46 PM
Quá trình khởi động của 1 hệ thống máy tính.
Khi bật nút nguồn thì BIOS là chương trình được chạy đầu tiên.BIOS là chương trình nhúng vào ROM của máy tính.Đặc điểm là nó sẽ chạy 1 đoạn code đã biên dịch,thông thường do nhà sản xuất viết sẵn.Chủ yếu là để nạp và kiểm tra các devide hoặc hardware gọi là POST (Power-on Self-test),và gọi Master Boot Record từ 512byte ở sector đầu tiên của ổ đĩa.BIOS đọc dữ liệu trong master boot record, nạp vào RAM tại địa chỉ 7C00:0000 và chuyển quyền điều khiển cho chương trình này.

BIOS thường hỗ trợ đọc MBR từ :
1/cdrom
2/floppy
3/hard disk
...
Tùy vào lựa chọn của ta mà nó sẽ ưu tiên lấy cái nào.

MBR nằm trong phần sector đầu tiên nằm trên 1 thiết bị boot,có thể là ổ đĩa,cd ...
Từ đó sẽ nạp boot code khoảng tầm 512 byte,bao gồm MBR,partition table(tổng cộng là 510b) và 1 cái signature(2byte thường là AA55).MBR sau đó gọi bootloader tương ứng,trên linux nổi tiếng là lilo và grub.
Bootloader sẽ nạp kernel(copy hdh lên bộ nhớ thực thi(RAM chẳn hạn)) rồi hdh sẽ chạy,nạp các tiến trình ....

Cấu trúc thông dụng của MBR có thể xem tại đây (http://en.wikipedia.org/wiki/Master_boot_record).Dĩ nhiên đây là cấu trúc thông dụng của các máy tính hiện tại.MBR trên ổ đĩa khác CD khác.Nhưng nhìn chung,thì MBR có cấu trúc cũng có nét tương tự mà thôi.

Sau đây là hướng dẫn viết 1 boot loader cho 1 hệ thống nhúng đơn giản.Chương trình viết = asm trên linux,dịch bằng nasm.Ta sẽ viết 1 chương trình boot,dùng ngắt 10h để xuất ra chữ helloworld trên màn hình



BITS 16
;code vs vxl 16bit - dich bang nasm
org 0x7c00
; chỉ thị giúp các instruction sinh ra được nạp vào 0x7c00 theo đúng
;địa chỉ nạp code boot

Start: jmp loader
msg db "hello world", 0

Print:
lodsb ;load next character
or al,al ;xem al null chưa-> bật cờ để jz nhảy đến PrintDone
jz PrintDone
mov ah, 0eh ;tham số cho ngắt 10h
int 10h ;xuất ra màn hình từng ký tự
jmp Print

PrintDone:
ret

loader:

xor ax,ax ;empty ax
mov si,msg
Call Print

xor ax,ax ; empty ax
cli
hlt ;clear hết các ngắt

times 510- ($-$$) db 0 ;chừa 510 byte để nạp MBR và partion table

dw 0xAA55 ;2 byte cho signature là 512,đúng như structure của 1 sector đầu tiên


Hướng dẫn test :
đầu tiên phải biên dịch dc code trên:
Mình dùng asm để dịch :


apt-get install nasm
nasm -f bin -o quanrock/boot.bin quanrock/boot.asm

Sau đó dd toàn bộ dữ liệu vào image của floopy hoặc cdrom


dd qua floopy :
dd if=quanrock/boot.bin of=quanrock/boot.flp
dd qua cdrom
dd if=quanrock/boot.bin of=dev/boot.iso


Cài virtualbox từ ubuntu software center
Sau đó new 1 OS mới
Trong phần setting thì open file img của floopy là xong

Hình ảnh khi chạy trên virtualbox của Sun
8621

Tham khảo : codeproject.com/Articles/36907/How-to-develop-your-own-Boot-Loader#_Toc231383186

hardwire
09-02-2012, 09:56 PM
bài này hay quá nhưng tiếc là dùng nasm để dịch

lttq
09-02-2012, 10:26 PM
bài này hay quá nhưng tiếc là dùng nasm để dịch

Bạn dịch bằng ch trình khác cũng được mà.Nếu không được thì chỉnh sửa lại 1 tí cho phù hợp vì kiến thức nạp MBR cơ bản là thế thôi.
Mà sao lúc bạn tên là panfider lúc thì hardwire thế.

hardwire
12-02-2012, 10:59 AM
từ đoạn mã này lttq thử viết ra đoạn load một hoặc nhiều sector vào bộ nhớ
rùi sau đó jump tới đoạn mã đó
đoạn mã đó chính là kernel cho phép người dùng nhập lệnh xem ngày giờ
bạn thử làm như vậy xem
bạn nên xử dụng các instruction in/out để thực hiện