BUAA OS實驗環境配置指南-2020年版[2020.5.22更新]

更新內容

2020.5.22 v1.1

對gxemul編譯好之後手動安裝的命令進行了修改,且增加了Win上CLion SSH連接虛擬機的教程。

前言

時至2020年,實驗指導書上的配環境方法有一部分已經不能使用,網上的資料很多也過時了。筆者踩了無數坑終於把OS環境配置好了,爲了避免後人繼續踩坑,故將配置經驗分享出來。本文主要是面向像筆者一樣的Linux新手。
本文也許也會在未來的某一天過時,因此讀者閱讀時,請注意本文的發佈時間。
由於筆者水平有限,文中提到的一些解決方案可能是繞了彎路的,如果讀者有更好的方案,歡迎聯繫筆者。如果文中有錯誤,也懇請指正。
爲了照顧不同讀者的閱讀需求,筆者將本文中的教程部分與筆者的所思所想、所做所爲分開,只想閱讀教程的讀者僅需閱讀第三部分“完整配置教程”即可

爲什麼要配環境?

筆者寫本文時,本學期的OS正處於Lab5的第二週。據說,Lab4是最難的,而Lab5簡單很多。爲什麼最難的部分都熬過來了,卻要在這樣一個時間相對緊張的時候配環境呢?

實際上,筆者配置環境不是爲了Lab5和Lab6,而是爲了挑戰性任務。筆者本學期的OS工具經歷瞭如下的發展過程。

最開始完全在Jupyter裏直接寫代碼、編譯、調試、提交,但是Jupyter有屏幕小、無圖形界面、連接不穩定等諸多不便之處,對筆者而言最大的不便是隻能用vim,不能用自己用的順手的IDE(筆者由於自身水平不足,不太會配置vim)。因此,當筆者得知可以將代碼從Jupyter中下載到本地編寫,再上傳到Jupyter中後,筆者果斷放棄了在Jupyter中寫,從此進入第二階段——下載到本地用IDE寫,完後上傳回Jupyter進行調試。

這一階段對於效率的提升是顯著的,到後面幾次Lab,常常是反覆在幾十個文件之間進行切換。即使在Clion中開滿了標籤頁,筆者依然覺得標籤頁數不夠用,如果仍然在Jupyter中寫,是什麼樣的體驗可想而知。

但是這一階段仍然有不足。筆者一直使用win系統,儘管可以用本地強大的IDE寫代碼,卻無法編譯和運行,因此調試工作仍然只能在Jupyter中進行,調試階段在數十個文件之間切換依然不可避免,效率依然有待提高。

挑戰性任務更加複雜,需要大量的調試,還需要自己構造測試數據。隨着挑戰性任務的發佈,筆者更加覺得需要配置一個可以編寫、編譯、調試的閉環環境,實現除了提交以外的環節完全擺脫對Jupyter的依賴,從而將大屏、圖形界面、自由分屏等優勢運用到每個環節中,提高效率。因此,筆者下定決心配置一套完整的環境。

配置環境過程中的嘗試

筆者首先想到的是把學期初助教Ausar分享的已經配置好的環境拿過來用,但是面臨的第一個難關就是VirtualBox始終無法打開鏡像,一直報錯0x80004005。搜索錯誤代碼,按其中的指示進行處理依然無果,考慮到可能是助教給的環境掛載了一些本機沒有的鏡像導致無法啓動,於是暫時擱置。

接下來筆者考慮的是WSL,筆者的想法是:WSL畢竟是微軟官方出的,穩定性肯定比VirtualBox有保障。由於筆者的電腦版本爲1909,不能安裝WSL2,於是就去安裝WSL1。

安裝好WSL後,筆者一邊蒐集安裝GUI的方案,一邊嘗試安裝ELDK交叉編譯器。費了很大一番功夫終於把iso的鏡像掛載上之後,輸入安裝命令,卻報瞭如下的錯:

$ sudo ./install  -d /OSLAB/compiler/
[sudo] password for brooks:
./install: 1: ./install: Syntax error: "(" unexpected

這樣的錯讓筆者完全摸不着頭腦,查閱資料後,發現可能原因是WSL1沒有完整的Linux內核。另外從查閱的資料看來,在WSL上安裝圖形界面似乎也是件費力不討好的事情,於是放棄WSL。

