Tạo hệ điều hành dựa trên nhân linux. Từ đầu

Về cơ bản ...

Hệ điều hành là loại thực thi đa nhiệm (thông thường) và quản lý việc phân bổ tài nguyên giữa các tác vụ này và nói chung. Bạn cần đảm bảo rằng các tác vụ không thể gây hại cho nhau và hoạt động trong các vùng bộ nhớ khác nhau và lần lượt hoạt động với các thiết bị, đó là ít nhất. Và bạn cũng cần cung cấp khả năng chuyển thông điệp từ tác vụ này sang tác vụ khác.

Ngoài ra, hệ điều hành, nếu có bộ nhớ dài hạn, phải cung cấp quyền truy cập vào nó: nghĩa là cung cấp tất cả các chức năng để làm việc với hệ thống tệp. Đó là mức tối thiểu.

Hầu như ở mọi nơi, mã khởi động đầu tiên phải được viết bằng trình hợp dịch - có rất nhiều quy tắc về vị trí của nó, nó sẽ trông như thế nào, nó phải làm gì và không được vượt quá kích thước.

Đối với PC, bạn cần viết bộ nạp khởi động trên ASM, bộ nạp khởi động này sẽ được gọi bởi BIOS và bộ nạp này phải, không vượt quá bốn trăm rưỡi byte, hãy làm gì đó và chạy hệ điều hành chính - chuyển quyền điều khiển sang mã chính, trong đó tương lai gần có thể được viết bằng C.

Đối với ARM, bạn cần tạo bảng ngắt trên ACM (đặt lại, các lỗi khác nhau, ngắt IRQ, FIQ, v.v.) và chuyển quyền điều khiển sang mã chính. Mặc dù, trong nhiều môi trường phát triển, mã như vậy có sẵn cho hầu hết mọi bộ điều khiển.

Đó là, nó là cần thiết cho điều này:

  1. Biết trình lắp ráp của nền tảng mục tiêu.
  2. Biết kiến ​​trúc bộ xử lý và tất cả các loại lệnh và đăng ký dịch vụ để cấu hình nó hoạt động ở chế độ mong muốn. Trong PC, đây là quá trình chuyển đổi sang chế độ được bảo vệ, ví dụ, hoặc sang chế độ 64-bit ... Trong ARM, đó là thiết lập xung nhịp của lõi và ngoại vi.
  3. Biết chính xác cách hệ điều hành sẽ chạy, vị trí và cách đẩy mã của bạn.
  4. Biết ngôn ngữ C - rất khó để viết mã lớn trong ASM nếu không có kinh nghiệm, việc duy trì nó sẽ càng khó hơn. Do đó, cần phải viết kernel trong C.
  5. Biết nguyên lý hoạt động của HĐH. Chà, có rất nhiều sách bằng tiếng Nga về chủ đề này, mặc dù tôi không biết liệu chúng có hay không.
  6. Có rất nhiều kiên nhẫn và kiên trì. Các lỗi sẽ có và chúng sẽ cần được tìm kiếm và sửa chữa. Và bạn cũng sẽ phải đọc rất nhiều.
  7. Có rất nhiều thời gian.

Hơn nữa. Giả sử bạn đã viết một cái gì đó. Chúng tôi cần phải kiểm tra hoạt động kinh doanh này. Bạn cần một thiết bị vật lý để thực hiện các thử nghiệm (bảng gỡ lỗi, máy tính thứ hai) hoặc trình mô phỏng của nó. Cách thứ hai thường dễ sử dụng hơn và nhanh hơn. Đối với PC như VMWare.

Trên Internet cũng có đủ các bài viết về chủ đề này nếu bạn tìm kiếm tốt. Và cũng có rất nhiều ví dụ về hệ điều hành được tạo sẵn với các nguồn.

Ngay cả khi bạn thực sự muốn, bạn có thể xem mã nguồn của hạt nhân cũ của hệ thống NT (Windows), cả hai mã nguồn riêng biệt (một cái gì đó được trình bày bởi phần mềm vi mô, với các nhận xét và các loại tài liệu tham khảo khác nhau), và kết hợp với HĐH cũ (bị rò rỉ).

Hệ điều hành 0 đến 1 được xuất bản trên GitHub và có hơn 2.000 sao và 100 nhánh. Như tên của nó, sau khi đọc nó, bạn có thể tạo hệ điều hành của riêng mình - và có lẽ, ít thứ trong thế giới lập trình viên có thể thú vị hơn.

