@(hv6是Hyperkernel: Push-Button Verification of an OS Kernel中設計的一款操做系統,用這款操做系統實驗了一種新的驗證內核的方法,具體請查看這篇論文:Hyperkernel: Push-Button Verification of an OS Kernel)前端
Linux Ubuntu 17.10
Binutils 2.29.1
GCC 7.2.0
QEMU 2.10.1node
tar -xvf make&make install
gcc默認是編譯c89,可是c89不支持explict
關鍵字,因此在make
生成Makefile以後,須要修改Makefile中的-std=c89
爲-std=c99
python
undefined reference to 'static_assert'
錯
[tianchiliu@localhost hv6]$ make GEN o.x86_64/hv6/user/fs/mkfs /tmp/ccfyijTc.o: In function `main': mkfs.c:(.text+0xad): undefined reference to `static_assert' collect2: error: ld returned 1 exit status make: *** [o.x86_64/hv6/user/fs/mkfs] Error 1
make qemu
會出現以下錯誤qemu/target/i386/kvm.c:1849: kvm_put_msrs: Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed.
QEMUOPTS += -cpu host,pmu=off
QEMUOPTS += -cpu host,pmu=off
不能在QEMUOPTS += -M q35,accel=$(QEMU_ACCEL),kernel-irqchip=split -cpu $(QEMU_CPU)
上面,QEMU := qemu-system-$(ARCH)<br> QEMUOPTS += -M q35,accel=$(QEMU_ACCEL),kernel-irqchip=split -cpu $(QEMU_CPU)<br> QEMUOPTS += -cpu host,pmu=off <br> QEMUOPTS += -serial mon:stdio -s<br> QEMUOPTS += -display $(QEMU_DISPLAY)<br> QEMUOPTS += -smp cpus=$(NR_CPUS)<br> QEMUOPTS += -device isa-debug-exit QEMUOPTS += -debugcon file:/dev/stdout QEMUOPTS += -netdev user,id=net0,hostfwd=tcp::10007-:7,hostfwd=tcp::10080-:80,hostfwd=tcp::5900-:5900<br> QEMUOPTS += -device $(QEMU_NIC),netdev=net0 -object filter-dump,id=filter0,netdev=net0,file=$(O)/qemu.pcap<br> QEMUOPTS += -device $(IOMMU),intremap=on<br>
繼續make qemu
出現以下錯誤linux
[ 12.576076] kernel panic: hvm: no svm/vmx解決方法:
開啓kvm的虛擬化嵌套
,宿主機開啓虛擬化加上VMware勾選虛擬化只是支持VMware中的系統虛擬化,在qemu中運行系統就須要虛擬化嵌套了。參考連接
[tianchiliu@localhost hv6]$ cat /sys/module/kvm_intel/parameters/nested N
[root@localhost hv6]# modprobe -r kvm-intel [root@localhost hv6]# modprobe kvm-intel nested=1 [root@localhost hv6]# cat /sys/module/kvm_intel/parameters/nested Y
-- 最後make&make qemu
,運行成功了!c++
fs: use memfs fs: size 1000 nblocks 904 ninodes 4000 nlog 30 ns: waiting for link to come up ns: link up at 1000 Mb/s full-duplex ns: MAC address in EEPROM ns: ether 52:54:00:12:34:56 ns: no caplist ns: dhcp initializing ns: inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.2 init: starting httpd init: starting vncd init: starting sh httpd: waiting for http connections... vncd: 1322 8x16 glyphs vncd: waiting for vnc connections... $
http://localhost:5900/sh.html.
vncd: client connected from 10.0.2.2 vncd: client version GET /sh.html
Linux Ubuntu 17.10 LLVM 5.0.0 Z3 4.5.0 Python 2.7.10
安裝了不少軟件後,VMware提示容量不足,下面進行:git
VMware擴容
:[root@localhost] fdisk /dev/sda p 查看已分區數量(我看到有兩個 /dev/sda1 /dev/sda2) n 新增長一個分區 p 分區類型咱們選擇爲主分區 分區號選3(由於1,2已經用過了,見上) 回車 默認(起始扇區) 回車 默認(結束扇區) t 修改分區類型 選分區3 8e 修改成LVM(8e就是LVM) w 寫分區表 q 完成,退出fdisk命令
<tab><tab> 使用`partprobe` 命令 或者重啓機器
mkfs.xfs /dev/sda3 #因爲centos7默認是xfs系統,因此我選擇了mkfs.xfs
lvm 進入lvm管理 lvm>pvcreate /dev/sda3 這是初始化剛纔的分區,必須的 lvm>vgextend cl /dev/sda3 將初始化過的分區加入到虛擬卷組centos (卷和卷組的命令能夠經過 vgdisplay ) #cl是可經過vgdisplay查看,即第一行vg name lvm>vgdisplay -v lvm>lvextend -l+768 /dev/mapper/centos-root 擴展已有卷的容量(768是經過vgdisplay查看的free的大小)我增長了3G lvm>pvdisplay 查看卷容量,這時你會看到一個很大的捲了 lvm>quit 退出
以上只是卷擴容了,下面是文件系統的真正擴容
CentOS 7 下面 因爲使用的是 XFS,因此要用:
xfs_growfs /dev/mapper/cl-root
CentOS 6 下面 要用:
resize2fs /dev/mapper/cl-root
github
df -h
獲得]git clone https://github.com/Z3Prover/z3.git cd z3 python scripts/mk_make.py cd build make sudo make install
參考連接
bootstrap
cmake
LLVM 5.0.0
不支持./configure&make
,須要安裝cmake
,故安裝cmake:
參考連接1
由於參考連接1中./configure
時報錯沒法解決,
遂使用下面./bootstrap
方法
參考連接2
./bootstrap
提示glibc沒有GLIBCXX_3.4.21
或更高版本centos
[root@localhost cmake-2.8.12.2] strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX咱們看到當前GCC版本中的確沒有GLIBCXX_3.4.15,考慮到剛安裝過新版的GCC,彷佛不該該出現這樣的問題。
[root@localhost cmake-2.8.12.2] strings /usr/local/lib64/libstdc++.so.6.0.24|grep GLIBCXX
@[libstdc++.so.6.0.24要去/usr/local/lib64/具體查看是否存在]
/usr/lib64/
[root@localhost cmake-2.8.12.2] cp /usr/local/lib64/libstdc++.so.6.0.20 /usr/lib64/ [root@localhost cmake-2.8.12.2] cd /usr/lib64/ [root@localhost lib64] rm -f libstdc++.so.6 [root@localhost lib64] ln -s libstdc++.so.6.0.20 libstdc++.so.6 [root@localhost lib64] ll libstdc* lrwxrwxrwx. 1 root root 19 5月 12 13:34 libstdc++.so.6 -> libstdc++.so.6.0.20 -rwxr-xr-x. 1 root root 987096 11月 22 02:08 libstdc++.so.6.0.13 -rwxr-xr-x. 1 root root 6700716 5月 12 13:33 libstdc++.so.6.0.20參考連接
./bootstrap gmake make installcmake基本命令格式爲:cmake (cmakelist所在目錄) (配置)
[root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/llvm-4.0.1.src.tar.xz [root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/cfe-4.0.1.src.tar.xz [root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/clang-tools-extra-4.0.1.src.tar.xz [root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/compiler-rt-4.0.1.src.tar.xz [root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/libcxx-4.0.1.src.tar.xz [root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/libcxxabi-4.0.1.src.tar.xz [root@typecodes ~]# wget -c http://releases.llvm.org/4.0.1/libunwind-4.0.1.src.tar.xz
[root@typecodes ~]# tar -xf llvm-4.0.1.src.tar.xz && mv -f llvm-4.0.1.src llvm && rm -rf llvm-4.0.1.src.tar.xz
[root@typecodes ~]# cd llvm/tools/ && mv ~/cfe-4.0.1.src.tar.xz . [root@typecodes tools]# tar -xf cfe-4.0.1.src.tar.xz && mv -f cfe-4.0.1.src clang && rm -rf cfe-4.0.1.src.tar.xz
[root@typecodes tools]# cd clang/tools/ && mv ~/clang-tools-extra-4.0.1.src.tar.xz . [root@typecodes tools]# tar -xf clang-tools-extra-4.0.1.src.tar.xz && mv -f clang-tools-extra-4.0.1.src extra && rm -rf clang-tools-extra-4.0.1.src.tar.xz
[root@typecodes tools]# cd ../../../projects/ && pwd /root/llvm/projects
[root@typecodes projects]# mv ~/compiler-rt-4.0.1.src.tar.xz . [root@typecodes projects]# tar -xf compiler-rt-4.0.1.src.tar.xz && mv -f compiler-rt-4.0.1.src compiler-rt && rm -rf compiler-rt-4.0.1.src.tar.xz
[root@typecodes projects]# mv ~/libcxx-4.0.1.src.tar.xz . [root@typecodes projects]# tar -xf libcxx-4.0.1.src.tar.xz && mv -f libcxx-4.0.1.src libcxx && rm -rf libcxx-4.0.1.src.tar.xz
[root@typecodes projects]# mv ~/libcxxabi-4.0.1.src.tar.xz . [root@typecodes projects]# tar -xf libcxxabi-4.0.1.src.tar.xz && mv -f libcxxabi-4.0.1.src libcxxabi && rm -rf libcxxabi-4.0.1.src.tar.xz
[root@typecodes projects]# mv ~/libunwind-4.0.1.src.tar.xz . [root@typecodes projects]# tar -xf libunwind-4.0.1.src.tar.xz && mv -f libunwind-4.0.1.src libunwind && rm -rf libunwind-4.0.1.src.tar.xz
建立CMake的編譯目錄:build
[root@typecodes projects]# cd ~/ && mkdir build && cd build/
[root@typecodes build]# cmake ../llvm -G "Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCLANG_DEFAULT_CXX_STDLIB=libc++ -DCMAKE_BUILD_TYPE="Release" ../llvm
cmake ../llvm
:找到cmakelist所在目錄make -j2
來編譯make -j4
或make -j8
由於只給虛擬機分配了3個處理器make
:使用單核編譯make -j[n]
:在同一時間並行編譯n個任務make -j
:不限制同一時間並行編譯的任務數make -j2
:通常雙核處理器使用make -j4
:4核處理器在4G內存、3核處理器
下,編譯LLVM用時5h
make install
- 安裝clang/clang++所須要的libc++庫 `make install-cxx install-cxxabi` - `make hv6-verify` :Runs the verification scripts for the hv6 kernel. This includes building the kernel into LLVM IR, translating the kernel to Python using Irpy, and invoking hv6/spec/main.py 出現以下錯誤:
irpy/compiler/PyLLVMEmitter.cc: In member function ‘void irpy::PyInstVisitor::visitSwitchInst(llvm::SwitchInst&)’:
irpy/compiler/PyLLVMEmitter.cc:546:49: error: passing ‘const llvm::SwitchInst::CaseIteratorT<llvm::SwitchInst, llvm::ConstantInt, llvm::BasicBlock>’ as ‘this’ argument discards qualifiers [-fpermissive]
``解決: 把 545行 for (
const `auto &c : i.cases()) 改成for (auto &c : i.cases()) {,即去掉const
分析:C++中,const 修飾的參數引用的對象,只能訪問該對象的const函數,由於調用其餘函數有可能會修改該對象的成員,編譯器爲了不該類事情發生,會認爲調用非const函數是錯誤的。
通常有三種解決方法:
編譯時加上-fpermissive忽略掉const可能引起的安全問題
make hv6-virify
[root@localhost hv6]# make hv6-verify C++ o.x86_64/irpy/compiler/PyLLVMEmitter.o C++ o.x86_64/irpy/compiler/irpy.o C++ irpy/compiler/irpy IRPY o.x86_64/hv6/hv6.py Parsing took 70 ms. Emitting took 24320 ms. PY2 hv6-verify Traceback (most recent call last): File "o.x86_64/hv6/hv6py/kernel/spec/main.py", line 23, in <module> import libirpy File "/home/tianchiliu/hv6/irpy/libirpy/__init__.py", line 17, in <module> from ctx import newctx, initctx File "/home/tianchiliu/hv6/irpy/libirpy/ctx.py", line 18, in <module> import util File "/home/tianchiliu/hv6/irpy/libirpy/util.py", line 20, in <module> import z3 ImportError: No module named z3
bin
目錄,要將bin
改成build
/usr/local/z3/build
vi ~/.bashrc export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/z3/build ldconfig
vi /etc/profile export PYTHONPATH=/usr/local/z3/build/python source /etc/profile參考連接
再次make hv6-verify
:
[root@localhost hv6]# make hv6-verify PY2 hv6-verify Using z3 v4.8.0.0 .....
4G內存,3核處理器
驗證用時20h時提示:
Traceback (most recent call last): File "o.x86_64/hv6/hv6py/kernel/spec/main.py", line 590, in setUp self.solver = Solver() File "/home/tianchiliu/hv6/irpy/libirpy/solver.py", line 58, in __init__ stdin=subprocess.PIPE, File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__ errread, errwrite) File "/usr/lib64/python2.7/subprocess.py", line 1224, in _execute_child self.pid = os.fork() OSError: [Errno 12] Cannot allocate memory
OSError: [Errno 12] Cannot allocate memory
:超過最大線程數cat /proc/sys/kernel/threads-max : 查看 echo 222222 > /proc/sys/kernel/threads-max 設置新的線程數
make irpy/test
: Runs the Irpy test suite, which compares symbolic execution results to running the C code directly.
cd irpy/o.test && python2 test.py Random seed: 5075005128484348075 .[param.7 = 2084980470, param.6 = 2143437557] In function irpy/test/add_overflow.c:test:24:14 ................. In function irpy/test/poison_cond.c:test:23:9 .........[i32 10, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 _1, i32 _1, i32 703] E...[param.140 = 0] In function irpy/test/zero_div.c:test:23:14 ERROR: test_switch_table (__main__.IRPyTest) Traceback (most recent call last): File "test.py", line 78, in <lambda> self._test(name, *args) File "test.py", line 150, in _test self._test_o(name + '_1', *args) File "test.py", line 136, in _test_o smt, symbolic_params = self._irpy(name, *args) File "test.py", line 123, in _irpy libirpy.initctx(ctx, module) File "/home/tianchiliu/hv6/irpy/o.test/libirpy/ctx.py", line 159, in initctx module._init_globals(ctx) File "/home/tianchiliu/hv6/irpy/o.test/switch_table_1.py", line 14, in _init_globals irpy.declare_global_constant(ctx,'@switch_table',itypes.parse_type(ctx,'[10 x i32]*'),irpy.constant_data_array(ctx,itypes.parse_type(ctx,'[10 x i32]'),'[i32 10, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 _1, i32 _1, i32 703]',),itypes.parse_type(ctx,'[10 x i32]')) File "/home/tianchiliu/hv6/irpy/o.test/libirpy/z3eval.py", line 323, in declare_global_constant for n, i in enumerate(util.parse_constant_array(value)): File "/home/tianchiliu/hv6/irpy/o.test/libirpy/util.py", line 265, in parse_constant_array return [int(v.split()[1]) for v in values[1:-1].split(', ')] ValueError: invalid literal for int() with base 10: '_1' Ran 33 tests in 87.651s FAILED (errors=1) make: *** [irpy/test] Error 1
解決:
ValueError: invalid literal for int() with base 10: '_1'
:字符串不能轉爲整型
由 File "/home/tianchiliu/hv6/irpy/o.test/switch_table_1.py", line 14, in init_globalsirpy.declare_global_constant(ctx,'@switch_table',itypes.parse_type(ctx,'[10 x i32]*'),irpy.constant_data_array(ctx,itypes.parse_type(ctx,'[10 x i32]'),'[i32 10, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15,**i32 _1, i32 _1**, i32 703]',),itypes.parse_type(ctx,'[10 x i32]')):
和
[int(v.split()[1]) for v in values[1:-1].split(', ')]
修改switch_table_1.py和switch_table_1.py的 line 14中**i32 _1, i32 _1爲i32 1, i32 1**
再次make irpy/test
[root@localhost hv6]# make irpy/test cd irpy/o.test && python2 test.py Random seed: 17799494710820576461 .[param.7 = 2084980470, param.6 = 2143437557] In function irpy/test/add_overflow.c:test:24:14 ................. In function irpy/test/poison_cond.c:test:23:9 .........[i32 10, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 1, i32 1, i32 703] [i32 10, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 1, i32 1, i32 703] ....[param.141 = 0] In function irpy/test/zero_div.c:test:23:14 .. Ran 33 tests in 89.920s OK
成功!