2010-01-10 35 views
5

Tôi có một số câu hỏi cơ bản về quá trình khởi động của máy tính và phần mà bộ nạp khởi động gọi hệ điều hành.Câu hỏi khởi động hệ điều hành cơ bản

Vì vậy, tôi biết rằng BIOS sao chép 512 byte đầu tiên từ ổ đĩa khởi động vào bộ nhớ và thực thi mã - vì vậy đó là khối khởi động.

  • Nhưng bộ khởi động nhỏ này khởi động được các lệnh từ hệ điều hành như thế nào?
  • Trình tải khởi động có tiếp tục chạy và vẫn hoạt động như một "bộ phát" giữa phần mềm và phần cứng không? Hoặc là điều khiển hoàn toàn được cung cấp cho hệ điều hành?
  • Tại sao tất cả bộ nạp khởi động được ghi bằng trình biên dịch?
  • Và tại sao bạn phải quay trở lại từ C++ đến C khi viết hệ điều hành?

Trân trọng, lạt ma

+6

Quay lại? ** Quay lại?! ** C++ không phải là cải tiến trên C, nó là * ngôn ngữ khác * –

+0

@StephenCanon Đồng ý. Mặc dù tôi đoán cho nó cùng một lá thư và tăng nó hai lần đã không thực sự giúp đỡ. – uSeRnAmEhAhAhAhAhA

Trả lời

12

1) bootloader thường chứa một số hướng dẫn đơn giản để tải dữ liệu nhưng nhiều hơn từ đĩa và để thực hiện nó.

2) Không,

3) Để giảm thiểu không gian chúng chiếm.

4) Bạn không.

+4

+1 cho "bạn không". – avakar

+1

+1 cho "bạn không" Hệ điều hành đã được viết bằng Lisp và Prolog - C++ sẽ rất dễ dàng! –

+0

Tất nhiên, về lâu dài, ngay cả C hoặc hướng dẫn của máy không đủ .. nó nén xuống các electron :) –

2

Nhưng bộ khởi động nhỏ này khởi động được các lệnh từ hệ điều hành như thế nào?

Vì bạn không thể làm được gì nhiều trong 512 byte mã (mặc dù, trên thực tế, một bộ nạp khởi động không phải là Nghiêm giới hạn ở 512 byte), một bootloader sẽ thường không nhiều hơn so với tải một khối lớn mã từ đĩa vào RAM và sau đó thực hiện nó.

Trình khởi động tiếp tục chạy và vẫn hoạt động như một "bộ phát" giữa phần mềm và phần cứng? Hoặc là điều khiển hoàn toàn được cung cấp cho hệ điều hành?

Tôi nghĩ rằng một khi mã bootloader đã làm công việc của mình, và nhảy vào mã bổ sung mà nó đã được nạp vào bộ nhớ, nó có thể sau đó được ghi đè, vì nó không còn cần thiết.

Tại sao tất cả bộ nạp khởi động được ghi bằng bộ lắp ráp?

Tôi cho rằng đây là chủ yếu vì một lý do: Nếu bạn viết một bootloader bằng một ngôn ngữ cấp cao, các mã được sản xuất sẽ hoàn toàn có thể dựa vào một số loại thư viện runtime, chứa các chức năng cần thiết. Tuy nhiên, những người này thường không cần thiết cho một bộ nạp khởi động, và do đó sẽ làm tăng kích thước mã của nó.

Và tại sao bạn phải quay trở lại từ C++ thành C khi viết hệ điều hành?

Bạn không nhất thiết phải làm như vậy. Nó chỉ là mã C gần máy hơn C++. Với C++ bạn không thể lúc nào cũng đoán được mã nào sẽ được tạo ra và liệu nó có hiệu quả như bạn muốn hay không.