Qua cuốn sách này, bạn sẽ học được những điều sau:

  • Tìm hiểu cách tạo hệ điều hành dựa trên tài liệu kỹ thuật phần cứng. Đây là cách nó hoạt động trong thế giới thực, bạn không thể sử dụng Google để trả lời nhanh.
  • Hiểu cách các thành phần máy tính tương tác với nhau, từ phần mềm đến phần cứng.
  • Tự học cách viết mã. Sao chép mã một cách mù quáng không phải là một phương pháp học tập; bạn sẽ thực sự học được cách giải quyết vấn đề. Nhân tiện, sao chép mù quáng cũng rất nguy hiểm.
  • Nắm vững các công cụ quen thuộc để phát triển cấp thấp.
  • Làm quen với hợp ngữ.
  • Tìm hiểu những chương trình được tạo ra và cách hệ điều hành chạy chúng. Chúng tôi đã đưa ra một cái nhìn tổng quan nhỏ về chủ đề này cho những người tò mò.
  • Tìm ra cách gỡ lỗi một chương trình trực tiếp trên phần cứng với GDB và QEMU.
  • Ngôn ngữ lập trình C. Bạn có thể nhanh chóng làm chủ nó bằng cách làm theo.
  • Kiến thức cơ bản về Linux. Nó là đủ để nghiên cứu trên trang web của chúng tôi.
  • Kiến thức cơ bản trong vật lý: nguyên tử, electron, proton, neutron, hiệu điện thế.
  • Định luật Ôm về mối quan hệ giữa hiệu điện thế, cường độ dòng điện và cảm kháng.

Cuốn sách được cải tiến và sửa đổi hầu như mỗi ngày: bạn có thể tự mình thay đổi hoặc sửa lỗi chính tả. Hệ điều hành, sự phát triển của hệ điều hành được coi là "cốt truyện" cho cuốn sách này,

Loạt bài viết này dành cho lập trình cấp thấp, tức là kiến ​​trúc máy tính, thiết kế hệ điều hành, lập trình hợp ngữ và các lĩnh vực liên quan. Cho đến nay, đã có hai habrausers tham gia viết lách - iley và pehat. Đối với nhiều học sinh trung học, sinh viên và các lập trình viên chuyên nghiệp, những chủ đề này hóa ra rất khó học. Có rất nhiều tài liệu và khóa học về lập trình cấp thấp, nhưng rất khó để có được một bức tranh toàn cảnh và đầy đủ về chúng. Thật khó, sau khi đọc một hoặc hai cuốn sách về trình lắp ráp và hệ điều hành, ít nhất là hình dung một cách tổng quát về cách thức hoạt động của hệ thống phức tạp gồm sắt, silicon và nhiều chương trình - một máy tính - thực sự hoạt động.

Mọi người đều giải quyết vấn đề học tập theo cách riêng của họ. Ai đó đọc rất nhiều tài liệu, ai đó cố gắng nhanh chóng chuyển sang thực hành và hiểu dọc đường, ai đó cố gắng giải thích cho bạn bè mọi thứ mà mình đang học. Và chúng tôi quyết định kết hợp các cách tiếp cận này. Vì vậy, trong khóa học này của bài viết, chúng tôi sẽ trình bày từng bước cách viết một hệ điều hành đơn giản. Các bài viết sẽ mang tính chất tổng quan, tức là sẽ không chứa đầy đủ thông tin lý thuyết, tuy nhiên, chúng tôi sẽ luôn cố gắng cung cấp các liên kết đến các tài liệu lý thuyết tốt và giải đáp mọi thắc mắc phát sinh. Chúng tôi không có kế hoạch rõ ràng, vì vậy nhiều quyết định quan trọng sẽ được đưa ra trong quá trình thực hiện, có tính đến phản hồi của bạn.

Có lẽ chúng tôi sẽ cố tình dẫn quá trình phát triển vào bế tắc để cho phép bạn và chính chúng tôi hiểu đầy đủ tất cả hậu quả của một quyết định sai lầm, cũng như trau dồi một số kỹ năng kỹ thuật về nó. Vì vậy, bạn không nên coi những quyết định của chúng tôi là những quyết định đúng đắn duy nhất và tin tưởng chúng tôi một cách mù quáng. Một lần nữa, chúng tôi nhấn mạnh rằng chúng tôi mong muốn độc giả tích cực thảo luận về các bài viết, điều này sẽ ảnh hưởng mạnh mẽ đến sự phát triển chung và việc viết các bài báo tiếp theo. Tốt nhất, chúng tôi muốn thấy một số độc giả tham gia vào sự phát triển của hệ thống theo thời gian.