回到虛擬機方案,筆者高中時期爲了OI曾經用VirtualBox裝過Ubuntu,查閱資料後發現可能是這個VirtualBox版本過老,即使更新了也和舊的文件有衝突,因此筆者卸載並重裝了最新版。儘管依然報錯,但是報錯的內容變成了找不到gxemul安裝包的鏡像,並且把預期的文件地址展示了出來。因此筆者將gxemul安裝包放到指定位置後,終於打開了Ubuntu 12.04的鏡像。

但是這個鏡像沒有GUI,筆者查閱資料後使用sudo apt-get ubuntu-desktop(並經過漫長的等待)安裝上了GUI,這才終於有一個能看的圖形界面。

由於給出的環境中ELDK編譯器的安裝路徑與筆者的代碼中使用的編譯器路徑不同,於是筆者另外安裝了一份ELDK編譯器到/OSLAB/compiler。此次安裝總體上比較順利。測試了一下make和gxemul,現象均和Jupyter平臺上一致。另外還安裝了Clion,整個實驗環境基本達到了筆者理想的程度。

但是不足的是筆者始終無法在這個環境中開啓VirtualBox的無縫模式,而環境自帶的分辨率又無法充分使用筆者的屏幕空間。反覆嘗試安裝增強功能,不起效。查閱資料後筆者認爲可能是Ubuntu官方的Unity桌面的兼容性存在問題,於是下載了GNOME桌面並刪除了Unity桌面。但是重啓後依然無法開啓無縫模式。於是筆者放棄了開啓無縫模式的想法。

悲劇意外的發生了。筆者打開了Clion,試着打開了幾份代碼,感覺稍稍有點卡,認爲可能是給虛擬機設置的配置過低。於是關掉虛擬機,內存從1024MB增加到2048MB,CPU從1核增加到2核,再次啓動。

結果悲劇了。環境卡在啓動時的命令界面,多次嘗試,均無法啓動系統。後來即使是把增強了的配置改回去,也依然無法啓動,筆者只好放棄Ubuntu12.04。

考慮到前面的嘗試已經給在Ubuntu上配置環境積累了一定的經驗,於是筆者決定索性安裝比較新版本的Ubuntu試試,理論上只要工具鏈的版本和Jupyter一致,代碼的運行結果就是一樣的。於是筆者開始安裝Ubuntu18.04。

在18.04上,筆者首先安裝ELDK編譯器,但是無論如何改權限、換安裝目錄,運行安裝命令後都會出錯,報錯大概內容爲sh: /opt/eldk/bin/rpm: not found。查閱資料後發現引起問題的原因是ELDK是32位軟件,而筆者使用的是64位Ubuntu,不兼容。官方給出的解決方案是運行sudo apt-get install ia32-libs,但是我運行這句指令,卻提示我找不到這個包。

繼續查資料,找到真正了有用的解決方案,終於把ELDK安裝好了。

接下來安裝gxemul,這個安裝包更特殊。ELDK是編譯好了現成的程序,只要運行安裝程序即可,而gxemul的安裝包裏只有源代碼,需要自己編譯後把編譯出的程序放到指定位置。筆者按照教程的步驟安裝,但是總是會在編譯到最後一步進行連接的時候出錯。

筆者搜索gxemul的安裝,排在搜索結果首位的居然是BUAA OS 2014年的一份課件,內容大致是環境配置教學,但是內容過時而無法使用。往下翻,找到一位同樣在配置OS環境的同學的博客,這位同學也遇到了同樣的問題,make到最後會報錯如下(或者是意思相同的中文報錯):

