項目信息
項目名稱:龍芯2K上的RT-Thread系統
學生姓名:李志銳
學校:聊城大學
方案描述:該項目要求首先實現RT-Thread項目到龍芯2K平臺上的MMU移植,并實現GMAC及SATA/SSD驅動,同時要對接FAT文件系統以及網絡協議棧。
時間規劃:
初衷
我從去年開始關注操作系統的領域,由于興趣的緣故,在去年11月自己研究學習了RISC-V架構并在以RocketChip為核心的K210芯片上重實現了,這也是我第一次在于系統內核保持近距離的情況下對內核進行研究學習,并因此獲得了對于包括上下文切換、系統調用過程等的較深的理解,同時也是第一次接觸支持MMU的非x86架構處理器,RISC-V給我的感覺就是:沒有x86架構繁瑣的分段機制(這是x86歷史原因造成的),同時其硬件頁表機制與現代操作系統契合度高。
今年4月,我了解到了RT-Thread,并提前上手試著將RT-Thread移植到了CK810架構的qemu虛擬機上,RT-Thread的源代碼整體而言給我的感受就是代碼風格的一致性,并且其注釋也比較豐富,同時有完善的文檔支持,這對我的移植起到了不小的輔助。在這次移植工作中,我第一次接觸了Scons,個人感覺相比Makefile,基于Python的Scons構建工具更加方便也更加靈活。
在完成了上述的移植工作后,我參與到了RT-Thread Smart到CK810架構的移植項目之中,RT-Thread Smart給我的感覺就是,相比于公開版的RT-Thread,其功能要強大的多,很多特性更逼近Linux,其強大的用戶態支持更是吸引了我。 今年6月,我獲知了中科院軟件所的開源軟件計劃,同時了解到RT-Thread社區在該計劃中擁有一個名為“龍芯2K上的RT-Thread系統”的項目,該項目要求實現公開版RT-Thread在龍芯2K平臺上對SATA/SSD驅動的支持,同時對接FAT文件系統,同時要對接網絡協議棧。同期我也參加了RT-Thread Smart到龍芯2K平臺的適配項目,即要實現MMU等相關特性的適配。
龍芯平臺對我而言比較陌生,之前我僅僅是聽說過龍芯的大名,而龍芯平臺所使用的mips指令集我也比較陌生,SATA控制器和GMAC更是從未接觸過,但是我比較喜歡有一定挑戰性的任務,同時對這些東西也比較有興趣,因此我就接下了。
過程
7月份,當我獲知我中選之后,我就正式開始了項目開發工作:首先我選擇先實現RT-Thread Smart的龍芯適配工作。一開始我剛拿到龍芯2K的開發板,就迫不及待地接上顯示器和鍵盤鼠標先上電看一看龍芯自己的Linux系統,結果一進桌面處理器就直接掉電復位。經過排查發現,我所用的電源適配器和供電線都不達標,最終去買了一個比較好的適配器和一根比較粗的供電線之后,成功將龍芯Linux啟動了起來。
我在閱讀了龍芯教育派的使用手冊之后,了解到龍芯啟動時先啟動pmon,再由pmon引導SSD中的系統,pmon比較類似于現代PC機的bios。緊接著我就考慮該如何調試RT-Thread,在翻閱了pmon的相關說明文檔中之后,我了解到pmon支持tftp引導啟動,因此我進入pmon的配置程序,設置了默認的網卡參數,同時在我的PC機上配置了tftp服務端,在路由器中將PC機的IP固定下來,然后進入龍芯Linux,修改了boot.cfg,加入了tftp的啟動引導選項,并設為默認啟動項。
緊接著,我在Windows下配置了完整的編譯工具鏈,并利用Vmware配置了一臺裝有Ubuntu16.04 x64的虛擬機,在虛擬機中編譯安裝龍芯2K的qemu著實花了我一天時間,不過最終成功完成了配置工作,由于RT-Thread的公開版已經完成了龍芯2K的基本適配工作,因此我將該鏡像進行編譯同時利用該鏡像測試了qemu,一切正常。
由于我平時在Windows下利用VSCode開發,在Linux下利用qemu仿真調試RT-Thread,各種命令比較多,敲起來也比較復雜,因此將Windows下的RT-Thread鏡像輸出目錄映射到了虛擬機內,我在Linux利用Python開發了一個qemu監控端,同時在Windows下利用C#開發了一個控制Linux下qemu監控端的客戶端程序,利用該客戶端程序,可以實現內核一鍵編譯、一鍵啟動gdb仿真(即首先通知Linux下的qemu監控程序啟動qemu,然后在Windows下啟動gdb并自動建立連接,在入口點斷下,然后可以自動執行預先在文本框中設置好的一系列調試命令)。
由于musl libc庫的mips64的系統調用接口和crt接口已經預先被配置好,因此我直接對libc庫進行了編譯,然后對用戶程序進行了編譯,并生成了ROM,我在RT-Thread Smart將公開版的龍芯2K啟動代碼、上下文切換代碼、中斷控制器代碼和串口控制器代碼先移植了進去,花了一點時間通過了編譯,然后利用qemu進行調試,形成了初步的程序框架,然后在main.c中構建了一些mmu的測試用例,對龍芯2K的MMU展開了一系列測試,并最終完成了全部測試工作。
形成了mips_mmu.c/.h,緊接著我開始試著啟動hello.elf程序,發現系統無反應,經過跟蹤發現,RT-Thread Smart默認使用的ELF32模型,我將其改成了ELF64模型,同時對接了內核syscall接口,也對接了lwp用戶態的相關接口,為每個線程創建了獨立的異常棧和系統調用棧,同時在上下文切換代碼中實現了頁表的切換,并最終實現了hello world的輸出。
我在調試ping/pong程序的時候,發現龍芯2K的qemu源代碼中存在一個BUG:Config4寄存器未初始化導致無法使用KScratch1/2寄存器,我將其修正并進行了提交,最終ping/pong程序也調試通過。
實現signal支持我花了比較長的時間,這也是第一次接觸signal這個概念——用戶態模擬的中斷,在進入用戶態的信號處理程序之前,我將上下文保存在了用戶上下文中,由于這涉及到用戶態虛擬地址的訪問,在上下文保存過程中可能會發生tlb miss從而導致epc被毀,因此這里我也做了特殊處理,最終usersignal.elf也測試通過,在usersignal.elf的調試過程中,我還遇到了一個問題:線程執行的時候堆棧錯誤,最終獲知我要在用戶態的線程創建syscall中為線程獨立分配堆棧,同時要在線程堆棧中放置一段讓線程退出的trap代碼,將lr指向這里,從而讓線程執行時擁有獨立堆棧并在執行完后順利返回系統并清理線程運行環境。
在上述工作全部完成后,我開始嘗試在實機運行,結果一運行用戶程序就報錯了,經過詢問龍芯相關技術人員得知,由于Cache重影的問題,龍芯不支持4K頁,最少要使用16K頁,于是我花了一晚上進行修改,并在第二天實現了實機的完美運行,此時已經到了7月25日。然后我在公開版的RT-Thread中加入了一條mmu_test命令,并放置了一個簡單的mmu測試用例,提交到了點亮計劃提供的gitlab中。
然后我開始實現RT-Thread公開版上gmac驅動和lwip協議棧的適配,這部分工作必須完全在實機上完成,而我從龍芯手冊上只發現了GMAC的PCI頭,經過一些資料的閱讀,我對PCI總線有了基本的認識,獲取到了BAR,經過多方打聽和實驗,我獲知龍芯2K1000采用的GMAC是Synopsys的標準核,于是我下載了Synopsys Ethernet 3.50a版本的手冊,進行了閱讀,了解到gmac是一種數據鏈路層的器件,負責幀的收發,我根據手冊的寄存器說明讀出了龍芯2K1000的GMAC IP核的版本號,發現與手冊的版本差異不是太大。
于是我就按照手冊的要求開始進行調試,我將RT-Thread中ls1c的gmac驅動直接拷貝了過來,替換了寄存器起始地址,同時對接了一些Cache相關的接口,同時我選擇了lwip 2.0.2進行移植,由于驅動和lwip原先是在32位環境下工作,其中有大量硬編碼的地址類型轉換,因此出現了很多兼容性問題,我進行了逐一修改,終于,鏈路層握手成功,但是DHCP死活無法握手,我嘗試使用Wireshark進行抓包,也一無所獲,沒有獲取到任何數據包,我開始對照數據手冊分析DMA的發送列表和接收列表,發現其列表是連續環形方式構建的。
但是鏈表到處亂跳,根本不遵循手冊,經過幾天的調試我一無所獲,后來我獲知龍芯的GMAC的DMA也是通過Cache讀取內存,因此我就把一些Cache相關地址轉換功能去掉了,但是依然不工作,后來我偶爾在數據手冊中發現了Enhanced Descriptor,于是我將驅動程序轉為增強描述符運行模式,緊接著我就在wireshark中抓到了數據包,其發送列表和接收列表也完全正常工作了,我對細節進行一些調試后,DHCP就正常完成了握手工作,同時ping操作也可以正常執行了,經過長達10個小時的ping命令運行,證明其可以正常工作,這部分工作我在8月11日成功完成。
緊接著我撰寫了中期報告并通過了中期考核,緊接著我開始寫SATA控制器驅動,這部分比較順利,我閱讀了Synopsys的標準AHSATA控制器的手冊,發現其和龍芯2K的寄存器定義完全一致,由此證明其使用的又是Synopsys的標準IP核,然后我將uboot的AHSATA驅動移植了過來,在移植過程中,我注意到其中有大量的源代碼文件,經過篩選,我逐漸知道了AHSATA和SATA并不是一種東西AHSATA指的是AHCI + SATA,獲得了正確的驅動后,讀出了AHSATA控制器的BAR并替換進源代碼,同時處理好64位運行環境的兼容問題后,SSD的MBR就被我完整讀出了。
原定計劃是移植FAT文件系統,但是我注意到龍芯2K的pmon依賴Linux根文件系統下的boot.cfg引導文件,并且其中的龍芯Linux也不想破壞掉,因此最終改為移植lwext4,其支持ext2/3/4文件系統,其移植過程比較順利,同時我還加入了mbr的解析支持,從而支持了多分區掛載,最終在8月19日,我完成了全部的工作,并于后來撰寫了結題報告,通過了結題考核。
心得體會
本次項目我提前一個半月完成,整體而言,經歷了這次項目,我獲得了大量操作系統方面的相關開發經驗,接觸到了signal機制,同時理解了GMAC與SATA控制器,對之前所學的大量知識有了更深入的理解,最重要的是,我也獲得了一些閱讀他人代碼和大型工程代碼的經驗,也結識了很多圈子內的大佬,獲得了更多的機會,同時也獲得了更多操作系統方面的最新和最前沿信息。
對RT-Thread的感受
首先,相較于傳統的RTOS,公開版RT-Thread提供了更豐富的調度機制、組件機制以及驅動模型,其次,RT-Thread Smart提供了更完整的用戶態支持,同時與傳統的RTOS最大的不同在于,可以加載來自文件系統中的elf文件,我認為,若加入網絡文件系統支持,便可以執行存儲于網絡中來自任意一臺嵌入式設備中的可執行文件,這種高度自由的特性非常適應如今的物聯網場景。我認為RT-Thread屬于類Unix系統。
其高度可定制化的特性、對多平臺的兼容性以及對硬件的低要求,促使其可以快速地適應多種應用場合,并快速切入市場,同時也是一個比較成型的國產操作系統,讓國家的國產化進程更向前了一步,比較適合IoT領域,甚至有切入智能手持設備和桌面平臺的潛力,整體而言,這是一個極具發展潛力的國產操作系統,我比較看好其未來的發展趨勢。
責任編輯:xj
原文標題:經驗分享|在龍芯2K上運行RT-Thread系統并開源
文章出處:【微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。
-
龍芯
+關注
關注
3文章
333瀏覽量
31215 -
開源
+關注
關注
3文章
3256瀏覽量
42420 -
RT-Thread
+關注
關注
31文章
1274瀏覽量
39942
原文標題:經驗分享|在龍芯2K上運行RT-Thread系統并開源
文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論