Chỉnh sửa: Tôi cũng đã nghe lý lẽ rằng một số nhà phát triển hệ điều hành tuân thủ ngôn ngữ C vì có ít sự lựa chọn hơn trong các mô hình và kiểu lập trình khác nhau. trong C++. Do đó nó dễ dàng hơn để làm việc cho một nhóm với cơ sở mã thông thường, bởi vì mọi người sẽ viết nhiều mã "tương tự" hơn. (Vì bản thân tôi không tham gia vào bất kỳ sự phát triển mã nguồn mở hoặc hệ điều hành nào, tôi không thể đánh giá kinh nghiệm dù đây là một tuyên bố hợp lệ hay không.)

+1

Điều đáng buồn là các lập trình viên C là khủng khiếp tại "đoán" những gì t máy mã chương trình C của họ sản xuất. –

+0

Những ngày này (với các trình biên dịch tối ưu hóa rất nhiều) đó có thể là sự thật. Tuy nhiên tôi muốn nói rằng nó dễ dàng hơn để đoán ngôn ngữ lắp ráp từ mã C hơn từ mã C + +, vì không có "phức tạp" những thứ như OOP (vtables vv) hoặc STL. – stakx

+0

Nếu bạn không sử dụng các chức năng ảo, thì cũng không có những thứ như vậy trong C++. T –

1

Để trả lời câu hỏi cuối cùng của bạn: Hạt nhân không cần được viết bằng C. Nhưng nó làm cho chúng dễ dàng hơn nhiều khi nói đến việc cố gắng cấp phát bộ nhớ.

C++ có rất nhiều trường hợp khác nhau, nơi bạn có thể nhận được bộ nhớ ngầm được phân bổ cho các biến tạm thời, vv, không phải lúc nào cũng hiển nhiên khi kiểm tra mã. Điều này làm cho việc viết kernel trở nên khó khăn hơn, vì bạn phải tránh phân bổ bộ nhớ trong một số ngữ cảnh.

Tuy nhiên, nó không loại trừ hoàn toàn việc viết hạt nhân trong C++. Có nhiều cách để giải quyết vấn đề này.

+3

C và C++ có chính xác cùng một mô hình để phân bổ các biến. Mọi thứ được tạo tự động hoặc tự động hoặc tĩnh. –

+0

Neil: Tôi nghĩ anh ta đang nói về thực tế là nếu bạn tạo một đối tượng trên stack, ví dụ, constructor được gọi là automaticall (tôi nghĩ?), Có thể phân bổ bất cứ thứ gì bên trong nó. – Pod

+1

Có, và ngay cả khi bạn không phân bổ rõ ràng nó trên ngăn xếp; đôi khi C++ sao chép các đối tượng khi bạn không mong đợi nó. – MarkR

0

Trình tải khởi động tải hệ điều hành từ đĩa.

Đó là lý do tại sao nó được gọi là bộ nạp khởi động - nó tự nâng lên trong dây nịt bằng cách tải hệ điều hành đĩa từ đĩa trước khi có bất kỳ hệ điều hành đĩa nào để tải bất cứ thứ gì từ đĩa.

Khi hệ điều hành được tải, nó sẽ thay thế và bộ nạp được bỏ đi.

Trình tải khởi động thường được viết trong bộ lắp ráp vì đó là sự cân bằng giữa tổng kiểm soát và khả năng đọc. Nó có thể được viết bằng mã máy đơn giản (và những cái đầu tiên có thể là) nhưng khó đọc hơn. Nó có thể được viết bằng một ngôn ngữ cấp thấp như C, nhưng thật khó để đạt được các trình độ cấp thấp trong BIOS mà bạn cần thực hiện tải, và cũng khó giữ nó trong giới hạn kích thước vì mã được biên dịch có xu hướng có rất nhiều chi phí.

Hệ điều hành thường được viết bằng ngôn ngữ cấp thấp như C (với những thứ như trình tải khởi động và trình điều khiển phần cứng vẫn còn trong trình biên dịch). Bạn có thể viết nó trong C++ khi nó được xây dựng trên C, nhưng điều đó sẽ hầu như vô nghĩa vì bạn sẽ không sử dụng phần lớn những gì C++ đã thêm vào. Định hướng đối tượng đơn giản là không hữu ích khi viết một hệ điều hành.

+0

