diff options
| author | xxy <[email protected]> | 2022-04-16 00:38:54 +0800 |
|---|---|---|
| committer | xxy <[email protected]> | 2022-04-16 00:38:54 +0800 |
| commit | abdeff9ee2815f1b4c7e2cb1af214da6c02845f5 (patch) | |
| tree | c992ce1374d9c0064b53d70cdae99d0113ef7592 | |
| parent | 3267353b5c96d07b49ce2985754776d5c6199ee4 (diff) | |
working log added
| -rw-r--r-- | .vscode/c_cpp_properties.json | 4 | ||||
| -rw-r--r-- | hw/intc/apic.c | 9 | ||||
| -rw-r--r-- | target/i386/hax/hax-interface.h | 2 | ||||
| -rw-r--r-- | target/i386/hvf/x86_emu.c | 8 | ||||
| -rw-r--r-- | target/i386/tcg/misc_helper.c | 2 | ||||
| -rw-r--r-- | target/i386/tcg/sysemu/seg_helper.c | 3 | ||||
| -rw-r--r-- | workinglog.md | 261 |
7 files changed, 281 insertions, 8 deletions
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 88c5cc9c36..c24c5b96f8 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -6,7 +6,9 @@ "${workspaceFolder}/target/i386", "${workspaceFolder}/**" ], - "defines": [], + "defines": [ + "TARGET_X86_64" + ], "compilerPath": "/usr/bin/gcc-11", "cStandard": "gnu17", "cppStandard": "gnu++14", diff --git a/hw/intc/apic.c b/hw/intc/apic.c index 86902162e6..5692737455 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -29,7 +29,8 @@ #include "hw/i386/apic-msidef.h" #include "qapi/error.h" #include "qom/object.h" - +#include <stdio.h> +// static bool Debug = true; #define MAX_APICS 255 #define MAX_APIC_WORDS 8 @@ -635,7 +636,8 @@ static void apic_timer(void *opaque) } static uint64_t apic_mem_read(void *opaque, hwaddr addr, unsigned size) -{ +{ + // if(Debug)printf("apic mem read called\n"); // 改 DeviceState *dev; APICCommonState *s; uint32_t val; @@ -738,6 +740,7 @@ static void apic_send_msi(MSIMessage *msi) static void apic_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { + //if(Debug)printf("apic mem write called\n"); // 改 DeviceState *dev; APICCommonState *s; int index = (addr >> 4) & 0xff; @@ -854,7 +857,7 @@ static void apic_post_load(APICCommonState *s) timer_del(s->timer); } } -// ?????? 拦截 +// ??????? 拦截 static const MemoryRegionOps apic_io_ops = { .read = apic_mem_read, .write = apic_mem_write, diff --git a/target/i386/hax/hax-interface.h b/target/i386/hax/hax-interface.h index 537ae084e9..f0e3eb99e5 100644 --- a/target/i386/hax/hax-interface.h +++ b/target/i386/hax/hax-interface.h @@ -62,7 +62,7 @@ struct hax_msr_data { uint16_t nr_msr; uint16_t done; uint16_t pad[2]; - struct vmx_msr entries[HAX_MAX_MSR_ARRAY]; + struct vmx_msr entries[HAX_MAX_MSR_ARRAY]; // ??? msr array } __attribute__ ((__packed__)); union interruptibility_state_t { diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index 050428795b..5f78ae1cc8 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -45,6 +45,9 @@ #include "x86_flags.h" #include "vmcs.h" #include "vmx.h" +#include <stdio.h> +static bool Debug = true; + void hvf_handle_io(struct CPUState *cpu, uint16_t port, void *data, int direction, int size, uint32_t count); @@ -664,8 +667,9 @@ static void exec_lods(CPUX86State *env, struct x86_decode *decode) env->eip += decode->len; } -void simulate_rdmsr(struct CPUState *cpu) -{ +void simulate_rdmsr(struct CPUState *cpu) // ??? +{ + if(Debug){printf("simulate rdmsr called\n");} // 改、 X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; CPUState *cs = env_cpu(env); diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c index 24a0eaa3d5..c0def7d9c7 100644 --- a/target/i386/tcg/misc_helper.c +++ b/target/i386/tcg/misc_helper.c @@ -61,7 +61,7 @@ void helper_cpuid(CPUX86State *env) env->regs[R_EDX] = edx; } -void helper_rdtsc(CPUX86State *env) +void helper_rdtsc(CPUX86State *env) // ??? 读取时间相关的函数 { uint64_t val; diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/seg_helper.c index 34e22ec987..d4dc414b57 100644 --- a/target/i386/tcg/sysemu/seg_helper.c +++ b/target/i386/tcg/sysemu/seg_helper.c @@ -25,6 +25,8 @@ #include "exec/cpu_ldst.h" #include "tcg/helper-tcg.h" #include "../seg_helper.h" +#include <stdio.h> +static bool Debug = true; #ifdef TARGET_X86_64 void helper_syscall(CPUX86State *env, int next_eip_addend) @@ -146,6 +148,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request) //?????? apic_poll_irq(cpu->apic_state); break; case CPU_INTERRUPT_SIPI: + if(Debug) printf("x86 cpu exec interrupt called sipi \n"); do_cpu_sipi(cpu); break; case CPU_INTERRUPT_SMI: diff --git a/workinglog.md b/workinglog.md new file mode 100644 index 0000000000..796f282865 --- /dev/null +++ b/workinglog.md @@ -0,0 +1,261 @@ + + +# 尝试在qemu上实现新的硬件特性 + +[toc] + +## 整理qemu代码 + +### 指令翻译部分 + +阅读intel手册,得到 + + + + + + + +### 指令模拟部分 + +首先研究几个具体的函数: + +```c +gen_helper_rdtsc(cpu_env); //target/i386/tcg/translate.c 7304 +``` + + + + + +### 核间中断部分 + +apic, 中断控制器, localapic lapic //内核态 + +cs寄存器中,cpl的位标志着cpu权级0是内核态,3是用户态 iret返回,切换权级。 + +x2是读写msr的 + +核通过内存访问 + +hw/intc/apic.c/apic_delever_irq + +s->icr[0] 发送方,写了就可以发ipi + + + +### cpu状态设定 + +``` +target/i386/cpu.h CPUX86State +400行左右,msr编号定义 +``` + + + +### 内存模拟定位 + + + +### 一些接口 + +``` +target/i386/hax/hax-interface 65 msr array +target/i386/hvf/x86emu.c 670 simulate_rdmsr +``` + + + + + +# qemu -d help 查看log + + + + + + + + + +## 编译intel实现的linux内核 + +```shell +cd uintr-linux-kernel/ +make O=build x86_64_defconfig +make O=build menuconfig +``` + +在这里需要有包依赖, 执行 + +```shell +sudo apt-get install ncurses-dev +``` + +在选择构建参数时: + +在`General setup`目录下, 选择`Initial RAM filesystem and RAM disk (initramfs/initrd) support`。 + +在`Device Drivers`目录中`Block device`下, 选择`RAM block device support`, 并设置` Default RAM disk size (kbytes)`为65536KB。 + +随后开始构建: + +```shell +make O=build bzImage -j +``` + +出现缺少头文件报错: ` fatal error: gelf.h: No such file or directory`, `fatal error: openssl/bio.h: No such file or directory`,进行安装: + +```shell +sudo apt install libssl-dev +sudo apt-get install libelf-dev +``` + + + +#### 创建文件系统 + +下载`busybox`, 执行以下 + +```shell +mkdir build +make O=build menuconfig +# 在 settings Build Options 中选择 # [*] Build static binary (no shared libs) +cd build +make -j4 +make install +``` + +```shell + ./_install//usr/sbin/ubirmvol -> ../../bin/busybox + ./_install//usr/sbin/ubirsvol -> ../../bin/busybox + ./_install//usr/sbin/ubiupdatevol -> ../../bin/busybox + ./_install//usr/sbin/udhcpd -> ../../bin/busybox + + +-------------------------------------------------- +You will probably need to make your busybox binary +setuid root to ensure all configured applets will +work properly. +-------------------------------------------------- # 记录以下log +``` + +```shell +mkdir -pv initramfs/x86_64_busybox +cd initramfs/x86_64_busybox/ +mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}} +cp -av ../../busybox-1.32.0/build/_install/* . +``` + +在`x86_64_busybox`目录下, 执行打包当前文件系统: + +```shell +find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs-busybox-x86_64.cpio.gz +``` + +启动linux的shell脚本如下: + +```shell +qemu-system-x86_64 -smp 2 \ +-m 1024M -nographic \ +-kernel ./uintr-linux-kernel/build/arch/x86_64/boot/bzImage \ +-initrd ./initramfs/initramfs-busybox-x86_64.cpio.gz \ +-append "root=/dev/ram0 rw rootfstype=ext4 console=ttyS0 init=/linuxrc" +``` + + + + + +## 编译测试程序 + +#### 编译简单测试程序: + +```shell +gcc -static compute.c -o compute +chmod a+x compute +``` + +#### 编译设计uintr的测试程序: + +直接编译: + +```shell +gcc -Wall -static -muintr -mgeneral-regs-only -minline-all-stringops uipi_sample.c -lpthread +gcc: error: unrecognized command line option ‘-muintr’ +``` + +用`gcc-11`编译: + +```shell +# 安装gcc-11 +sudo add-apt-repository ppa:ubuntu-toolchain-r/test +sudo apt install build-essential manpages-dev software-properties-common +sudo apt update && sudo apt install gcc-11 + +gcc-11 -Wall -static -muintr -mgeneral-regs-only -minline-all-stringops uipi_sample.c -lpthread -o /home/xcd/uintr_sample/uipi_sample +/tmp/ccmkHYQa.s: Assembler messages: +/tmp/ccmkHYQa.s:74: Error: no such instruction: `uiret' +/tmp/ccmkHYQa.s:120: Error: no such instruction: `senduipi %rax' +/tmp/ccmkHYQa.s:196: Error: no such instruction: `stui' +``` + +安装最新的汇编器: + +首先下载对应版本的安装包`binutils-2.38.tar.bz2 ` + +```shell +tar -jxvf +binutils-2.38.tar.bz2 +cd binutils-2.38 +./configure +make -j +sudo make install +``` + +随后编译,可以成功。 + +```shell +xxy@7af409e42583:~/uintr-linux-kernel/tools/uintr/sample$ make +gcc-11 -Wall -static -muintr -mgeneral-regs-only -minline-all-stringops uipi_sample.c -lpthread -o /home/xxy/uintr-linux-kernel/tools/uintr/sample/uipi_sample +xxy@7af409e42583:~/uintr-linux-kernel/tools/uintr/sample$ ls +Makefile README uipi.s uipi_sample uipi_sample.c +``` + +执行出现错误: + +```shell +./uipi_sample +Interrupt handler register error +``` + +gcc -S 得到汇编代码,主要的新增代码如下 + +```assembly + uiret # 这里是之前出错的指令 + senduipi %rax # 这里是出错的汇编指令 + stui # 这里也是之前出错的指令 +``` + + + +## 编译qemu + +```shell + cd qemu + mkdir build + ../configure --enable-debug --target-list=x86_64-softmmu + make -j +``` + +遇到缺少的包: + +```shell +ERROR: Cannot find Ninja +``` + +## ref + +1. https://hackmd.io/@octobersky/qemu-run-ubuntu +2. http://blog.vmsplice.net/2011/03/qemu-internals-big-picture-overview.html +3. https://vmsplice.net/~stefan/qemu-code-overview.pdf |