Chúng tôi sẽ giả định rằng người đọc đã quen thuộc với những kiến ​​thức cơ bản về hợp ngữ và ngôn ngữ C, cũng như các khái niệm cơ bản về kiến ​​trúc máy tính. Đó là, chúng tôi sẽ không giải thích thanh ghi hay bộ nhớ truy cập ngẫu nhiên là gì. Nếu chưa đủ kiến ​​thức, bạn có thể tham khảo thêm tài liệu tham khảo thêm. Một danh sách ngắn các tài liệu tham khảo và liên kết đến các trang web có các bài báo tốt nằm ở cuối bài viết. Cũng mong muốn có thể sử dụng Linux, vì tất cả các hướng dẫn biên dịch sẽ được cung cấp riêng cho hệ thống này.

Và bây giờ - hơn thế nữa. Trong phần còn lại của bài viết, chúng tôi sẽ viết một chương trình "Hello World" cổ điển. Hello World của chúng tôi sẽ trở nên cụ thể hơn một chút. Nó sẽ không chạy từ bất kỳ hệ điều hành nào, mà trực tiếp, có thể nói là "trên kim loại trần". Trước khi tiếp tục trực tiếp viết mã, hãy tìm hiểu cách chính xác chúng tôi đang cố gắng thực hiện điều này. Và đối với điều này, bạn cần phải xem xét quá trình khởi động máy tính của bạn.

Vì vậy, hãy lấy máy tính yêu thích của bạn và nhấn nút lớn nhất trên thiết bị hệ thống. Chúng tôi thấy một màn hình giật gân vui vẻ, thiết bị hệ thống phát ra tiếng bíp vui vẻ với loa và một lúc sau hệ điều hành được tải. Như bạn đã hiểu, hệ điều hành được lưu trữ trên đĩa cứng, và ở đây câu hỏi đặt ra: hệ điều hành đã khởi động kỳ diệu vào RAM và bắt đầu thực thi như thế nào?

Hãy biết điều này: hệ thống trên bất kỳ máy tính nào cũng phải chịu trách nhiệm cho việc này và tên của nó - không, không phải Windows, khiến bạn thích thú - nó được gọi là BIOS. Tên của nó là viết tắt của Basic Input-Output System, tức là hệ thống đầu vào - đầu ra cơ bản. BIOS nằm trên một vi mạch nhỏ trên bo mạch chủ và khởi động ngay sau khi nhấn nút BẬT lớn. BIOS có ba nhiệm vụ chính:

  1. Phát hiện tất cả các thiết bị được kết nối (bộ xử lý, bàn phím, màn hình, RAM, card màn hình, đầu, tay, cánh, chân và đuôi ...) và kiểm tra khả năng hoạt động của chúng. Chương trình POST (Power On Self Test) chịu trách nhiệm cho việc này. Nếu phần cứng quan trọng không được tìm thấy, thì sẽ không có phần mềm nào có thể trợ giúp và lúc này loa hệ thống sẽ kêu lên một thứ gì đó nham hiểm và hệ điều hành sẽ không thể tiếp cận được với hệ điều hành. Đừng nói về điều đáng buồn, giả sử chúng ta có một máy tính hoạt động hoàn toàn, hãy vui mừng và chuyển sang kiểm tra chức năng BIOS thứ hai:
  2. Cung cấp cho hệ điều hành một bộ chức năng cơ bản để làm việc với phần cứng. Ví dụ, thông qua các chức năng BIOS, bạn có thể hiển thị văn bản trên màn hình hoặc đọc dữ liệu từ bàn phím. Do đó, nó được gọi là hệ thống I / O cơ bản. Thông thường, hệ điều hành truy cập các chức năng này thông qua các ngắt.
  3. Khởi chạy bộ tải hệ điều hành. Trong trường hợp này, theo quy luật, khu vực khởi động được đọc - khu vực đầu tiên của vật mang thông tin (đĩa mềm, đĩa cứng, CD, ổ đĩa flash). Thứ tự của phương tiện thăm dò có thể được đặt trong BIOS SETUP. Khu vực khởi động chứa một chương trình đôi khi được gọi là bộ tải khởi động chính. Nói một cách đại khái, công việc của bootloader là khởi động hệ điều hành. Quá trình khởi động của một hệ điều hành có thể rất cụ thể và phụ thuộc nhiều vào các tính năng của nó. Do đó, bộ nạp khởi động chính được viết trực tiếp bởi các nhà phát triển hệ điều hành và được ghi vào khu vực khởi động trong quá trình cài đặt. Tại thời điểm khởi động bộ nạp khởi động, bộ xử lý đang ở chế độ thực.
Tin buồn: kích thước của bộ nạp khởi động chỉ nên là 512 byte. Tại sao quá ít? Để làm được điều này, chúng ta cần làm quen với thiết bị của đĩa mềm. Đây là một hình ảnh thông tin:

Hình ảnh cho thấy bề mặt của một ổ đĩa. Đĩa mềm có 2 bề mặt. Mỗi bề mặt có các rãnh (rãnh) hình vành khuyên. Mỗi bản nhạc được chia thành các mảnh nhỏ, hình vòm được gọi là cung. Vì vậy, về mặt lịch sử, một khu vực mềm có kích thước 512 byte. Khu vực đầu tiên trên đĩa, khu vực khởi động, được BIOS đọc vào phân đoạn bộ nhớ 0 tại offset 0x7C00, và sau đó điều khiển được chuyển đến địa chỉ này. Bộ nạp khởi động thường tải vào bộ nhớ không phải chính hệ điều hành mà là một bộ nạp khác chương trình được lưu trữ trên đĩa nhưng vì một lý do nào đó (rất có thể, lý do này là do kích thước) không vừa với một khu vực. làm cho máy tính tin vào sự tồn tại của hệ điều hành của chúng ta, ngay cả khi chỉ trên một sector và chạy nó.

Khu vực khởi động hoạt động như thế nào? Trên PC, yêu cầu duy nhất đối với khu vực khởi động là hai byte cuối cùng của nó chứa các giá trị 0x55 và 0xAA - chữ ký khu vực khởi động. Vì vậy, nó đã ít nhiều rõ ràng những gì chúng ta cần phải làm. Hãy viết mã! Đoạn mã trên được viết cho trình hợp dịch yasm.

tiết diện. chữ

sử dụng16

org 0x7C00 ; chương trình của chúng tôi được tải ở 0x7C00

khởi đầu:

mov ax, cs

mov ds, rìu ; chọn phân đoạn dữ liệu



mov si, tin nhắn

cld ; hướng cho các lệnh chuỗi

mov ah, 0x0E ; Số chức năng BIOS

mov bh, 0x00 ; trang bộ nhớ video

put_loop:

lodsb ; tải ký tự tiếp theo vào al

kiểm tra al, al ; ký tự rỗng có nghĩa là cuối dòng

jz put_loop_exit

int 0x10 ; gọi chức năng BIOS

jmp put_loop

put_loop_exit:

jmp $; chu kỳ vĩnh cửu



nhắn:

db "Xin chào Thế giới!" , 0

hoàn thành:

lần 0x1FE - kết thúc + bắt đầu db 0

db 0x55, 0xAA ; chữ ký khu vực khởi động

Chương trình ngắn này yêu cầu một số giải thích quan trọng. Dòng org 0x7C00 là cần thiết để trình hợp dịch (ý tôi là chương trình, không phải ngôn ngữ) tính toán chính xác địa chỉ cho các nhãn và biến (put_loop, put_loop_exit, message). Vì vậy, chúng tôi thông báo cho anh ta rằng chương trình sẽ được tải vào bộ nhớ tại địa chỉ 0x7C00.
Trong dòng
mov ax, cs

mov ds, rìu
phân đoạn dữ liệu (ds) được đặt bằng phân đoạn mã (cs), vì trong chương trình của chúng tôi, cả dữ liệu và mã đều được lưu trữ trong một phân đoạn.

Sau đó, thông báo “Hello World!” Được hiển thị từng ký tự trong vòng lặp. Hàm 0x0E của ngắt 0x10 được sử dụng cho việc này. Nó có các thông số sau:
AH = 0x0E (số hàm)
BH = số trang video (đừng bận tâm, chỉ định 0)
AL = mã ký tự ASCII

Tại dòng "jmp $" chương trình bị treo. Và đúng như vậy, cô ấy không cần phải thực thi thêm mã. Tuy nhiên, để máy tính hoạt động trở lại, bạn sẽ phải khởi động lại.

Trong dòng "times 0x1FE-finish + start db 0", phần còn lại của mã chương trình (ngoại trừ hai byte cuối cùng) được điền bằng các số không. Điều này được thực hiện để sau khi biên dịch, chữ ký khu vực khởi động xuất hiện trong hai byte cuối cùng của chương trình.

Chúng tôi đã tìm ra mã chương trình, bây giờ chúng ta hãy thử biên dịch niềm hạnh phúc này. Để biên dịch, trên thực tế, chúng tôi cần một trình biên dịch - điều đã đề cập ở trên


Một trong những cách tốt nhất để tiết kiệm thời gian trong bất kỳ hoạt động nào là tạo một hệ thống cho hoạt động đó. Ưu điểm của nó là bằng cách tự động hóa và tối ưu hóa công việc của mình, bạn trở nên năng suất hơn và có nhiều thời gian hơn cho các nhiệm vụ quan trọng khác đối với bạn.

