<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## 寫在前面 下面有不熟悉的代碼很正常,這節課主要目的是讓我們跑一下。 引用編輯恢復評論里的一句話: 初入門一個上下左右都有很多牽扯的復雜網狀系統的時候,一定要像張無忌學太極劍一樣,只記住劍意,選擇性忘記忽略一些細枝末節。不然的話,很可能就會被帶跑偏,沉溺于一些奇奇怪怪暫時又不太重要的東西。 **學習可以先抓主線,慢慢消化甚至優化細節** ## PC 機的引導流程 這里課程沒有從 PC 的引導程序開始寫起,原因是目前我們的知識儲備還不夠,所以先借用一下 GRUB 引導程序,只要我們的 PC 機上安裝了 Ubuntu Linux 操作系統,GRUB 就已經存在了。 下面附上我們要跑起來的Hello OS的引導流程圖: ![](https://img.kancloud.cn/11/9f/119f69bcf46dcfe7a946f012a8649907_4335x3170.png) ## Hello OS 引導匯編代碼 ```asm ;彭東 @ 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 ;重新加載GDT 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. 代碼 1~40 行,用匯編定義的 GRUB 的多引導協議頭,其實就是一定格式的數據,我們的 Hello OS 是用 GRUB 引導的,當然要遵循 GRUB 的多引導協議標準,讓 GRUB 能識別我們的 Hello OS。之所以有兩個引導頭,是為了兼容 GRUB1 和 GRUB2。 2. 代碼 44~52 行,關掉中斷,設定 CPU 的工作模式。你現在可能不懂,沒事兒,后面 CPU 相關的課程我們會專門再研究它。 3. 代碼 54~73 行,初始化 CPU 的寄存器和 C 語言的運行環境。 4. 代碼 78~87 行,GDT_START 開始的,是 CPU 工作模式所需要的數據,同樣,后面講 CPU 時會專門介紹。 ## Hello OS 的主函數 ```c //彭東 @ 2021.01.09 #include "vgastr.h" void main() { printf("Hello OS!"); return; } ``` ## 控制計算機屏幕 附:顯卡的字符模式的工作細節 它把屏幕分成 24 行,每行 80 個字符,把這(24*80)個位置映射到以 0xb8000 地址開始的內存中,每兩個字節對應一個字符,其中一個字節是字符的 ASCII 碼,另一個字節為字符的顏色值。如下圖所示: ![](https://img.kancloud.cn/83/59/8359572ac3177435b302891eb52e5267_3530x1605.png) ## 編譯和安裝 Hello OS 下載代碼 `git clone https://gitee.com/lmos/cosmos.git` 目錄結構如下 ![](https://img.kancloud.cn/1b/23/1b238ca1630e1a1239ef1e2f69194963_761x157.png) * entry.asm:是一段匯編代碼,用作GRUB引導調用,關掉中斷,設定CPU工作模式,初始化寄存器及C語言運行環境等; * hello.lds:進行鏈接調用,代碼簡單看看,反正也看不懂: ```lds ENTRY(_start) OUTPUT_ARCH(i386) OUTPUT_FORMAT(elf32-i386) SECTIONS { . = 0x200000; __begin_start_text = .; .start.text : ALIGN(4) { *(.start.text) } __end_start_text = .; ? __begin_text = .; .text : ALIGN(4) { *(.text) } __end_text = .; ? __begin_data = .; .data : ALIGN(4) { *(.data) } __end_data = .; ? __begin_rodata = .; .rodata : ALIGN(4) { *(.rodata) *(.rodata.*) } __end_rodata = .; ? __begin_kstrtab = .; .kstrtab : ALIGN(4) { *(.kstrtab) } __end_kstrtab = .; ? __begin_bss = .; .bss : ALIGN(4) { *(.bss) } __end_bss = .; } ``` * install.md:需要將這個文件里的內容復制到GRUB的cfg配置文件中,才能使電腦開機時可以找到我們的Hello OS; * main.c:我們Hello OS的主函數,它調用的printf可不是常見的C語言庫函數哦,而是我們自己實現的printf! ![](https://img.kancloud.cn/28/aa/28aa015628cedcb775ca8b1c4f4075e8_316x138.png) 即下面要講的vgastr.h; * vgastr.h:控制計算機屏幕VGABIOS固件程序顯示特定字符,后面詳細介紹; * Makefile:利用make工具來實現編譯源代碼,主要是將entry.asm、main.c、vgastr.h編譯并鏈接。 ### 編譯操作系統 ### 流程 ![](https://img.kancloud.cn/99/58/9958c1d2c15c80931515df2e99bc2faa_4378x4923.png) ### 編譯 ![](https://img.kancloud.cn/51/e4/51e42c4957f0a29fac8897c7d0150319_951x346.gif) 提示 **nasm**編譯器沒有安裝 安裝一下:`sudo apt-get install nasm` 繼續編譯: ![](https://img.kancloud.cn/a5/44/a54444a4b24020d68f280919c3fefb4b_951x416.gif) ### 安裝 #### 找到boot目錄掛載分區: `df /boot/` ![](https://img.kancloud.cn/9e/f8/9ef80bac3e6e5516cf6e2fa5b4dd0aac_699x78.png) 可以看到虛擬機中ubuntu16.04的系統GRUB引導是在硬盤的第**五**分區 然后**打開文件夾中的install.md,復制粘貼到\***\*/boot/grub/grub.cfg中\*\*,install.md主要是加載我們的Hello OS的啟動項: ![](https://img.kancloud.cn/5b/c6/5bc6897d36730fd29560dc9fa8d1315c_815x331.png) ```vim /boot/grub/grub.cfg``` ![](https://img.kancloud.cn/54/92/5492da23038944a861c3a3a4dafa780f_968x712.png) 將 **Hello OS.bin** 文件復制到 /boot/ 目錄下 ![![](https://img.kancloud.cn/f7/9e/f79e41babb6e63968e5ce71c78c917bb_874x351.png)](images/screenshot_1628234267320.png) ### 設置GRUB引導界面時間 **執行命令**:`sudo gedit /etc/default/grub` 修改圖示內容 ![](https://img.kancloud.cn/2c/88/2c88bb5404a824b82c4229e1721039bc_868x289.png) **更新grub配置** `sudo update-grub` ![](https://img.kancloud.cn/ff/4d/ff4d961440acd2de714a07c470f50c81_610x213.png) #### 重啟查看效果 **以上一切看起來都沒問題,也沒有報錯,但是,遇到坑了!!** 我驚奇的發現,我重啟系統的時候,啟動項里竟然沒有HelloOs選項,經過反復排錯(用戶權限問題,代碼段放置位置問題,等等)后,折騰一個小時后,我終于找到問題了:**設置GRUB引導界面時間,更新grub配置,一定要放在配置/boot/grub/grub.cfg后進行!** 查看一下效果: ![](https://img.kancloud.cn/fe/5a/fe5a6e8f6ffd70fa6be5108aca743def_1051x715.gif) >0x7C00?由來的一種說法。當時,搭配的操作系統是86-DOS。這個操作系統需要的內存最少是32KB。我們知道,內存地址從0x0000開始編號,32KB的內存就是0x0000~0x7FFF。8088芯片本身需要占用0x0000~0x03FF,用來保存各種中斷處理程序的儲存位置。(主引導記錄本身就是中斷信號INT?19h的處理程序。)所以,內存只剩下0x0400~0x7FFF可以使用。為了把盡量多的連續內存留給操作系統,主引導記錄就被放到了內存地址的尾部。由于一個扇區是512字節,主引導記錄本身也會產生數據,需要另外留出512字節保存(自己?和?產生)。所以,它的預留位置就變成了: ????0x7FFF?-?512?-?512?+?1?=?0x7C00
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看