cc -fstrict-aliasing -fomit-frame-pointer -fpeephole -O3 -DNDEBUG  src/*.o src/cpus/*.o src/debugger/*.o src/devices/*.o src/disk/*.o src/file/*.o src/machines/*.o src/native/*.o src/net/*.o src/promemul/*.o src/useremul/*.o  -lm  -o gxemul
src/devices/dev_sgi_ip32.o: In function `__cmsg_nxthdr':
dev_sgi_ip32.c:(.text+0x1d60): multiple definition of `__cmsg_nxthdr'
src/emul.o:emul.c:(.text+0x10): first defined here
src/devices/dev_sgi_ip32.o: In function `recv':
dev_sgi_ip32.c:(.text+0x1db0): multiple definition of `recv'
src/emul.o:emul.c:(.text+0x60): first defined here
src/devices/dev_sgi_ip32.o: In function `recvfrom':
dev_sgi_ip32.c:(.text+0x1dc0): multiple definition of `recvfrom'
src/emul.o:emul.c:(.text+0x70): first defined here
src/machines/machine_sgi.o: In function `__cmsg_nxthdr':
machine_sgi.c:(.text+0xaf0): multiple definition of `__cmsg_nxthdr'
src/emul.o:emul.c:(.text+0x10): first defined here
src/machines/machine_sgi.o: In function `recv':
machine_sgi.c:(.text+0xb40): multiple definition of `recv'
src/emul.o:emul.c:(.text+0x60): first defined here
src/machines/machine_sgi.o: In function `recvfrom':
machine_sgi.c:(.text+0xb50): multiple definition of `recvfrom'
src/emul.o:emul.c:(.text+0x70): first defined here
collect2: error: ld returned 1 exit status
Makefile:28: recipe for target 'build' failed
make: *** [build] Error 1

筆者嘗試了4.6、4.7還有許多從這兩個大版本衍生出的小版本如4.6.1、4.7.1等,嘗試了多種CFLAGS設置,無一例外的失敗了,報錯內容基本一樣。筆者又下載了6.0版本,使用g++終於編譯成功了。然而嘗試使用gxemul -E testmips -C R3000 -M 64 gxemul/vmlinux命令,又會提示非法參數。筆者嘗試使用sudo apt-get install gxemul安裝gxemul,提示沒有這個包。

上網蒐集gxemul安裝錯誤的解決方案,搜到的有關gxemul的資料都很少,解決問題的資料更是根本沒有。無奈之下向助教求助,助教說應該使用gcc-4.8或gcc-4.9。

筆者輸入命令gcc --version,發現筆者的gcc版本爲7.5.0。於是又去搜集安裝低版本gcc的方案(讀者莫笑,筆者作爲幾乎沒用過linux的人,並不知道怎麼用apt-get裝低版本的軟件)。考慮到之前安裝某些過於老的軟件就會提示沒有這個包,因此筆者決定安裝gcc-4.9,結果輸入命令sudo apt-get install gcc-4.9後又提示沒有這個包。

筆者想當然的以爲,既然gcc-4.9都沒有了,那gcc-4.8更不可能有。於是繼續找別的安裝方法。出乎意料的是,筆者找到一個提問,回答的人讓安裝gcc-4.8,筆者嘗試使用sudo apt-get install gcc-4.8,果然成功。

於是,在重新設置CC變量後,筆者終於把gxemul 4.6編譯成功了。本地測試了下make和gxemul -E testmips -C R3000 -M 64 gxemul/vmlinux,獲得了和Jupyter一樣的實驗現象。

至此,OS環境配置終於成功。

完整配置教程

筆者由於主力使用Win,且配置的環境只打算使用到課程結束,對性能要求不高,故選擇虛擬機方案。想要長期使用Linux的同學可以自行將安裝虛擬機的部分換成安裝真實系統。

準備工作

ELDK編譯器,版本爲mips-linux-x86 4.1。指導書和官方文檔中給出的下載鏈接在筆者寫本文時已失效。

gxemul仿真器,版本爲4.6,官方下載鏈接爲http://gavare.se/gxemul/src/。注意不能下載6.x版本,不兼容(上面有講不兼容的表現)。

Ubuntu系統鏡像,直接去官方下載即可,理論上只要ELDK、gxemul版本和課程組一致,無所謂使用哪一版本的Ubuntu。出於穩定性和功能豐富的考慮,筆者使用18.04LTS版。

VirtualBox,去官網下載最新版的platform package即可,可順帶下載extension pack。

由於ELDK和gxemul發佈較早,且ELDK下載鏈接已失效,故筆者分享在此,希望拿到資源的同學可以保持分享。

百度網盤:https://pan.baidu.com/s/1OAM3t7-vKA17jP8TgU-iVA
提取碼:tq05

北航雲盤:https://bhpan.buaa.edu.cn:443/link/0CAD4CD3D9921271D9517306198FE075 有效期限:2022-06-30 23:59 訪問密碼:1sOF

安裝虛擬機

虛擬機的安裝不是本文的重點,故分享一篇筆者認爲不錯的教程

筆者建議讀者按照此教程完成Ubuntu虛擬機的安裝,在此分享一些筆者使用的設置,供讀者參考。

  • 內存2048MB
  • 硬盤10GB,在筆者配置完環境、安裝好CLion後,還剩餘600M,足夠寫OS代碼
  • CPU雙核,啓用PAE/NX

此外,筆者建議按教程中的指示更換升級源,提高下載速度。

筆者建議在打開虛擬機之後安裝增強功能,這樣就可以開啓無縫模式、雙向共享粘貼板。

關於主機與虛擬機之間的文件共享,筆者建議通過VirtualBox共享文件夾的方式實現。筆者對共享文件夾設置了自動掛載,並按照資料的方法二將筆者的用戶名加入了vboxsf組,解決了自動掛載的權限問題。這樣共享的文件夾可以很方便的雙向傳文件,且對文件的改變實時生效,無需重啓Ubuntu。

在Ubuntu中,指令前如果加了sudo表示Super User DO,即以超級用戶權限執行。如果讀者不想每次sudo都要輸入密碼,也可以進行設置,輸入sudo visudo,在最後一行加入username ALL=(ALL) NOPASSWD: ALL即可(username需要替換爲自己設置的用戶名)

Ubuntu中開啓終端的快捷鍵是Ctrl+Alt+T

安裝ELDK編譯器

64位系統的準備工作

如果讀者使用的是64位的Ubuntu,還需要做一些額外的操作。

方案一是按照指導書中所述,使用sudo apt-get install ia32-libs安裝32位運行庫。但是筆者使用該方案時,提示找不到包。

方案二來自網絡,具體操作爲依次運行如下三條命令,其中:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386

如果不進行上述操作,可能會在安裝時報類似這樣的錯sh: /opt/eldk/bin/rpm: not found

正式安裝

ELDK編譯器的安裝包是名爲mips-2007-01-21.iso的鏡像,在傳到虛擬機中後,雙擊使用歸檔管理器打開即可當作壓縮包打開,首先將其解壓到目錄A(A代表一個路徑,具體在哪由讀者自行決定,只要有權限訪問且讀者記住該目錄即可,下文的B、C等同理)。A下面的readme.html有ELDK的安裝和使用指南。

接下來是決定安裝目錄,有兩種可能的目錄,具體是哪一種取決於讀者的Lab1.1是怎麼做的。筆者當時是在include.mk裏的CROSS_COMPILE的路徑前加上了/OSLAB/compiler,因此筆者的安裝路徑應當爲/OSLAB/compiler/,但也可能有讀者應當安裝在/opt/eldk/。記安裝路徑爲B。

安裝之前要創建安裝目錄,使用命令sudo mkdir B。如果提示目錄不存在,就一級一級創建文件夾。如筆者實際使用了兩條命令:

sudo mkdir /OSLAB
sudo mkdir /OSLAB/compiler

接下來進行安裝,使用命令sudo ./A/install -d B(需自行將A、B替換爲對應的目錄),其中-d B是安裝程序install的一個參數,表示指定安裝目錄爲B,如果沒有這個參數,就會默認安裝到目錄A。

在安裝過程中,可能會有報錯提示Failed to stat ~/.gvsf或類似的內容,可以忽視,不會影響安裝。

安裝完成後,輸入命令A/usr/bin/mips_4KC-gcc --version,如果輸出類似如下的內容,則說明安裝成功。

jovyan@jovyan-VirtualBox:~$ /OSLAB/compiler/usr/bin/mips_4KC-gcc --version

mips_4KC-gcc (GCC) 4.0.0 (DENX ELDK 4.1 4.0.0)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

安裝gxemul

小小的準備工作

安裝前,需要先安裝gcc-4.8或gcc-4.9。以4.8爲例,使用命令sudo apt-get install gcc-4.8即可。

如果安裝4.9時提示找不到包,就試試安裝4.8。筆者就是遇到這樣的情況,最終安裝了4.8。

此外,如果之前沒有安裝過make,則無法通過make命令對gxemul進行編譯,需要預先使用sudo apt-get install make安裝make。

正式安裝

假設gxemul的安裝包gxemul-0.4.6.tar.gz在目錄C下,進入目錄C後輸入命令tar -zxvf gxemul-0.4.6.tar.gz進行解壓。

進入gxemul-0.4.6文件夾,其中README是使用說明。先輸入export CC=gcc-4.8,表示在當前終端中設置CC環境變量爲gcc-4.8(如果之前沒有設置過CFLAGS,則無需設置CFLAGS)。設置之後可以輸入env查看所有環境變量的值,查看CC變量是否設置成功。然後輸入./configure

接下來輸入make進行編譯,編譯過程需要花幾分鐘時間。編譯完成後輸入以下指令進行手動安裝(命令來自6.x版本的gxemul的Makefile文件,實際上也就是把程序和文檔複製到對應的地方,卸載則是把這些文件刪除即可)。

#程序
sudo mkdir -p /usr/bin
sudo cp -f gxemul /usr/bin/
#文檔,可不復制
sudo mkdir -p /usr/share/man/man1
sudo cp -f man/gxemul.1 /usr/share/man/man1/
sudo mkdir -p /usr/share/doc/gxemul
sudo cp -R doc/* /usr/share/doc/gxemul/

安裝完成後,輸入gxemul,如果出現類似如下的輸出,說明安裝成功。

GXemul 0.4.6    Copyright (C) 2003-2007  Anders Gavare
Read the source code and/or documentation for other Copyright messages.

usage: gxemul [machine, other, and general options] [file [...]]
   or  gxemul [general options] @configfile
   or  gxemul [userland, other, and general options] file [args ...]

Run  gxemul -h  for help on command line options.

No filename given. Aborting.

安裝CLion

筆者使用的IDE爲CLion,故在本文中簡單介紹一下CLion的安裝。

首先從官網下載格式爲tar.gz的安裝包,解壓,其目錄D下的install-Linux-tar.txt爲安裝教程。運行D/bin/clion.sh,會將CLion安裝在目錄D中並初始化。之後的初始化步驟和win版基本相同。以後開啓CLion時,依然是運行D/bin/clion.sh。如果安裝時忘了創建快捷方式,後面依然可以創建快捷方式。編譯器調試器等可以不配置或者使用默認配置,因爲據筆者所知目前無法在IDE內直接使用ELDK編譯器編譯,還是要在代碼目錄下用make命令。

用Win上的CLion建立SSH連接

筆者在使用Ubuntu上的CLion的時候還是或多或少感到些卡頓,因此後來換了一種方案,即用Win上的CLion SSH連接到虛擬機,在Win上寫代碼,寫好後自動上傳到虛擬機,然後即可在虛擬機上編譯、運行。這樣就和用虛擬機裏的CLion寫代碼一樣了,唯一的區別是,在真機上的CLion操作更順暢。
關於如何利用CLion建立SSH,建議參考官方文檔
建立的SSH的類型是SFTP。SSH的關鍵是填寫好Host、Port等參數。首先選擇Host即爲虛擬機IPV4的ip地址,獲取的辦法有兩種,一種是通過命令

sudo apt-get install net-tools
ifconfig -a

在這裏插入圖片描述
inet 後的即爲虛擬機的IPV4地址。

另一種是通過圖形界面的操作,在設置中查看網絡的詳細信息,可以看到ip地址(IPV4)
在這裏插入圖片描述
將IPV4地址填入Host,Port使用默認,用戶名填寫自己登錄Ubuntu的用戶名,驗證類型選密碼,密碼填登錄Ubuntu的密碼,剩下的項目按照文檔填寫即可(如果文檔中沒講,就使用默認或者Autodetect)。工具鏈的配置不用管,因爲CLion並不支持OS的工具鏈,配置了也沒用。
建立好SSH後,可以在Tools-Deployment中勾選Automatic upload,這樣只要保證虛擬機開機,寫好代碼後按下Ctrl+S,就會自動上傳代碼到虛擬機,切換到虛擬機後即可直接編譯與運行。
CLion的缺點是目前對Makefile項目的支持不友好,不支持跨文件夾文件的跳轉等功能,因此對於OS只能當文本編輯器來用。筆者找了一些建立Makefile項目的教程(如compiledb、bear等工具生成json),嘗試後效果都不理想。不過,即使如此,一個可以在多個文件間自由切換、提供同文件夾內文件跳轉的文本編輯器,依然比默認的vim要好用太多。至少make的時候不用把代碼關掉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章