Hệ thống là một phương pháp, thủ tục hoặc quy trình thường xuyên được tạo ra để thực hiện một hoạt động lặp đi lặp lại bằng cách sử dụng một chiến lược. Hệ thống cho phép bạn quản lý công việc và cuộc sống của mình hiệu quả hơn.

Dưới đây là một số lĩnh vực của cuộc sống mà bạn có thể tạo hệ thống của riêng mình:

  • Hệ thống hóa.
  • Hệ thống hóa.
  • Tổ chức các nhiệm vụ cho việc viết blog.
  • Hệ thống hóa vệ sinh nhà cửa.
  • Hệ thống hóa thói quen buổi sáng và buổi tối.
  • Hệ thống hóa xử lý email.
  • Hệ thống hóa các nhiệm vụ công việc.

Năm bước tiếp theo sẽ cho phép bạn tạo hệ thống của riêng mình cho hầu hết mọi hoạt động.

Kiểm kê

Bắt đầu bằng cách xác định những hành động bạn thực hiện thường xuyên, cả ở nhà và nơi làm việc. Phân tích ngày của bạn và xem xét tất cả những thứ tạo nên lịch trình hàng ngày của bạn. Ví dụ: chuẩn bị đi làm / đi học vào buổi sáng, chuẩn bị cho bọn trẻ đi học, đi làm, trả lời email và cuộc gọi điện thoại, viết báo cáo, chạy bộ vào buổi tối, chuẩn bị bữa tối, viết bài blog, tiếp thị sách của bạn, v.v.

Đi tới danh sách việc cần làm cụ thể cho mục bạn đã chọn và tự hỏi bản thân những điều sau:

  • Bây giờ bạn đang làm như thế nào?
  • Bạn có nghĩ rằng bạn đang làm điều này một cách hiệu quả nhất có thể?
  • Bạn lãng phí nhiều thời gian ở đâu?
  • Bạn đang mất tiền ở đâu?
  • Hành động nào khiến bạn khó chịu nhất?
  • Điều gì hiện không được thực hiện nhanh nhất có thể?
  • Những gì cần được tối ưu hóa?

Dựa trên khoảng không quảng cáo của bạn, hãy chọn một hoạt động để tổ chức.

Phân tích những gì bạn hiện đang làm

Thực hiện theo các hành động bạn muốn tổ chức bằng quy trình bình thường (nghĩa là hoạt động như bình thường). Ghi lại quá trình bằng cách ghi lại tất cả những điều sau:

  • Bạn đang thực hiện những bước nào?
  • Bạn đang sử dụng công cụ nào?
  • Đâu là “điểm nghẽn” (thời gian bị lãng phí, sự chậm trễ xảy ra liên tục, sự cố xảy ra)?
  • Điều gì làm bạn thất vọng?
  • Mất bao lâu để hoàn thành hoạt động này?
  • cái này giá bao nhiêu?
  • Kết quả bạn nhận được là gì?

Sau đó, xem xét tài liệu kết quả và nghiên cứu nó.

Lập kế hoạch cho một quy trình mới

Hệ thống, như chúng tôi đã chỉ ra trước đó, là một quy trình mà bạn tạo ra để tối ưu hóa các tác vụ và tăng hiệu quả. Hãy xem tài liệu của bạn và hoạt động bạn muốn tối ưu hóa và tự hỏi bản thân những câu hỏi sau:

  • Bạn muốn đạt được kết quả gì khi thực hiện hoạt động này? Bạn đang cố gắng đạt được mục tiêu gì? Kết quả lý tưởng là gì?
  • Tất cả các bước bạn thực hiện có cần thiết không? Có thể loại bỏ một số trong số chúng không?
  • Bạn có đang làm theo các bước theo trình tự hiệu quả nhất không? Bạn có nhận được kết quả khác nếu bạn thay đổi thứ tự của các bước không?
  • Làm thế nào để tất cả điều này được thực hiện nhanh hơn?
  • Bạn có thể tạo danh sách kiểm tra, sơ đồ, bản đồ tư duy hoặc tập lệnh cho hoạt động này không?
  • Có thể tự động hóa một số bước hoặc toàn bộ quy trình không? Có một chương trình bạn có thể sử dụng cho việc này?
  • Có thể ủy thác một số bước hoặc toàn bộ quy trình không?
  • Bạn có cần cập nhật các công cụ bạn đang sử dụng không?

Bây giờ hãy viết ra hệ thống mới của bạn chi tiết từng bước.

Thực hiện theo kế hoạch

