Skip to content

BIOS (Legacy)

BIOS (Basic Input/Output System) là firmware khởi động của máy tính x86 theo kiến trúc IBM PC: chạy ngay sau khi cấp nguồn, khởi tạo phần cứng, rồi nạp sector đầu tiên của disk để chuyển quyền cho bootloader. Trên phần cứng hiện nay, vai trò này đã chuyển sang firmware UEFI, nhưng từ "BIOS" vẫn được dùng rộng rãi với nhiều nghĩa khác nhau. Trang này trình bày theo thứ tự: các nghĩa của từ "BIOS", trình tự boot của legacy BIOS, dịch vụ ngắt, cấu trúc MBR và giới hạn của nó, nơi lưu cấu hình, so sánh với UEFI và CSM, các firmware BIOS mã nguồn mở, và cách kiểm tra chế độ boot trên Linux. Firmware UEFI và EDK2 xem tại EDK2 (UEFI); vị trí của firmware trong chuỗi boot nói chung xem tại Bootloader trong hệ nhúng Linux.

Các nghĩa của từ "BIOS"

Khi đọc tài liệu hoặc trao đổi, cần phân biệt từ "BIOS" đang được dùng theo nghĩa nào.

Nghĩa Ví dụ cách dùng Thực chất
Legacy BIOS "boot ở chế độ Legacy", "BIOS mode", grub-install --target=i386-pc Firmware chạy ở real mode 16-bit, cung cấp dịch vụ qua ngắt phần mềm, boot từ MBR. Đây là nghĩa gốc và là nội dung chính của trang này.
Firmware của mainboard nói chung "vào BIOS chỉnh boot order", "UEFI BIOS", "BIOS setup" Trên máy đời mới, đây gần như luôn là firmware UEFI. Màn hình setup là một ứng dụng của firmware UEFI, chạy trong pha BDS (xem EDK2).
Tên còn lại trong giao diện và tài liệu "BIOS update", dmidecode -t bios, /sys/class/dmi/id/bios_version Phiên bản firmware của mainboard, bất kể là legacy BIOS hay UEFI. Bảng SMBIOS vẫn gọi mục này là "BIOS Information".
CSM "bật CSM", "Legacy support" Module trong firmware UEFI giả lập giao diện legacy BIOS để chạy hệ điều hành hoặc option ROM cũ (xem mục CSM).

Như vậy, câu "máy này dùng BIOS" thường không đủ thông tin. Điều cần xác định là máy đang boot theo kiểu legacy (qua MBR và ngắt BIOS) hay theo kiểu UEFI (qua ESP và file .efi), vì điều này quyết định cách phân vùng disk, cách cài bootloader và việc có dùng được Secure Boot hay không.

Trình tự boot của legacy BIOS

Trình tự boot của legacy BIOS trên x86

Các bước dưới đây đối chiếu với mã nguồn SeaBIOS, một bản cài đặt BIOS mã nguồn mở:

  1. Reset vector. Sau reset, CPU x86 ở real mode (chế độ 16-bit, địa chỉ hóa tối đa 1 MB theo dạng segment:offset) và bắt đầu thực thi tại địa chỉ ở 16 byte cuối của vùng ROM, tương ứng F000:FFF0. Trong SeaBIOS, nhãn reset_vector đặt tại ORG 0xfff0 chỉ có một lệnh nhảy tới code POST.
  2. POST (Power-On Self-Test). BIOS khởi tạo CPU, DRAM, chipset, liệt kê thiết bị PCI, dựng bảng vector ngắt (IVT, Interrupt Vector Table) ở đầu bộ nhớ và các vùng dữ liệu BIOS.
  3. Option ROM. Card mở rộng (VGA, RAID, card mạng) mang firmware riêng gọi là option ROM. BIOS chép các ROM này vào vùng bắt đầu từ 0xC0000, kiểm tra chữ ký 0xAA55 ở đầu ROM, rồi gọi code khởi tạo của chúng. Đây là cách card mạng cung cấp khả năng boot PXE và card RAID cung cấp disk ảo cho BIOS.
  4. INT 19h, nạp hệ điều hành. BIOS duyệt danh sách thiết bị theo boot order. Với disk, nó dùng INT 13h đọc sector 0 (512 byte) vào địa chỉ 0000:7C00, kiểm tra hai byte cuối có giá trị 0xAA55 (boot signature), rồi nhảy tới 0000:7C00. Nếu chữ ký sai, BIOS thử thiết bị tiếp theo.
  5. Bootloader. Code trong MBR chỉ có 440 byte, đủ để nạp stage tiếp theo của bootloader, ví dụ core.img của GRUB (xem GRUB: BIOS (legacy)). Bootloader vẫn chạy ở real mode và đọc disk qua INT 13h.
  6. Kernel. Bootloader nạp kernel Linux theo boot protocol x86. Phần setup code real mode của kernel gọi INT 15h (hàm E820) để lấy bản đồ bộ nhớ, INT 13h để lấy thông tin disk (EDD) và INT 10h để chọn chế độ màn hình, sau đó chuyển sang protected mode hoặc long mode và không gọi BIOS nữa.

