羽夏看Linux核心——環境搭建

2022-08-06 06:00:25

寫在前面

  此係列是本人一個字一個字碼出來的,包括範例和實驗截圖。如有好的建議,歡迎反饋。碼字不易,如果本篇文章有幫助你的,如有閒錢,可以打賞支援我的創作。如想轉載,請把我的轉載資訊附在文章後面,並宣告我的個人資訊和本人部落格地址即可,但必須事先通知我

前言

  在學習與計算機相關的知識時,工欲善其事,必先利其器,搭建一個優秀的學習實驗環境是完成學習任務和提高學習熱情的推動劑。本來虛擬機器器想選VirtualBox,不過太難搞了,網上也沒有好到成熟的教學,最關鍵是沒有配套的偵錯功能,這樣很不直觀。到最後我還是選擇了Bochs
  嚴格的說,Bochs是一個模擬器。它是一個以LGPL許可證發放的開放原始碼的x86x86-64IBM PC相容機模擬器和偵錯工具。它支援處理器(包括保護模式)、記憶體、硬碟、顯示器、乙太網、BIOSIBM PC相容機的常見硬體外設的模擬,主要用於作業系統開發。
  說了這麼有關Bochs一大堆,它有一個十分優秀的地方,它具有配套的偵錯工具,只要在編譯期間開啟了對應的開關,就可以實現偵錯的圖形介面化,這在 Linux 上是可遇不可求的,如下圖所示:

  這個和我係統主題相關,看起來比較醜一點,但這已經很不錯了,在開發與 Linux 相關應用的同志會深有體會。
  下面我們來開始編譯Bochs,為 Linux 核心的學習開始新的旅程。

編譯 Bochs

  在編譯之前,我們需要安裝編譯所需的依賴,請輸入以下指令:

sudo apt install build-essential
sudo apt install libgtk2.0-dev 

  我們解壓我們下載的Bochs原始碼,然後在該檔案開啟終端,輸入如下命令:

./configure --with-x11 --with-wx --enable-disasm --enable-all-optimizations --enable-readline  --enable-debugger-gui --enable-x86-debugger --enable-a20-pin --enable-fast-function-calls --enable-debugger --enable-iodebug

  --後面跟著字母的引數就是我所謂的開關,開啟這些開關之後,就支援反組合、內建偵錯、io 介面偵錯以及圖形介面。
  該指令執行完之後,就會在該目錄下生成MakeFile檔案,我們需要編輯一下繼續。找到檔案的第92行,在最後加一個引數-lpthread,如下所示:

LIBS =  -lm -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfontconfig -lfreetype -lpthread

  如果不這麼修改,在編譯的過程中就會報錯。因為pthread庫不是Linux系統預設的庫,連線時需要使用靜態庫 libpthread.a,所以在使用pthread_create建立執行緒,以及呼叫pthread_atfork函數建立fork處理程式時,需要連結該庫。
  然後我們輸入make回車,不到一分鐘就能編譯完。如果編譯無報錯,我們再輸入sudo make install將其安裝在系統當中。
  如果以後要解除安裝,請保留編譯過後留下的內容,只需要MakeFile資料夾下,進入終端,輸入sudo make uninstall即可解除安裝。

設定 Bochs

  下面我們需要簡單設定一下它以能夠使用,我們需要一個組態檔。由於個人習慣起名字為bochsrc.disk,它的內容如下:

#=======================================================================
# MEGS
# Set the number of Megabytes of physical memory you want to emulate. 
# The default is 32MB, most OS's won't need more than that.
# The maximum amount of memory supported is 2048Mb.
# The 'MEGS' option is deprecated. Use 'MEMORY' option instead.
#=======================================================================
megs: 32

#=======================================================================
# DISPLAY_LIBRARY
#
# The display library is the code that displays the Bochs VGA screen.  Bochs 
# has a selection of about 10 different display library implementations for 
# different platforms.  If you run configure with multiple --with-* options, 
# the display_library command lets you choose which one you want to run with.
# If you do not write a display_library line, Bochs will choose a default for
# you.
#=======================================================================
display_library: x, options="gui_debug" # use GTK debugger gui

#=======================================================================
# ROMIMAGE:
# The ROM BIOS controls what the PC does when it first powers on.
# Normally, you can use a precompiled BIOS in the source or binary
# distribution called BIOS-bochs-latest. The ROM BIOS is usually loaded
# starting at address 0xf0000, and it is exactly 64k long. Another option
# is 128k BIOS which is loaded at address 0xe0000.
# You can also use the environment variable $BXSHARE to specify the
# location of the BIOS.
# The usage of external large BIOS images (up to 512k) at memory top is
# now supported, but we still recommend to use the BIOS distributed with
# Bochs. The start address optional, since it can be calculated from image size.
#=======================================================================
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest

#=======================================================================
# VGAROMIMAGE
# You now need to load a VGA ROM BIOS into C0000.
#=======================================================================
vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest

#=======================================================================
# BOOT:
# This defines the boot sequence. Now you can specify up to 3 boot drives,
# which can be 'floppy', 'disk', 'cdrom' or 'network' (boot ROM).
# Legacy 'a' and 'c' are also supported.
#=======================================================================
#boot: floppy
boot: disk

#=======================================================================
# LOG:
# Give the path of the log file you'd like Bochs debug and misc. verbiage
# to be written to. If you don't use this option or set the filename to
# '-' the output is written to the console. If you really don't want it,
# make it "/dev/null" (Unix) or "nul" (win32). :^(
#=======================================================================
#log: /dev/null
log: bochsout.txt