Khi bạn có một kế hoạch, bạn cần phải bắt tay vào thực hiện ngay. Trước tiên, bạn có thể cần nhờ người khác trợ giúp, mua phần mềm hoặc cập nhật các công cụ của mình.

Bây giờ là lúc để bắt đầu quá trình và kiểm tra công việc của nó. Chạy nó và thông báo kết quả. Hãy tự hỏi mình những câu hỏi sau đây:

  • Bạn đã có kết quả như mong muốn chưa?
  • Những gì hoạt động?
  • Những gì không hoạt động?
  • Bạn đã tiết kiệm được bao nhiêu thời gian?
  • Tất cả chi phí là bao nhiêu? Cho biết kết quả, hệ thống có hiệu quả không?
  • Bạn có đang đạt được mục tiêu của mình một cách dễ dàng nhất không?
  • Có bất kỳ lỗ hổng nào trong quá trình này không?
  • Bạn vẫn có thể tối ưu hóa quy trình chứ?

Thực hiện các điều chỉnh và thay đổi cần thiết. Cập nhật hệ thống của bạn cho đến khi bạn nhận được kết quả mong muốn.

Cải thiện hệ thống liên tục

Bạn nên theo dõi hệ thống của mình liên tục, bởi vì trong một thế giới đang thay đổi nhanh chóng, nó có thể nhanh chóng trở nên lỗi thời. Luôn tự hỏi bản thân xem có cần cải thiện không.

  • Hệ thống có hoạt động như bình thường không?
  • Bạn có thể giảm chi phí của hệ thống?
  • Bạn có thể làm cho hệ thống hiệu quả hơn không?
  • Bạn có thể đơn giản hóa hệ thống để đạt được kết quả tốt hơn không?

Việc thiết lập một hệ thống luôn đòi hỏi sự đầu tư về thời gian. Nhưng bằng cách chi tiêu ban đầu nhiều hơn mức bạn thường chi tiêu, cuối cùng bạn sẽ tiết kiệm được rất nhiều. Và bạn giảm thiểu tác động của căng thẳng hoạt động.

Chúng tôi chúc bạn may mắn!

Loạt bài viết này dành cho lập trình cấp thấp, tức là kiến ​​trúc máy tính, thiết kế hệ điều hành, lập trình hợp ngữ và các lĩnh vực liên quan. Cho đến nay, hai habrauzera đang tham gia viết lách - và. Đối với nhiều học sinh trung học, sinh viên và các lập trình viên chuyên nghiệp, những chủ đề này hóa ra rất khó học. Có rất nhiều tài liệu và khóa học về lập trình cấp thấp, nhưng rất khó để có được một bức tranh toàn cảnh và đầy đủ về chúng. Thật khó, sau khi đọc một hoặc hai cuốn sách về trình lắp ráp và hệ điều hành, ít nhất là hình dung một cách tổng quát về cách thức hoạt động của hệ thống phức tạp gồm sắt, silicon và nhiều chương trình - một máy tính - thực sự hoạt động.

Mọi người đều giải quyết vấn đề học tập theo cách riêng của họ. Ai đó đọc rất nhiều tài liệu, ai đó cố gắng nhanh chóng chuyển sang thực hành và hiểu dọc đường, ai đó cố gắng giải thích cho bạn bè mọi thứ mà mình đang học. Và chúng tôi quyết định kết hợp các cách tiếp cận này. Vì vậy, trong khóa học này của bài viết, chúng tôi sẽ trình bày từng bước cách viết một hệ điều hành đơn giản. Các bài viết sẽ mang tính chất tổng quan, tức là sẽ không chứa đầy đủ thông tin lý thuyết, tuy nhiên, chúng tôi sẽ luôn cố gắng cung cấp các liên kết đến các tài liệu lý thuyết tốt và giải đáp mọi thắc mắc phát sinh. Chúng tôi không có kế hoạch rõ ràng, vì vậy nhiều quyết định quan trọng sẽ được đưa ra trong quá trình thực hiện, có tính đến phản hồi của bạn.

Có lẽ chúng tôi sẽ cố tình dẫn quá trình phát triển vào bế tắc để cho phép bạn và chính chúng tôi hiểu đầy đủ tất cả hậu quả của một quyết định sai lầm, cũng như trau dồi một số kỹ năng kỹ thuật về nó. Vì vậy, bạn không nên coi những quyết định của chúng tôi là những quyết định đúng đắn duy nhất và tin tưởng chúng tôi một cách mù quáng. Một lần nữa, chúng tôi nhấn mạnh rằng chúng tôi mong muốn độc giả tích cực thảo luận về các bài viết, điều này sẽ ảnh hưởng mạnh mẽ đến sự phát triển chung và việc viết các bài báo tiếp theo. Tốt nhất, chúng tôi muốn thấy một số độc giả tham gia vào sự phát triển của hệ thống theo thời gian.