Toàn bộ chuỗi trên không có bước kiểm tra chữ ký: BIOS chạy bất kỳ code nào nằm ở sector 0 có chữ ký 0xAA55. Đây là lý do legacy BIOS không có Secure Boot theo nghĩa của UEFI.

Dịch vụ BIOS

Legacy BIOS cung cấp dịch vụ cho bootloader và hệ điều hành qua ngắt phần mềm: code đặt số hàm vào thanh ghi AH (hoặc AX), gọi lệnh INT n, và nhận kết quả qua thanh ghi và cờ carry. Các dịch vụ này chỉ dùng được ở real mode.

Ngắt Chức năng Ví dụ sử dụng
INT 10h Màn hình: chọn chế độ hiển thị, in ký tự, VESA BIOS Extensions (VBE) Bootloader in menu, kernel chọn chế độ vga=
INT 13h Disk: đọc ghi sector theo CHS, bản mở rộng đọc theo LBA, Enhanced Disk Drive (EDD) BIOS đọc MBR, GRUB đọc core.img và filesystem
INT 15h Dịch vụ hệ thống, đặc biệt hàm E820 trả về bản đồ bộ nhớ Kernel Linux xây bảng e820 (in trong dmesg)
INT 16h Bàn phím Bootloader nhận phím chọn menu
INT 19h Nạp hệ điều hành từ thiết bị boot Bước cuối của POST
INT 1Ah Đồng hồ thời gian thực, PCI BIOS Đọc giờ, dò thiết bị PCI ở real mode

Trên Linux, các lời gọi này nằm trong arch/x86/boot/ (memory.c cho E820, edd.c cho INT 13h, video-bios.c cho INT 10h). Khi kernel được nạp bằng UEFI qua EFI stub, phần setup code real mode này không chạy và thông tin tương ứng được lấy từ firmware UEFI.

MBR và giới hạn

MBR (Master Boot Record) là sector đầu tiên của disk khi phân vùng theo kiểu DOS. Bố cục theo struct mbr_s trong SeaBIOS:

Offset Kích thước Nội dung
0x000 440 byte Code khởi động (stage 1 của bootloader)
0x1B8 4 byte Disk signature, Linux hiển thị dưới dạng PARTUUID=xxxxxxxx-NN
0x1BC 2 byte Thường bằng 0
0x1BE 4 × 16 byte Bảng phân vùng: trạng thái active, type, địa chỉ CHS, LBA bắt đầu (32-bit), số sector (32-bit)
0x1FE 2 byte Boot signature 0xAA55 (byte 55 AA trên disk)

Bố cục này dẫn tới các giới hạn đã khiến MBR được thay bằng GPT:

  • Bảng chỉ có 4 phân vùng chính. Muốn nhiều hơn phải dùng phân vùng extended chứa các phân vùng logical.
  • LBA và số sector là số 32-bit, nên với sector 512 byte, phân vùng chỉ địa chỉ hóa được tối đa 2^32 × 512 byte = 2 TiB.
  • Code khởi động chỉ có 440 byte, nên bootloader phải tách nhiều stage và cần chỗ ngoài filesystem để chứa stage 2 (khoảng trống sau MBR, hoặc BIOS boot partition khi dùng GPT).

GRUB vẫn boot được disk GPT trên legacy BIOS nhờ BIOS boot partition (type EF02). Ngược lại, firmware UEFI đọc GPT và ESP trực tiếp, không cần code trong MBR.

Lưu cấu hình: CMOS và RTC

Cấu hình của legacy BIOS (boot order, ngày giờ, bật tắt thiết bị) được lưu trong một vùng RAM nhỏ gắn với chip đồng hồ thời gian thực (RTC), thường gọi là CMOS RAM. Vùng này được nuôi bằng pin trên mainboard nên giữ được dữ liệu khi rút nguồn. Phần mềm truy cập qua hai cổng I/O: ghi chỉ số vào 0x70, đọc ghi dữ liệu ở 0x71 (định nghĩa PORT_CMOS_INDEX và PORT_CMOS_DATA trong SeaBIOS). Thao tác "clear CMOS" bằng jumper hoặc tháo pin đưa cấu hình về mặc định.

Trên Linux, RTC này được driver rtc-cmos quản lý và xuất ra /dev/rtc0. Firmware UEFI thì lưu cấu hình và biến boot trong flash dưới dạng biến UEFI, không phụ thuộc pin; xem EDK2: Biến UEFI.

BIOS và UEFI

Legacy BIOS UEFI
Chế độ CPU khi chạy firmware và bootloader Real mode 16-bit, 1 MB đầu bộ nhớ 32-bit hoặc 64-bit, bộ nhớ phẳng
Giao diện cho bootloader Ngắt phần mềm (INT 10h, INT 13h...) Boot services, protocol, có đặc tả đầy đủ
Bảng phân vùng MBR (GPT qua BIOS boot partition) GPT, ESP định dạng FAT
Định dạng bootloader Code thô trong MBR và các sector sau File PE/COFF .efi trên ESP
Chọn thiết bị boot Boot order trong CMOS, chỉ theo thiết bị Biến BootOrder/Boot####, trỏ tới file cụ thể
Driver Option ROM 16-bit Driver UEFI, chạy được trên nhiều kiến trúc
Kiểm tra chữ ký Không có Secure Boot
Dịch vụ cho hệ điều hành sau khi boot Không (Linux không gọi BIOS sau setup code) Runtime services: biến, đồng hồ, reset, capsule update
Kiến trúc Chỉ x86 x86, ARM64, RISC-V, LoongArch

