Runtime Services là gì?

Runtime Services là nhóm API UEFI còn hợp lệ sau ExitBootServices. Bao gồm variable, time, reset và virtual address mapping - truy cập qua gRT.

Cập nhật 5 phút đọc
BIOS Terms cover

Runtime Services là nhóm API của UEFI vẫn còn hợp lệ sau khi OS loader gọi ExitBootServices(). Khác với Boot Services bị tắt hoàn toàn, Runtime Services tiếp tục tồn tại để OS có thể gọi variable service, time service và reset system.

Toàn bộ Runtime Services được truy cập qua con trỏ gRT (EFI_RUNTIME_SERVICES *).

Runtime Services phải sống qua ranh giới firmware → OS. Vì vậy runtime code nhạy cảm hơn nhiều: memory phải có đúng attribute, pointer phải được remap, và mọi locking phải tương thích với môi trường OS.

Các Runtime Services chính

Mục Giá trị Ghi chú
GetVariable / SetVariable Đọc/ghi UEFI variable OS và firmware đều có thể dùng. Variable non-volatile lưu qua reboot.
GetNextVariableName Enumerate toàn bộ variable Dùng để liệt kê tất cả variable hiện có trong NVRAM.
GetTime / SetTime Đọc/ghi thời gian Liên quan RTC. OS dùng để sync time khi boot.
ResetSystem Reboot hoặc shutdown OS gọi khi shutdown/restart. Firmware thực thi reset platform.
SetVirtualAddressMap Remap địa chỉ runtime Nếu OS dùng virtual mapping cho runtime services, OS gọi sau ExitBootServices để báo địa chỉ virtual cho runtime code. Chỉ gọi một lần.
ConvertPointer Chuyển đổi pointer Runtime driver dùng để update pointer nội bộ sau SetVirtualAddressMap.

SetVirtualAddressMap và tại sao quan trọng

Sau ExitBootServices(), OS có thể thiết lập virtual mapping cho các vùng runtime memory. Khi đó, OS gọi SetVirtualAddressMap() để báo cho firmware biết địa chỉ virtual tương ứng với từng vùng runtime memory.

Theo UEFI model, nếu OS chuyển runtime services sang virtual addressing, SetVirtualAddressMap() chỉ được gọi một lần trong boot flow đó.

// OS loader gọi sau ExitBootServices() nếu cần virtual mapping
gRT->SetVirtualAddressMap(
       MemoryMapSize,
       DescriptorSize,
       DescriptorVersion,
       VirtualMemoryMap    // memory map với VirtualStart đã được fill
     );

Sau lời gọi này, runtime code phải dùng địa chỉ virtual cho các vùng runtime đã được map. Runtime driver có thể nhận notification qua event EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE để update pointer nội bộ:

// Runtime driver đăng ký handler để update pointer sau virtual remap
VOID EFIAPI
MyRuntimeAddressChangeEvent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  // ConvertPointer chuyển physical pointer sang virtual
  gRT->ConvertPointer(0, (VOID **)&mMyRuntimeBuffer);
  gRT->ConvertPointer(0, (VOID **)&mMyPrivateContext);
  gRT->ConvertPointer(0, (VOID **)&mMyRuntimeTable);
}

Runtime driver lifecycle

Runtime driver (DXE_RUNTIME_DRIVER) có lifecycle đặc biệt so với DXE driver thông thường:

Boot time:
  Entry point chạy → install protocol, allocate EfiRuntimeServicesData/Code
  Có thể đăng ký EVT_SIGNAL_EXIT_BOOT_SERVICES handler nếu cần cleanup Boot Services dependency
  Thường cần đăng ký EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE handler nếu driver giữ pointer cần convert

ExitBootServices():
  EVT_SIGNAL_EXIT_BOOT_SERVICES fire → cleanup dependency vào Boot Services
  gBS không còn hợp lệ sau đây

SetVirtualAddressMap():
  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE fire → update pointer nội bộ bằng ConvertPointer()

Runtime (OS running):
  OS gọi gRT->GetVariable(), gRT->SetVariable(), gRT->ResetSystem()...
  Runtime service implementation phục vụ các lời gọi này - không được dùng gBS

Variable Service - nơi hay gặp lỗi nhất

GetVariable / SetVariable là Runtime Services được dùng nhiều nhất và cũng là nơi hay xảy ra lỗi nhất trong thực tế:

// OS hoặc firmware gọi GetVariable
UINTN DataSize = sizeof(MyData);
Status = gRT->GetVariable(
                L"MyVariableName",
                &gMyVendorGuid,
                &Attributes,
                &DataSize,
                &MyData
                );

Các nguyên nhân phổ biến khiến variable service fail hoặc treo:

Mục Giá trị Ghi chú
Flash write protect SetVariable bị block SPI flash bị lock sau ExitBootServices. SMM variable driver cần được phép ghi.
SMM communication fail Variable qua SMM không response Trên nhiều PC/x86 firmware hiện đại, variable write path có thể đi qua SMM để bảo vệ flash/NVRAM. Nếu SMM communication hoặc SMM variable handler lỗi, call có thể fail hoặc hang.
NVRAM full SetVariable trả EFI_OUT_OF_RESOURCES Variable store đầy. Cần garbage collect hoặc xóa variable không cần.
Wrong VendorGuid GetVariable trả EFI_NOT_FOUND Name + VendorGuid mới xác định một variable. Sai một trong hai thì không tìm được.

Lỗi hay gặp khi debug Runtime Services

Code vô tình gọi gBS sau ExitBootServices() - đây là lỗi phổ biến nhất. Runtime driver phải thay thế mọi gBS->... bằng cách khác hoặc loại bỏ hẳn dependency vào Boot Services.

Pointer không được update sau SetVirtualAddressMap() - runtime driver giữ physical pointer nhưng OS đã chuyển sang virtual mode. Kết quả là crash hoặc data corruption trong OS, không phải trong firmware.

Runtime memory bị cấp sai type - dùng EfiBootServicesData cho runtime buffer sẽ bị OS reclaim sau ExitBootServices(). Phải dùng EfiRuntimeServicesData cho mọi buffer mà runtime code cần truy cập.

Checklist Runtime Services

Câu hỏi tự kiểm tra

  1. Runtime Services được truy cập qua pointer nào?
  2. Tại sao OS cần gọi SetVirtualAddressMap() sau ExitBootServices()?
  3. Runtime driver xử lý virtual address change bằng event nào?
  4. ConvertPointer() dùng để làm gì?
  5. Vì sao lỗi SMM hoặc flash lock có thể làm SetVariable() fail hoặc treo trên nhiều PC/x86 firmware?
  6. Nếu SetVariable() trả EFI_OUT_OF_RESOURCES, nguyên nhân có thể là gì?
  7. Vì sao runtime buffer phải dùng EfiRuntimeServicesData thay vì EfiBootServicesData?

Bài liên quan

Nguồn tham khảo public

Thấy nội dung này hữu ích?

Lưu lại hoặc chia sẻ cho người cũng đang học firmware, BIOS/UEFI và embedded systems.

Nội dung liên quan

Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.