Chúng tôi sẽ giả định rằng người đọc đã quen thuộc với những kiến ​​thức cơ bản về hợp ngữ và ngôn ngữ C, cũng như các khái niệm cơ bản về kiến ​​trúc máy tính. Đó là, chúng tôi sẽ không giải thích thanh ghi hay bộ nhớ truy cập ngẫu nhiên là gì. Nếu chưa đủ kiến ​​thức, bạn có thể tham khảo thêm tài liệu tham khảo thêm. Một danh sách ngắn các tài liệu tham khảo và liên kết đến các trang web có các bài báo tốt nằm ở cuối bài viết. Cũng mong muốn có thể sử dụng Linux, vì tất cả các hướng dẫn biên dịch sẽ được cung cấp riêng cho hệ thống này.

Và bây giờ - hơn thế nữa. Trong phần còn lại của bài viết, chúng tôi sẽ viết một chương trình "Hello World" cổ điển. Hello World của chúng tôi sẽ trở nên cụ thể hơn một chút. Nó sẽ không chạy từ bất kỳ hệ điều hành nào, mà trực tiếp, có thể nói là "trên kim loại trần". Trước khi tiếp tục trực tiếp viết mã, hãy tìm hiểu cách chính xác chúng tôi đang cố gắng thực hiện điều này. Và đối với điều này, bạn cần phải xem xét quá trình khởi động máy tính của bạn.

Vì vậy, hãy lấy máy tính yêu thích của bạn và nhấn nút lớn nhất trên thiết bị hệ thống. Chúng tôi thấy một màn hình giật gân vui vẻ, thiết bị hệ thống phát ra tiếng bíp vui vẻ với loa và một lúc sau hệ điều hành được tải. Như bạn đã hiểu, hệ điều hành được lưu trữ trên đĩa cứng, và ở đây câu hỏi đặt ra: hệ điều hành đã khởi động kỳ diệu vào RAM và bắt đầu thực thi như thế nào?

Hãy biết điều này: hệ thống trên bất kỳ máy tính nào cũng phải chịu trách nhiệm cho việc này và tên của nó - không, không phải Windows, khiến bạn thích thú - nó được gọi là BIOS. Tên của nó là viết tắt của Basic Input-Output System, tức là hệ thống đầu vào - đầu ra cơ bản. BIOS nằm trên một vi mạch nhỏ trên bo mạch chủ và khởi động ngay sau khi nhấn nút BẬT lớn. BIOS có ba nhiệm vụ chính:

  1. Phát hiện tất cả các thiết bị được kết nối (bộ xử lý, bàn phím, màn hình, RAM, card màn hình, đầu, tay, cánh, chân và đuôi ...) và kiểm tra khả năng hoạt động của chúng. Chương trình POST (Power On Self Test) chịu trách nhiệm cho việc này. Nếu phần cứng quan trọng không được tìm thấy, thì sẽ không có phần mềm nào có thể trợ giúp và lúc này loa hệ thống sẽ kêu lên một thứ gì đó nham hiểm và hệ điều hành sẽ không thể tiếp cận được với hệ điều hành. Đừng nói về điều đáng buồn, giả sử chúng ta có một máy tính hoạt động hoàn toàn, hãy vui mừng và chuyển sang kiểm tra chức năng BIOS thứ hai:
  2. Cung cấp cho hệ điều hành một bộ chức năng cơ bản để làm việc với phần cứng. Ví dụ, thông qua các chức năng BIOS, bạn có thể hiển thị văn bản trên màn hình hoặc đọc dữ liệu từ bàn phím. Do đó, nó được gọi là hệ thống I / O cơ bản. Thông thường, hệ điều hành truy cập các chức năng này thông qua các ngắt.
  3. Khởi chạy bộ tải hệ điều hành. Trong trường hợp này, theo quy luật, khu vực khởi động được đọc - khu vực đầu tiên của vật mang thông tin (đĩa mềm, đĩa cứng, CD, ổ đĩa flash). Thứ tự của phương tiện thăm dò có thể được đặt trong BIOS SETUP. Khu vực khởi động chứa một chương trình đôi khi được gọi là bộ tải khởi động chính. Nói một cách đại khái, công việc của bootloader là khởi động hệ điều hành. Quá trình khởi động của một hệ điều hành có thể rất cụ thể và phụ thuộc nhiều vào các tính năng của nó. Do đó, bộ nạp khởi động chính được viết trực tiếp bởi các nhà phát triển hệ điều hành và được ghi vào khu vực khởi động trong quá trình cài đặt. Tại thời điểm khởi động bộ nạp khởi động, bộ xử lý đang ở chế độ thực.
