Rất nhiều người quan tâm đến cách máy tính khởi động. Đây là nơi phép màu bắt đầu và tiếp tục miễn là thiết bị được bật. Trong bài viết này, chúng tôi sẽ giới thiệu tổng quan về quy trình khởi động , bao gồm các giai đoạn khác nhau, các thành phần chính liên quan và những thách thức gặp phải trong quá trình này.
Mặc dù trọng tâm chính của chúng tôi sẽ là kiến trúc x86 (được sử dụng rộng rãi nhất), các kiến trúc khác sẽ có nhiều điểm tương đồng trong quá trình khởi động của chúng. Tôi hy vọng bài viết này sẽ là một nguồn tài nguyên quý giá cho bất cứ ai muốn đào sâu kiến thức của họ trong lĩnh vực này. Chúng ta đi đây!
Mạch tích hợp (chip) nằm trên bo mạch chủ và lưu trữ mã phần sụn chịu trách nhiệm khởi động máy tính được gọi là BOOT ROM . Tên này không được chuẩn hóa, vì vậy các nhà phát triển khác thường gọi nó là FLASH ROM , BIOS FLASH , BOOT FLASH , SPI FLASH , v.v. (những tên này được đặt cho họ vì công nghệ, giao diện và tên mục đích). Đừng lo lắng, những thuật ngữ này có thể hoán đổi cho nhau. Mã chương trình cơ sở trong ROM BOOT được thực thi đầu tiên khi bật nguồn máy tính. Nó thực hiện các bài kiểm tra cơ bản, khởi tạo phần cứng, sau đó tải bộ tải hệ điều hành từ một thiết bị có khả năng khởi động, chẳng hạn như ổ cứng hoặc ổ USB, vào bộ nhớ. Con chip này được làm từ bộ nhớ không bay hơi (NVM) .
Bộ nhớ ổn định là một loại bộ nhớ máy tính giữ lại nội dung của nó ngay cả khi tắt nguồn . Nó làm cho loại bộ nhớ này trở nên lý tưởng để lưu trữ dữ liệu quan trọng cần được giữ lại ngay cả khi tắt nguồn máy tính. Hơn nữa, cuộc thảo luận sẽ chỉ tập trung vào bộ nhớ chứa mã chương trình cơ sở. Chúng tôi sẽ không nói về lưu trữ như Ổ đĩa cứng (HDD), Ổ đĩa thể rắn (SSD), đĩa mềm, v.v.
Về cơ bản, chúng ta có thể phân loại bộ nhớ này thành các nhóm sau.
Có thể lập trình xóa bằng điện (EEPROM): Có thể lập trình lại nhiều lần bằng tín hiệu điện .
Bộ nhớ NOR Flash : Được sắp xếp theo kiến trúc theo khối nơi dữ liệu bị xóa ở cấp độ khối và có thể được đọc hoặc ghi ở cấp độ byte . Bộ nhớ NOR có thể truy cập trực tiếp bằng giao diện tiêu chuẩn như song song byte, I2C hoặc SPI.
Trong ngành, có một quy ước dành thuật ngữ EEPROM cho bộ nhớ có thể xóa theo byte so với bộ nhớ flash có thể xóa theo khối.
Bộ nhớ có thể lập trình đi kèm với một quy tắc - xóa trước khi ghi . Trong bộ nhớ như vậy, việc ghi dữ liệu mới phức tạp hơn vì dữ liệu được lưu trữ dưới dạng điện tích trên một cổng nổi (lý do phần lớn nằm ở tính chất vật lý của các ô nhớ). Lượng điện tích trên cổng xác định ô lưu trữ "0" hay "1".
Khi bạn xóa chip bộ nhớ flash, bạn đặt tất cả các bit dữ liệu được lưu trữ trên đó về trạng thái đã biết (mặc định), thường là logic "1". Điều này cho phép bạn bắt đầu với một phương tiện rõ ràng, có thể nói như vậy và lập trình dữ liệu mới trên chip mà không có bất kỳ tàn dư nào của dữ liệu cũ vẫn được lưu trữ trên đó. Khi dữ liệu mới được ghi vào chip, trạng thái của các bit riêng lẻ được thay đổi từ "1" thành "0" để biểu thị dữ liệu mới.
Nếu bạn chỉ ghi dữ liệu mới vào chip mà không xóa nó trước, dữ liệu mới sẽ được kết hợp với dữ liệu cũ, dẫn đến kết quả không thể đoán trước. Ví dụ: hãy xem xét chip bộ nhớ flash có bộ nhớ 8 bit lưu trữ giá trị "0110 0010". Nếu bạn ghi dữ liệu mới "1100 1001" vào chip mà không xóa nó trước, trạng thái kết quả của chip sẽ là "0100 0000", đây có thể không phải là điều bạn dự định.
Sự nhầm lẫn chính liên quan đến từ ROM viết tắt của Read Only Memory . Thuật ngữ "Bộ nhớ chỉ đọc" đã từng được sử dụng để chỉ bộ nhớ vĩnh viễn và người dùng không thể thay đổi. Tuy nhiên, khi công nghệ ngày càng phát triển, định nghĩa về ROM đã thay đổi và hiện nay nó thường được dùng để chỉ bộ nhớ được lập trình sẵn tại nhà máy và người dùng cuối không thể dễ dàng thay đổi. Nhưng nếu người dùng có kỹ năng mong muốn và thiết bị chuyên dụng (ví dụ: lập trình viên), người đó có thể lập trình lại chip. Tên ROM vẫn còn, mặc dù định nghĩa đã thay đổi, như một tham chiếu lịch sử đến mục đích ban đầu của bộ nhớ.
Bằng cách áp dụng bảo vệ ghi, một số loại ROM có thể lập trình lại có thể tạm thời trở thành bộ nhớ chỉ đọc.
Đây KHÔNG phải là TẤT CẢ các loại bộ nhớ cố định hiện có, mà là hầu hết các loại bộ nhớ phổ biến mà bạn có thể tình cờ nghe thấy. Ngày nay, trên hầu hết các bo mạch chủ, những con chip này được tạo ra bằng cách sử dụng công nghệ NOR Flash .
Execute in Place (XIP) là phương pháp cho phép bộ xử lý thực thi mã trực tiếp từ bộ nhớ flash mà không cần sao chép mã đó vào bộ nhớ dễ bay hơi (chẳng hạn như RAM ) trước. Điều này đạt được bằng cách ánh xạ bộ nhớ flash vào không gian địa chỉ của bộ xử lý, để có thể thực hiện mã trực tiếp từ flash. Vì vậy, hệ thống có thể bắt đầu thực thi mã ngay khi có thể mà không cần phải đợi RAM được khởi tạo trước.
Đợi đã... CPU có thể giao tiếp với ROM BOOT thông qua giao thức SPI/Parallel/etc không? Tất nhiên là không, nó chỉ tìm nạp hướng dẫn từ bộ nhớ hệ thống, các yêu cầu đến vùng bộ nhớ này được chuyển hướng đến Giao diện phương tiện trực tiếp của Intel (DMI ) hoặc AMD Infinity Fabric (IF) / Giao diện phương tiện hợp nhất (UMI) (tiền thân). Đó là liên kết giữa CPU và chipset trên bo mạch chủ. Tại thời điểm này, việc giải mã địa chỉ được thực hiện thông qua bộ giải mã nằm trong chipset và dữ liệu từ chip được trả về bộ xử lý.
Khi chip được làm từ bộ nhớ flash NOR, hỗ trợ đọc truy cập ngẫu nhiên, nhưng không ghi truy cập ngẫu nhiên, đã xảy ra một vấn đề. Khi bộ nhớ có thể ghi không khả dụng, tất cả các tính toán phải được thực hiện trong các thanh ghi của bộ xử lý. Tại thời điểm này, mã chỉ có thể được viết bằng hợp ngữ và nó có xu hướng thiết lập môi trường cho ngôn ngữ cấp cao (thường là ngôn ngữ C ). Lý do cho điều này là việc khởi tạo bộ nhớ đã trở nên phức tạp đến mức khó có thể viết hoàn toàn bằng hợp ngữ. Vì những ngôn ngữ như vậy yêu cầu ít nhất một đống và ngăn xếp, nên chúng ta cần bộ nhớ có thể ghi. Một số bộ xử lý có SRAM được nhúng trong chính chip, nhưng một cách tiếp cận hiện đại hơn là sử dụng bộ nhớ Cache tích hợp dưới dạng RAM (CAR) .
Bộ đệm CPU là bộ nhớ tốc độ cao lưu trữ một bản sao của dữ liệu và hướng dẫn được sử dụng thường xuyên từ bộ nhớ chính. Bộ đệm được đặt gần bộ xử lý hơn và được tổ chức thành nhiều cấp độ (L1, L2, L3, ...), với mỗi cấp độ lớn hơn và chậm hơn cấp độ trước đó.
Nếu dữ liệu nằm trong bộ đệm, CPU có thể truy xuất dữ liệu được yêu cầu từ bộ đệm (nó được gọi là lần truy cập bộ đệm ). Khi bộ nhớ cache của CPU không thể tìm thấy dữ liệu cần thiết, nó sẽ dẫn đến lỗi bộ nhớ cache . Điều này có thể xảy ra do dữ liệu chưa bao giờ được lưu trữ trong bộ nhớ cache hoặc do dữ liệu đã được lưu trữ trước đó nhưng đã bị xóa khỏi bộ nhớ cache. Dù sao, bộ xử lý phải đi đến bộ nhớ chính để truy cập dữ liệu và sao chép nó vào bộ đệm.
Xoá bộ nhớ cache là quá trình xóa dữ liệu khỏi bộ nhớ cache để giải phóng dung lượng cho dữ liệu mới. Việc trục xuất dữ liệu có thể được bắt đầu bởi hệ thống bộ nhớ đệm (thường là khi bộ nhớ đệm đầy và dữ liệu mới cần được lưu trữ hoặc khi chính sách về thời gian tồn tại của dữ liệu đã hết hạn) hoặc theo yêu cầu rõ ràng.
Tuy nhiên, nếu chúng ta muốn sử dụng Cache CPU làm RAM , chúng ta cần thiết lập cache để hoạt động ở chế độ Non-Eviction Mode hay còn gọi là No-Fill Mode . Kỹ thuật này ngăn chặn việc trục xuất do lỗi bộ đệm . Thay vào đó, bộ nhớ đệm được coi như một SRAM thông thường và tất cả các truy cập (đọc/ghi) sẽ tác động vào bộ đệm chứ không tác động vào bộ nhớ chính. Chế độ này có thể được kích hoạt bằng cách sử dụng hướng dẫn CPU dành riêng cho nhà cung cấp.
Trên thực tế, ROM BOOT chứa một số loại phần sụn. Khi một loạt phần sụn được lưu trữ trong ROM BOOT, nó cần được sắp xếp theo cách nào đó để phân biệt giữa chúng. Hãy tìm hiểu làm thế nào nó được thực hiện.
Ban đầu, chipset thực hiện ánh xạ trực tiếp toàn bộ nội dung ROM BOOT vào bộ nhớ (từ 4GB đến 4GB - 16MB). Thông thường, nếu ROM BOOT nhỏ hơn 16 MB, nội dung sẽ được ánh xạ lặp lại. CPU và phần sụn có thể đọc/ghi vào flash mà không có bất kỳ hạn chế nào.
Chế độ Non-Descriptor không còn được hỗ trợ ở các chipset mới.
Cuối cùng, trong ICH8, Intel giới thiệu một bố cục đặc biệt cho BOOT ROM. Đèn flash được chia thành các vùng sau:
Bộ mô tả Flash (FD) - cấu trúc dữ liệu này phải được đặt ở đầu thiết bị với độ lệch 0x10
. Nó được tạo thành từ mười một phần như thể hiện trong hình bên dưới:
Bản đồ mô tả có các con trỏ tới các vùng khác và kích thước của từng vùng.
Phần Thành phần có thông tin về (các) đèn flash trong hệ thống (số lượng thành phần, mật độ của từng thành phần, hướng dẫn không hợp lệ, v.v.).
Phần Master xác định quyền đọc/ghi cho các vùng. Về phần đọc/ghi, quyền phải được đặt thành Chỉ đọc, thông tin được lưu trữ trong vùng này chỉ có thể được ghi trong quá trình sản xuất.
Bộ mô tả Flash và Intel ME là những vùng bắt buộc duy nhất.
FIT là một cấu trúc dữ liệu bên trong vùng BIOS và chứa nhiều mục khác nhau mô tả cấu hình nền tảng. Mỗi mục trong bảng có kích thước 16 byte. Cái đầu tiên được gọi là tiêu đề FIT , cái còn lại được gọi là mục FIT . Nó được định vị bởi con trỏ FIT tại địa chỉ vật lý 0xFFFFFFC0
(4GB - 0x40).
Các thành phần này phải được xử lý trước khi thực hiện lệnh CPU đầu tiên từ vectơ đặt lại . Các mục bao gồm cập nhật vi mã CPU, ACM khởi động, chính sách Khởi động nền tảng/TPM/BIOS/TXT và các nội dung khác. Nhưng ít nhất FIT phải bao gồm các mục Cập nhật tiêu đề FIT và vi mã . Vì vậy, cách sử dụng phổ biến của FIT là cập nhật vi mã trước khi thực hiện véc tơ đặt lại .
Đây là bản đồ bộ nhớ trông như thế nào:
Thật không may, có ít thông tin hơn nhiều, tôi không thể tìm thấy bất kỳ tài liệu rò rỉ nào về chipset AMD có thông tin chi tiết về cách bố trí của chúng. Vì vậy, tôi không thể cho bạn biết tốt hơn tài liệu coreboot nói . Nó được viết dựa trên tài liệu AMD chỉ có sẵn theo NDA.
Trên thực tế, sẽ đủ để biết rằng tương tự AMD của Bộ mô tả Flash là Cấu trúc phần sụn nhúng và nó chứa các con trỏ tới Bảng thư mục PSP , Bảng thư mục BIOS và phần sụn khác.
Nếu bạn muốn xem chính xác cách bộ nhớ và CPU hiện đại được khởi tạo, thì tôi phải làm phiền bạn. Intel và AMD không vội phát hành Mã khởi tạo Silicon cho cộng đồng. Theo như thông tin như vậy không có sẵn công khai, họ cung cấp phân phối nhị phân mã khởi tạo silicon cần thiết. Đây được coi là một thư viện dành cho các nhà phát triển chương trình cơ sở và chứa mã nhị phân để khởi tạo bộ điều khiển bộ nhớ, chipset, CPU và các bộ phận khác của hệ thống.
Nhị phân đó có thể được chia thành 4 thành phần:
Đây là Kho lưu trữ các tệp nhị phân Intel FSP do Intel đăng mà bạn có thể tìm thấy trên GitHub của họ. Thông số kỹ thuật FSP v2.1 có thể được lấy từ trang web của Intel.
AGESA cho các sản phẩm sớm hơn Family 17h được gọi là v5 hoặc Arch2008 . Vào thời điểm đó, AGESA có mã nguồn mở và mã có sẵn trong kho lưu trữ coreboot (mã này không được dùng nữa sau bản phát hành 4.18). Thông số kỹ thuật cho Arch2008 có thể được tìm thấy trên trang web của AMD.
Với việc giới thiệu các sản phẩm Family 17h (vi kiến trúc Zen), AMD đã không công bố mã nguồn AGESA, chỉ có các giải pháp nhị phân dựng sẵn. Người kế nhiệm như vậy được gọi là AGESA v9 và hỗ trợ Family 17h trở lên.
Không có thông tin chi tiết có sẵn, chỉ có tin tức .
Một phần không thể thiếu của quy trình khởi động x86 hiện đại, nếu không có nó thì các lõi x86 sẽ không bao giờ được kích hoạt. Do đó không thể vô hiệu hóa chúng hoàn toàn . Các công nghệ này chịu trách nhiệm khởi tạo phần cứng, xác minh tính toàn vẹn của hệ thống, quản lý năng lượng và khởi chạy CPU. Phần sụn cho các hệ thống phụ này được tải và thực thi trước khi bộ xử lý chính bắt đầu thực thi phần sụn của chính nó. Mã trên các hệ thống như vậy chạy độc lập với lõi CPU của nền tảng.
Miễn là nhiều công ty phần cứng đã kết hợp nguyên tắc bảo mật thông qua che khuất , mã nguồn cũng như tài liệu cho các hệ thống con này đều không có sẵn. May mắn thay, chúng tôi biết nó ảnh hưởng như thế nào đến quá trình khởi động - xem Trình tự sức mạnh phần cứng .
Chúng tôi sẽ không đi vào chi tiết, bởi vì đã có nhiều bài báo trên Internet từ các nhà nghiên cứu trên toàn thế giới. Nhưng tôi sẽ chỉ cung cấp cho bạn một mô tả ngắn gọn về nó là gì.
Intel ME là một bộ vi xử lý i486/80486 riêng biệt được tích hợp vào chipset Intel (PCH) từ năm 2008. Nó có RAM riêng, ROM tích hợp, cầu nối bus tới tất cả các bus bên trong chipset (kết quả là nó có thể truy cập mạng). và thậm chí cả RAM chính trên CPU), v.v. Chạy một hệ điều hành tùy chỉnh dựa trên MINIX.
AMD PSP là lõi ARM dựa trên phần mở rộng Trustzone, phần mở rộng này được đưa vào khuôn CPU dưới dạng bộ đồng xử lý. Con chip này đã được tích hợp vào hầu hết các nền tảng AMD kể từ năm 2013. Chạy một hệ điều hành độc quyền và không có giấy tờ.
Quá trình này, còn được gọi là Trình tự bật nguồn hoặc Trình tự bật nguồn , cung cấp một số mức điện áp dẫn xuất và/hoặc đường ray cấp điện theo một thứ tự cụ thể cần thiết trên nền tảng. Nói một cách đơn giản hơn, nó cung cấp năng lượng cho một số thành phần nền tảng theo một thứ tự cụ thể. Quá trình này khác nhau tùy thuộc vào thiết kế hệ thống hoặc nền tảng, nhưng thông thường, PC tiêu chuẩn bao gồm các bước sau:
Các hệ thống dựa trên AMD (dành cho Gia đình 17h trở lên)
PSP thực thi trên -chip BOOT ROM.
PSP định vị Bảng phần sụn nhúng trong ROM BOOT ngoài chip và thực thi phần sụn PSP.
PSP phân tích Bảng thư mục PSP để tìm các giai đoạn ABL và thực thi chúng.
Các giai đoạn ABL khởi tạo bộ nhớ chính, định vị hình ảnh BIOS trong BOOT ROM và tải nó vào DRAM (giải nén nếu hình ảnh được nén).
Nền tảng này không có lý do gì để sử dụng CAR vì DRAM đã có sẵn và PSP tải hình ảnh chương trình cơ sở vào đó.
Sau khi bật nguồn CPU lần đầu tiên, nó sẽ hoạt động ở chế độ thực . Hầu hết các thanh ghi đều có các giá trị được xác định rõ , bao gồm Con trỏ chỉ dẫn (IP), Đoạn mã (CS) và Bộ nhớ đệm mô tả , đây là bản sao của từng bộ mô tả đoạn trong bộ xử lý để cho phép truy cập nhanh vào bộ nhớ đoạn.
Bộ mô tả phân đoạn là một mục trong Bảng mô tả toàn cầu (GDT) và chứa địa chỉ cơ sở, giới hạn phân đoạn và thông tin truy cập (phần này bị bỏ qua vì chế độ thực không có quyền kiểm soát truy cập như chế độ được bảo vệ). Thay vì truy cập GDT (được đặt trong bộ nhớ) cho mỗi lần truy cập bộ nhớ, thông tin được lưu trữ trong bộ đệm mô tả.
Tuy nhiên, GDT không tham gia vào chế độ thực, vì vậy bộ xử lý tạo các mục nhập bên trong. Thanh ghi bộ chọn CS, được sử dụng để truy cập bộ mô tả đoạn, được tải với 0xF000
. Địa chỉ cơ sở CS được khởi tạo thành 0xFFFF_0000
. IP được khởi tạo thành 0xFFF0
.
Do đó, bộ xử lý bắt đầu tìm nạp các lệnh từ bộ nhớ nằm ở địa chỉ vật lý 0xFFFF_FFF0
( 0xFFFF_0000
+ 0x0000_FFF0
). Lệnh đầu tiên được thực thi tại địa chỉ đó được gọi là véc tơ đặt lại .
LƯU Ý: Thủ thuật này cho phép bạn truy cập vào không gian địa chỉ cao, tuy nhiên, bạn không thể truy cập mã bên dưới địa chỉ 0xFFFF_0000
. Địa chỉ cơ sở CS vẫn ở giá trị ban đầu này cho đến khi thanh ghi bộ chọn CS được phần sụn tải. Nó có thể được thực hiện bằng cách thực hiện một cú nhảy xa .
Tại thời điểm này, quyết định tốt nhất là chuyển sang chế độ được bảo vệ với 4 GB địa chỉ. Nếu phần sụn không làm được điều đó, thì để chế độ thực hoạt động, chipset phải có khả năng đặt bí danh cho phạm vi bộ nhớ dưới 1 MB thành phạm vi tương đương chỉ dưới 4 GB. Một số chipset nhất định không có răng cưa này và có thể yêu cầu chuyển sang chế độ hoạt động khác trước khi thực hiện bước nhảy xa đầu tiên.
Tôi khuyên bạn nên xem video bên dưới về trình tự bật nguồn, video này giải thích quy trình sử dụng bo mạch chủ ASUS P9X79 làm ví dụ. Mặc dù thực tế là nó bằng tiếng Nga, nhưng bạn sẽ có thể hiểu mọi thứ nếu bật phụ đề tiếng Anh được tạo tự động.
Bài viết này đã cung cấp rất nhiều thông tin lý thuyết liên quan đến cách khởi động hoạt động. Tuy nhiên, để thực sự hiểu quy trình này, chúng ta cần xem xét kỹ hơn mã nguồn và kiến trúc của phần sụn hiện có.
Trong bài viết tiếp theo, chúng ta sẽ tìm hiểu sâu hơn về BIOS , UEFI và coreboot để xem xét chúng một cách chi tiết.