CSM (Compatibility Support Module)

CSM là module trong firmware UEFI cung cấp lại giao diện legacy BIOS (ngắt, MBR boot, option ROM 16-bit) để chạy hệ điều hành và card mở rộng đời cũ. Khi bật CSM, firmware có thể boot theo cả hai kiểu và trong menu thường hiển thị hai mục cho cùng một disk, ví dụ "UEFI: Samsung SSD" và "Samsung SSD". SeaBIOS có thể build thành CSM (tùy chọn Kconfig CONFIG_CSM, "Build as Compatibility Support Module for EFI BIOS").

Secure Boot chỉ kiểm tra được ảnh .efi. Code boot qua CSM nằm ngoài chain of trust, vì vậy khi dùng Secure Boot cần tắt CSM và boot hoàn toàn theo kiểu UEFI.

Lộ trình loại bỏ CSM chưa kiểm chứng

Theo hiểu biết của tác giả, Intel đã công bố kế hoạch bỏ CSM khỏi các nền tảng client và server mới từ khoảng năm 2020, và UEFI Forum phân loại firmware thành các lớp (class) theo mức hỗ trợ legacy. Thông tin này chưa được đối chiếu với nguồn gốc, cần bổ sung nguồn trước khi coi là chắc chắn.

Firmware BIOS mã nguồn mở

Dự án Vai trò
SeaBIOS Bản cài đặt legacy BIOS cho x86, build bằng công cụ GNU và Kconfig. QEMU dùng file bios.bin (SeaBIOS) làm firmware mặc định cho máy x86 khi không chỉ định -bios hoặc pflash. Cũng dùng được làm payload của coreboot hoặc làm CSM.
coreboot Chỉ khởi tạo phần cứng (DRAM, chipset), sau đó chuyển cho một payload. Các payload có sẵn trong payloads/external/ gồm SeaBIOS (giao diện legacy BIOS), edk2 (giao diện UEFI), GRUB2, U-Boot, LinuxBoot, iPXE.

Mô hình của coreboot cho thấy rõ hai việc mà từ "BIOS" thường gộp lại: khởi tạo phần cứng, và cung cấp giao diện boot cho hệ điều hành. Với coreboot, việc thứ nhất do coreboot làm, việc thứ hai do payload đảm nhận, và có thể chọn payload legacy (SeaBIOS) hoặc UEFI (edk2).

Để thử legacy BIOS trên QEMU, chỉ cần không truyền firmware nào:

qemu-system-x86_64 -m 1G -nographic -drive format=raw,file=disk.img
# Firmware mặc định là SeaBIOS; log hiện "SeaBIOS (version ...)" và "Booting from Hard Disk..."

Kiểm tra trên Linux

# Hệ thống đang boot theo kiểu UEFI nếu thư mục này tồn tại
ls /sys/firmware/efi && echo "UEFI" || echo "Legacy BIOS (hoặc CSM)"

# Thông tin firmware từ bảng SMBIOS (áp dụng cho cả BIOS và UEFI)
cat /sys/class/dmi/id/bios_vendor /sys/class/dmi/id/bios_version /sys/class/dmi/id/bios_date
sudo dmidecode -t bios

# Bản đồ bộ nhớ firmware cung cấp cho kernel
sudo dmesg | grep -i e820

# Kiểu bảng phân vùng: "dos" là MBR, "gpt" là GPT
sudo fdisk -l /dev/sda | grep -i 'disklabel type'

/sys/class/dmi/id/bios_* do driver dmi-id của kernel tạo từ bảng SMBIOS. Mục này tồn tại trên cả máy UEFI, nên tên bios_version không có nghĩa là máy đang chạy legacy BIOS. Cách xác định chế độ boot đáng tin là kiểm tra /sys/firmware/efi.

Liên quan

Tài liệu tham khảo

  1. SeaBIOS source - github.com (src/romlayout.S: reset vector; src/boot.c: đọc MBR vào 0x7C00; src/std/disk.h: struct mbr_s; src/optionroms.c; src/hw/rtc.h; src/Kconfig: tùy chọn CSM)
  2. The Linux/x86 Boot Protocol - docs.kernel.org (mã nguồn tại Documentation/arch/x86/boot.rst)
  3. Linux arch/x86/boot/ - github.com (memory.c, edd.c, video-bios.c)
  4. Linux drivers/firmware/dmi-id.c - github.com
  5. QEMU pc-bios/README và hw/i386/pc_sysfw.c - github.com (SeaBIOS là bios.bin mặc định)
  6. coreboot payloads/external - github.com
  7. GNU GRUB Manual: BIOS installation - gnu.org