linux中部署自己的系統核心

2022-10-11 10:03:11 字數 4040 閱讀 2137

pc機bios韌體是固化在pc機主板上的rom晶元中,斷電也能儲存,pc機上電後的第一條指令就是在bios韌體中,它負責檢測和初始化cpu、記憶體和主機板平台,然後載入引導裝置(大概率是硬碟)中的第乙個扇區資料,到0x7c00位址開始的記憶體空間,再跳轉到0x7c00處執行指令。這裡是grub引導程式。

為什麼不能直接用c?

c 作為通用的高階語言,不能直接操作特定的硬體,而且 c 語言的函式呼叫、函式傳參,都需要用棧。

棧,資料滿足後進先出的特性,它由cpu特定的暫存器指向,所以需要先用彙編**處理好c語言的工作環境

;彭東 @ 2021.01.09

mbt_hdr_flags equ 0x00010003

mbt_hdr_magic equ 0x1badb002 ;多引導協議頭魔數

mbt_hdr2_magic equ 0xe85250d6 ;第二版多引導協議頭魔數

global _start ;匯出_start符號

extern main ;匯入外部的main函式符號

[section .start.text] ;定義.start.text**節

[bits 32] ;彙編成32位**

_start:

jmp _entry

align 8

mbt_hdr:

dd mbt_hdr_magic

dd mbt_hdr_flags

dd -(mbt_hdr_magic+mbt_hdr_flags)

dd mbt_hdr

dd _start

dd 0

dd 0

dd _entry

;以上是grub所需要的頭

align 8

mbt2_hdr:

dd mbt_hdr2_magic

dd 0

dd mbt2_hdr_end - mbt2_hdr

dd -(mbt_hdr2_magic + 0 + (mbt2_hdr_end - mbt2_hdr))

dw 2, 0

dd 24

dd mbt2_hdr

dd _start

dd 0

dd 0

dw 3, 0

dd 12

dd _entry

dd 0

dw 0, 0

dd 8

mbt2_hdr_end:

;以上是grub2所需要的頭

;包含兩個頭是為了同時相容grub、grub2

align 8

_entry:

;關中斷

cli;關不可遮蔽中斷

in al, 0x70

or al, 0x80

out 0x70,al

lgdt [gdt_ptr]

jmp dword 0x8 :_32bits_mode

_32bits_mode:

;下面初始化c語言可能會用到的暫存器

mov ax, 0x10

mov ds, ax

mov ss, ax

mov es, ax

mov fs, ax

mov gs, ax

xor eax,eax

xor ebx,ebx

xor ecx,ecx

xor edx,edx

xor edi,edi

xor esi,esi

xor ebp,ebp

xor esp,esp

;初始化棧,c語言需要棧才能工作

mov esp,0x9000

;呼叫c語言函式main

call main

;讓cpu停止執行指令

halt_step:

halt

jmp halt_step

gdt_start:

knull_dsc: dq 0

kcode_dsc: dq 0x00cf9e000000ffff

kdata_dsc: dq 0x00cf92000000ffff

k16cd_dsc: dq 0x00009e000000ffff

k16da_dsc: dq 0x000092000000ffff

gdt_end:

gdt_ptr:

gdtlen dw gdt_end-gdt_start-1

gdtbase dd gdt_start

** 1~40 行,用彙編定義的 grub 的多引導協議頭,其實就是一定格式的資料,我們的 hello os 是用 grub 引導的,當然要遵循 grub 的多引導協議標準,讓 grub 能識別我們的 hello os。之所以有兩個引導頭,是為了相容 grub1 和 grub2。

** 44~52 行,關掉中斷,設定 cpu 的工作模式

** 54~73 行,初始化 cpu 的暫存器和 c 語言的執行環境。

** 78~87 行,gdt_start 開始的,是 cpu 工作模式所需要的資料

#include "vgastr.h"

void main()

注意:這裡的printf不是應用程式庫中的printf,是需要自己實現的

具體實現如下:

void _strwrite(char* string)

return;

}void printf(char* fmt, ...)

顯示卡的字元模式的工作細節:

它把螢幕分成 24 行,每行 80 個字元,把這(24*80)個位置對映到以 0xb8000 位址開始的記憶體中,每兩個位元組對應乙個字元,其中乙個位元組是字元的 ascii 碼,另乙個位元組為字元的顏色值。如下圖所示:

因此在上述顯示printf的**中要從0xb8000 開始寫,p_strdst 每次+2跳過字元的顏色空間的原因

該選項將使得在鏈結過程中,生成鏈結布局檔案,通過該檔案可知helloos的記憶體對映布局

編譯helloos時生成的map檔案如下圖所示:

將helloos作為乙個作業系統啟動項供grub啟動,因此需要能夠在pc啟動時進入grub引導選單,並選擇啟動helloos

為了能夠每次啟動時進入grub引導選單,需要進行如下設定

a. 注釋掉hidden所在的2行

b. 將grub_timeout設定為30(使用預設值10其實也可以)

c. 將grub_cmdline_linux_defaul設定為text

參考

執行如下命令,更新grub配置

sudo update-grub
menuentry 'helloos'
ps:

使用df /boot 檢視/boot分割槽情況

選擇該啟動項,即可啟動helloos

linux中部署redis案例

1.作業系統 ubuntu 14.04 64位 2.jdk版本 1.8 3.工具 xshell5 xftp5 4.說明 本文是通過xshell5工具遠端連線linux操作,如果是直接在linux視覺化介面操作那就更方便了,原理一樣 方法一2.將壓縮包上傳至linux伺服器,我的上傳至home目錄下面...

Docker中部署 ELK日誌分析系統

一 docker環境搭建 linux x64下 1 通過yum安裝 可以連線外網 2 手動安裝 不能連線外網,無法yum安裝 二 elk原理圖 logstash forwarder 監控input 日誌檔案 socket.的改變,並發給logstash logstash 通過配置檔案裡的設定過濾 正...

家中部署WiFi何須求人 自己動手就搞定

現在wifi已成生活必備品,相信各位讀者的家中也都部署了無線網路。設定和安裝無線路由器在老鳥們看來是在是小菜一碟的事,而對沒有什麼網路知識的新手來說,還是要頗費一番周折的。無論是 大蝦 還是 小白 肯定都不希望在設定無線路由器上花太多的時間,快速安裝好後享受無線網路才是正題。而且,在管控網路方面,最...