#=======================================================================
# MOUSE:
# The Bochs gui creates mouse "events" unless the 'enabled' option is
# set to 0. The hardware emulation itself is not disabled by this.
# Unless you have a particular reason for enabling the mouse by default,
# it is recommended that you leave it off. You can also toggle the mouse
# usage at runtime (control key + middle mouse button on X11, SDL,
# wxWidgets and Win32).
# With the mouse type option you can select the type of mouse to emulate.
# The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
# on PS/2), 'serial', 'serial_wheel' and 'serial_msys' (one com port requires
# setting 'mode=mouse'). To connect a mouse to an USB port, see the 'usb_uhci'
# or 'usb_ohci' option (requires PCI and USB support).
#=======================================================================
mouse: enabled=0

#=======================================================================
# KEYBOARD_MAPPING:
# This enables a remap of a physical localized keyboard to a 
# virtualized us keyboard, as the PC architecture expects.
# If enabled, the keymap file must be specified.
#=======================================================================
keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/x11-pc-us.map

#=======================================================================
# ATA0, ATA1, ATA2, ATA3
# ATA controller for hard disks and cdroms
#
# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number
# 
# These options enables up to 4 ata channels. For each channel
# the two base io addresses and the irq must be specified.
# 
# ata0 and ata1 are enabled by default with the values shown below
#=======================================================================
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14

  如果啥也不想了解,直接新建檔案拷進去就能用。不過我建議你還是得了解一下。
  這個組態檔,它有點類似BIOS。我們在開機時按下的delesc ,或者F2鍵,各個機型進入BIOS式有所不同,但差不多就那幾種方式。BIOS中會顯示各種硬體的資訊,還有啟動順序等。Bochs既然是模擬硬體的,它就得知道,您需要它模擬的計算機是什麼樣的,換句話說,在這個虛擬機器器中有哪些硬體,啟動順序是什麼,是從軟碟開始,還是從硬碟開始。給Bochs設定硬體的方法,就是寫一個組態檔給它,Bochs啟動時會找到此檔案,根據檔案內容建立自己,這樣咱們的虛擬機器器就健全了。
  在安裝目錄下有樣本檔案:/usr/local/share/doc/bochs,裡面非常全,只不過是英文的,我上面的只是必須使用的部分。下面我們來介紹一下我使用的相關設定含義:

megs

  設定Bochs在執行過程中能夠使用的記憶體,本例為 32MB

display_library

  設定圖形介面,這條設定就可以啟用我們的圖形介面化偵錯,而不是黑框。

romimage

  設定對應的BIOS

vgaromimage

  設定對應的VGA BIOS。它是顯示卡BIOS,儲存了顯示卡的硬體控制程式和相關資訊,可以說是顯示卡的「神經中樞」。

boot

  選擇啟動碟符,floppy是軟碟的意思,disk是磁碟的意思,指的是從什麼地方啟動,這裡是從磁碟啟動。

log

  輸出的紀錄檔路徑。

mouse

  滑鼠相關設定,這裡被禁用。

keyboard_mapping

  開啟鍵盤,並設定鍵盤對映。

ata0

  設定硬體相關。

# 開頭的行

  表示是註釋。

其他

  當然上述部分並不能保證一個核心正常啟動,後續還需要進行新增,剩餘所需到後面用到再說。

使用 Bochs

  設定完畢後,我們在組態檔位置開啟終端,輸入以下指令:

bochs -f ./bochsrc.disk

  這行命令就是呼叫我們的虛擬機器器使用bochsrc.disk載入。當然,你可以直接輸入bochs,然後回車,你會看到如下介面:

  可以看到如下幾個選項,預設選項是2,也就是從組態檔進行載入,我們需要輸入檔案路徑,作用和bochs -f ./bochsrc.disk一樣。
  但每次學習的時候我們總不能現輸入這條指令吧,我們可以利用bash指令碼來減輕鍵盤的負擔。我們在組態檔目錄下新建一個檔案startLearning.sh,輸入如下指令:

#!/usr/bin/env bash

bochs -f ./bochsrc.disk

  然後儲存,賦予可執行許可權。以後我們要使用該環境進行學習的話,只需雙擊該指令碼就可以了。下面我們來雙擊測試一下:

  可以看到預設選項是開始模擬,直接回車即可:

  你會看到兩個表單,小的是虛擬機器器的顯示視窗,類似螢幕;大的是偵錯表單,我們可以在這裡進行偵錯操作。
  如果我們點選偵錯表單的Continue按鈕,你會看到如下彈窗:

  這個是正常現象,因為還沒有對應的映象,那麼我們建立一個。作為一個負責任的模擬器,Bochs給咱們提供了建立虛擬硬碟的工具bximage,這裡簡單介紹幾個引數:

  • -fd:建立軟碟
  • -hd:建立硬碟
  • -mode:建立硬碟的型別,有flatsparsegrowing三種
  • -size:指建立多大的硬碟,以MB為單位。
  • -q:以靜默模式建立,建立過程中不會和使用者互動。

  下面我們來開始操作了,在組態檔所在目錄輸入以下指令:

bximage -hd -mode="flat" -size=60 -q test.img

  然後我們就成功建立了一個啟動映象,下面我們把它新增到組態檔中。在ata0的下一行,新增一行內容,效果如下:

ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="test.img", mode=flat, cylinders=121 ,heads=16 ,spt=63

  儲存,執行指令碼檢視。不出意外的話,還是報錯:

  這此報錯說是不是一個啟動盤,和之前無啟動裝置不一樣了。不要灰心,這個時候說明學習環境已成功搭建完畢,至於什麼是啟動盤,啟動流程是啥將會在下一篇進行介紹。

練習與思考

  俗話說得好,光說不練假把式,如下是本節相關的練習。如果練習沒做成功,就不要看下一節教學了。

  1. 搭建Bochs環境並取得成功。

下一篇

  羽夏看Linux核心——啟動那些事