Tin buồn: kích thước của bộ nạp khởi động chỉ nên là 512 byte. Tại sao quá ít? Để làm được điều này, chúng ta cần làm quen với thiết bị của đĩa mềm. Đây là một hình ảnh thông tin:

Hình ảnh cho thấy bề mặt của một ổ đĩa. Đĩa mềm có 2 bề mặt. Mỗi bề mặt có các rãnh (rãnh) hình vành khuyên. Mỗi bản nhạc được chia thành các mảnh nhỏ, hình vòm được gọi là cung. Vì vậy, về mặt lịch sử, một khu vực mềm có kích thước 512 byte. Khu vực đầu tiên trên đĩa, khu vực khởi động, được BIOS đọc vào phân đoạn bộ nhớ 0 tại offset 0x7C00, và sau đó điều khiển được chuyển đến địa chỉ này. Bộ nạp khởi động thường tải vào bộ nhớ không phải chính hệ điều hành mà là một bộ nạp khác chương trình được lưu trữ trên đĩa nhưng vì một lý do nào đó (rất có thể, lý do này là do kích thước) không vừa với một khu vực. làm cho máy tính tin vào sự tồn tại của hệ điều hành của chúng ta, ngay cả khi chỉ trên một sector và chạy nó.

Khu vực khởi động hoạt động như thế nào? Trên PC, yêu cầu duy nhất đối với khu vực khởi động là hai byte cuối cùng của nó chứa các giá trị 0x55 và 0xAA - chữ ký khu vực khởi động. Vì vậy, nó đã ít nhiều rõ ràng những gì chúng ta cần phải làm. Hãy viết mã! Đoạn mã trên được viết cho trình hợp dịch yasm.

tiết diện. chữ

sử dụng16

org 0x7C00 ; chương trình của chúng tôi được tải ở 0x7C00

khởi đầu:

mov ax, cs

mov ds, rìu ; chọn phân đoạn dữ liệu



mov si, tin nhắn

cld ; hướng cho các lệnh chuỗi

mov ah, 0x0E ; Số chức năng BIOS

mov bh, 0x00 ; trang bộ nhớ video

put_loop:

lodsb ; tải ký tự tiếp theo vào al

kiểm tra al, al ; ký tự rỗng có nghĩa là cuối dòng

jz put_loop_exit

int 0x10 ; gọi chức năng BIOS

jmp put_loop

put_loop_exit:

jmp $; chu kỳ vĩnh cửu



nhắn:

db "Xin chào Thế giới!" , 0

hoàn thành:

lần 0x1FE - kết thúc + bắt đầu db 0

db 0x55, 0xAA ; chữ ký khu vực khởi động

Chương trình ngắn này yêu cầu một số giải thích quan trọng. Dòng org 0x7C00 là cần thiết để trình hợp dịch (ý tôi là chương trình, không phải ngôn ngữ) tính toán chính xác địa chỉ cho các nhãn và biến (put_loop, put_loop_exit, message). Vì vậy, chúng tôi thông báo cho anh ta rằng chương trình sẽ được tải vào bộ nhớ tại địa chỉ 0x7C00.
Trong dòng
mov ax, cs

mov ds, rìu
phân đoạn dữ liệu (ds) được đặt bằng phân đoạn mã (cs), vì trong chương trình của chúng tôi, cả dữ liệu và mã đều được lưu trữ trong một phân đoạn.

Sau đó, thông báo “Hello World!” Được hiển thị từng ký tự trong vòng lặp. Hàm 0x0E của ngắt 0x10 được sử dụng cho việc này. Nó có các thông số sau:
AH = 0x0E (số hàm)
BH = số trang video (đừng bận tâm, chỉ định 0)
AL = mã ký tự ASCII

Tại dòng "jmp $" chương trình bị treo. Và đúng như vậy, cô ấy không cần phải thực thi thêm mã. Tuy nhiên, để máy tính hoạt động trở lại, bạn sẽ phải khởi động lại.

Trong dòng "times 0x1FE-finish + start db 0", phần còn lại của mã chương trình (ngoại trừ hai byte cuối cùng) được điền bằng các số không. Điều này được thực hiện để sau khi biên dịch, chữ ký khu vực khởi động xuất hiện trong hai byte cuối cùng của chương trình.

Chúng tôi đã tìm ra mã chương trình, bây giờ chúng ta hãy thử biên dịch niềm hạnh phúc này. Để biên dịch, trên thực tế, chúng tôi cần một trình biên dịch - điều đã đề cập ở trên