Tại sao lại là downvote? Nếu bạn không giải thích những gì bạn nghĩ là sai, nó không thể cải thiện câu trả lời. – Guffa

6
  • Nhưng bộ khởi động nhỏ này khởi động được các lệnh từ hệ điều hành như thế nào?

Có, bộ tải khởi động nhỏ, nhưng BIOS không và nó thực hiện .. luôn luôn triển khai .. hệ thống DOS I/O "gọi". Hệ thống I/O này ban đầu chạy toàn bộ hệ điều hành I/O trở lại trong hệ điều hành DOS và những ngày đầu Windows. Bây giờ nó chỉ là một giao diện điều khiển chịu trách nhiệm tải hệ điều hành thực mà sau đó cung cấp tất cả các trình điều khiển riêng của mình. Đó là loại thư viện thiết bị-driver và bộ giả lập IBM-PC-gốc cho bộ nạp khởi động.

  • Trình tải khởi động có tiếp tục chạy và vẫn hoạt động như một "bộ phát" giữa phần mềm và phần cứng không? Hoặc là điều khiển hoàn toàn được cung cấp cho hệ điều hành?

Trình tải khởi động là bánh mì nướng khi hệ điều hành đang chạy. Tuy nhiên, đây là một câu hỏi hay, bởi vì trong khái niệm PC ban đầu, BIOS đã thực hiện I/O cho hệ điều hành cũng như bộ nạp khởi động, và do đó một phần của hệ thống đã tồn tại khi tải hệ điều hành.

  • Tại sao tất cả bộ nạp khởi động được ghi bằng trình biên dịch?

Một số lý do: họ cần phải nhỏ, họ đã cố định địa chỉ hạn chế bố trí, họ phải làm int cuộc gọi $ x kiểu BIOS, và cho kích thước của chúng và thực tế là một số của nó phải nằm trong lắp ráp, không có nhiều để đạt được bằng cách lấy 128 hoặc hơn byte và nói "ok, phần này bạn có thể viết trong C, cố gắng không để viết nhiều hơn 10 hoặc như vậy báo cáo".

  • Và tại sao bạn phải quay trở lại từ C++ đến C khi viết hệ điều hành?

C++ là tốt ngay hôm nay; trở lại khi các hạt nhân lớn ngày nay bắt đầu mọi thứ khác nhau.

0

Có một điểm quan trọng còn thiếu trong tất cả các câu trả lời về việc tại sao nó được viết bằng lắp ráp: vì:

a. MMU vẫn chưa được thiết lập,

b. không có quá trình tải hiện có đang chạy để tải các tệp nhị phân đã biên soạn của bạn - vì vùng bộ nhớ không đồng nhất - một số phần được hardwired cho các mục đích DMA/BIO, v.v ..., vì vậy rất nhiều công việc remapping là cần thiết. Vì vậy, khi bạn viết nó trong assembly, bạn phải xác định rõ ràng tất cả các vị trí bộ nhớ của bạn - dữ liệu nằm ở đâu, vị trí thực thi được đặt ở đâu, và đảm bảo rằng những ràng buộc này không xung đột.

Nếu bạn viết bằng C, gcc sẽ biên dịch nó thành một số định dạng chuẩn ABI và có trình tải trước (có thể chỉ là thư viện) để tải nhị phân vào bộ nhớ. Vì thường bộ nhớ được sử dụng trong nhị phân là nhiều hơn bộ nhớ phyical, và một số bộ nhớ nhất định được dành riêng cho việc sử dụng phần cứng - do đó nền tảng/phần cứng cụ thể - MMU rất quan trọng để được thiết lập trước khi tải các tệp nhị phân này.

ELF tải chỉ là một khía cạnh của sự phức tạp:

http://wiki.osdev.org/ELF#Loading_ELF_Binaries

Nhưng có làm tồn tại phân phối như uClinux mà bỏ sự cần thiết của MMU được thiết lập:

http://www.uclinux.org/

Ai đó phải dạy tôi nhiều hơn về điều đó .....

Các vấn đề liên quan