Misc ideas

Not all features are enabled by CPUID, some are enabled by MSR. You can verify this in QEMU:

typedef enum FeatureWordType {
   CPUID_FEATURE_WORD,
   MSR_FEATURE_WORD,
} FeatureWordType;

Xen is developed before the VT, so before the VT, The guest of Xen is running on Ring 1.

KVM is developed based on the VT.

ftrace is based on ring buffer.

Intel VT-x doesn't stand for Virtualization technology, it stands for Vanderpool technology.

Error number in QEMU #WIP

return -1
return -ENOENT
return -errno

Why always return a minus number?

Back in my old Unix days, there was something of a convention that 0 meant success, a positive number meant minor problems, and a negative number meant some sort of failure.

c - Why return a negative errno? - Stack Overflow

What's the difference between these 3?

For all capital letter error number, they are defined by the kernel, not by the QEMU, you can see them in the file /usr/include/asm-generic/errno-base.h.

errno actually is a macro.

PSC (Paging-Structure Cache)

The process is from exact to vague:

  • PTE is the most precise, so first see if the one is in the TLB (Using 47:12);
  • Not found, then find it in the PDE cache (Using 47:21);
  • Not found, then find it in the PDP cache (Using 47:30);
  • Not found, then find it in the PML4 cache (Using 47:39).

It has a spec, for more detailed information you can see there.

https://composter.com.ua/documents/TLBs_Paging-Structure_Caches_and_Their_Invalidation.pdf

Irqfd

基于 eventfd。

irqfd 机制提供了 QEMU/KVM 向 Guest 发送通知的快捷通道。The delivery path is single direction, say, interrupt is delivered from outside world into the guest. Userspace 和 Kernel 都可以向 Guest 注入中断。If we want to trigger an interrupt, what we need to do is only write to that corresponding eventfd:

  • In userspace, a simple write() is ok
  • In kernel, eventfd_signal().

Dive into irqfd mechanism - L

KVM irqfd support patch: http://git.kernel.org/linus/721eecbf4fe995ca94a9edec0c9843b1cc0eaaf3

Eventfd

eventfd 是一个用来通知事件的文件描述符,timerfd 是的定时器事件的文件描述符。二者都是内核向用户空间的应用发送通知的机制。

In brief:

  • The object contains an unsigned 64-bit integer (uint64_t) counter that is maintained by the kernel. This counter is initialized with the value specified in the argument initval.
  • A write(2) call adds the 8-byte integer value supplied in its buffer to the counter. The maximum value that may be stored in the counter is the largest unsigned 64-bit value minus 1 (i.e., 0xfffffffffffffffe).
  • The returned file descriptor supports poll(2) (and analogously epoll(7)) and select(2).

Exporting symbols from kernel module

Linux kernel allows modules stacking, which basically means one module can use the symbols defined in other modules. But this is possible only when the symbols are exported.

If you want to use the symbols exported by other kernel modules, you can simply just:

extern hello_export();

Linux World: Exporting symbols from module

UM archietecture

全名叫 user mode,它不是一种实体的 cpu 架构,这个架构的 linux 内核可以像 helloworld 程序一样运行,运行于 linux 之上用户空间中,取名 User Mode Linux,简写 UM。

You can see it under the arch/um.

Will memory access always cause a VM-exit without EPT?

假设在 TLB 里正好有映射,那

No, it will traverse the page table in CR3, like in bare-metal.

But the CR3 can be

Shadow page table / 影子页表

Without VMX:

  • Guest writes a mapping for VA 0xdeadbeef into it's page tables (a location in memory), but remember, this mapping isn't being used by the hardware.
  • Guest accesses 0xdeadbeef, which causes a page fault because the real page tables haven't been updated to add the mapping
  • Page fault is forwarded to hypervisor
  • Hypervisor looks at guest page tables and notices they're different from shadow page tables, says "hey, I haven't created a real mapping for 0xdeadbeef yet"
  • So it updates its shadow page tables and creates a corresponding 0xdeadbeef->HPA mapping for the hardware to use.

some of the work of the x86 MMU needs to be duplicated in software for the guest OS using a technique known as shadow page tables.

x86 virtualization - Wikipedia

virtual machine - What exactly do shadow page tables do? - Stack Overflow

Quick Note on Shadow Page Table | F叔的学习笔记

With VMX:

The MOV from CR3 instruction causes a VM exit if the “CR3-store exiting” VM-execution control is 1.

The MOV to CR3 instruction causes a VM exit unless the “CR3-load exiting” VM-execution control is 0 or the value of its source operand is equal to one of the CR3-target values specified in the VMCS. Only the first n CR3-target values are considered, where n is the CR3-target count. If the “CR3-load exiting” VMexecution control is 1 and the CR3-target count is 0, MOV to CR3 always causes a VM exit.

传统情况(有 VMX 但是没有 EPT):非根模式下访存被认定为敏感指令,会 VM-Exit。

有两个问题:

  • 频繁的触发 VM-Exit,开销非常大;
  • VMM 要经过 GPA -> HVA -> HPA 三个阶段,实现效率低。

影子页表解决了第二个问题,它的出发点是 减少地址转换:当处于非根模式下的 CPU 有修改 CR3 的动作时(通常是下一个进程被调度的时候),意味着有页目录地址会被加载到 CR3,这时会 VM-Exit。

VMM 中维护了一个 hash 链表,用于存放 Guest CR3 到影子地址的映射,VMM 拿到 Guest CR3 后计算该地址的 hash 值并作为 key 放到 hash 表中,然后申请一个物理地址放到 CR3 寄存器中,同时此地址也被存放到 hash 表的 value 中。

影子页表的 hash 链表中,一个节点对应一个进程(因为一个进程一个页表,也就是一个 CR3 地址)。

内存虚拟化硬件基础——EPT_享乐主的博客-CSDN博客_ept

现在所称的影子页表(shadow page table)指的是基于 VMX 硬件虚拟化技术的,但是并没有基于 EPT。

Are all MSRs 64bit?

Yes.

MSR_百度百科

Model Specific Registers - OSDev Wiki

Latency of different x86 instructions

https://uops.info/table.html

VT-x switch in BIOS and the VMXON instruction

VT-x switch: Does BIOS want to expose the virtualization feature to the OS?

VMXON: Does OS want to use this feature?

Actually, this BIOS's main functionality.

Python regex lookahead/lookbehind

  • (?=…)

    Matches if matches next, but doesn’t consume any of the string. This is called a lookahead assertion. For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov'.

  • (?!…)

    Matches if doesn’t match next. This is a negative lookahead assertion. For example, Isaac (?!Asimov) will match 'Isaac ' only if it’s not followed by 'Asimov'.

re — Regular expression operations — Python 3.10.6 documentation

Houdini: running ARM apps on X86 processors

Sleight of ARM: Demystifying Intel Houdini

What are .rej files and how to use them?

A reject file contains the hunks cannot be merged automatically.

git am  --reject  ~/ForwardedMessage.eml 

will generate reject files if there are conflicts.

Modify the .rej file then apply it:

git apply *.rej

if you meet the error: patch fragment without header at line error message, you should update the .rej file manully following git - How do I apply rejected hunks after fixing them? - Stack Overflow.

How does KVM know when to give the control to userspace when a VM-exit happened?

In arch/x86/kvm/vmx/vmx.c, you can see:

/*
 * The exit handlers return 1 if the exit was handled fully and guest execution
 * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
 * to be done to userspace and return 0.
 */
static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
	[EXIT_REASON_EXCEPTION_NMI]           = handle_exception_nmi,
	[EXIT_REASON_EXTERNAL_INTERRUPT]      = handle_external_interrupt,
	[EXIT_REASON_TRIPLE_FAULT]            = handle_triple_fault,
	[EXIT_REASON_NMI_WINDOW]	      = handle_nmi_window,
	[EXIT_REASON_IO_INSTRUCTION]          = handle_io,
	[EXIT_REASON_CR_ACCESS]               = handle_cr,
	[EXIT_REASON_DR_ACCESS]               = handle_dr,
	[EXIT_REASON_CPUID]                   = kvm_emulate_cpuid,
	[EXIT_REASON_MSR_READ]                = kvm_emulate_rdmsr,
	[EXIT_REASON_MSR_WRITE]               = kvm_emulate_wrmsr,
	[EXIT_REASON_INTERRUPT_WINDOW]        = handle_interrupt_window,
	[EXIT_REASON_HLT]                     = kvm_emulate_halt,
	[EXIT_REASON_INVD]		      = handle_invd,
	[EXIT_REASON_INVLPG]		      = handle_invlpg,
	[EXIT_REASON_RDPMC]                   = handle_rdpmc,
	[EXIT_REASON_VMCALL]                  = handle_vmcall,
	[EXIT_REASON_VMCLEAR]		      = handle_vmx_instruction,
	[EXIT_REASON_VMLAUNCH]		      = handle_vmx_instruction,
	[EXIT_REASON_VMPTRLD]		      = handle_vmx_instruction,
	[EXIT_REASON_VMPTRST]		      = handle_vmx_instruction,
	[EXIT_REASON_VMREAD]		      = handle_vmx_instruction,
	[EXIT_REASON_VMRESUME]		      = handle_vmx_instruction,
	[EXIT_REASON_VMWRITE]		      = handle_vmx_instruction,
	[EXIT_REASON_VMOFF]		      = handle_vmx_instruction,
	[EXIT_REASON_VMON]		      = handle_vmx_instruction,
	[EXIT_REASON_TPR_BELOW_THRESHOLD]     = handle_tpr_below_threshold,
	[EXIT_REASON_APIC_ACCESS]             = handle_apic_access,
	[EXIT_REASON_APIC_WRITE]              = handle_apic_write,
	[EXIT_REASON_EOI_INDUCED]             = handle_apic_eoi_induced,
	[EXIT_REASON_WBINVD]                  = handle_wbinvd,
	[EXIT_REASON_XSETBV]                  = handle_xsetbv,
	[EXIT_REASON_TASK_SWITCH]             = handle_task_switch,
	[EXIT_REASON_MCE_DURING_VMENTRY]      = handle_machine_check,
	[EXIT_REASON_GDTR_IDTR]		      = handle_desc,
	[EXIT_REASON_LDTR_TR]		      = handle_desc,
	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
	[EXIT_REASON_EPT_MISCONFIG]           = handle_ept_misconfig,
	[EXIT_REASON_PAUSE_INSTRUCTION]       = handle_pause,
	[EXIT_REASON_MWAIT_INSTRUCTION]	      = handle_mwait,
	[EXIT_REASON_MONITOR_TRAP_FLAG]       = handle_monitor_trap,
	[EXIT_REASON_MONITOR_INSTRUCTION]     = handle_monitor,
	[EXIT_REASON_INVEPT]                  = handle_vmx_instruction,
	[EXIT_REASON_INVVPID]                 = handle_vmx_instruction,
	[EXIT_REASON_RDRAND]                  = handle_invalid_op,
	[EXIT_REASON_RDSEED]                  = handle_invalid_op,
	[EXIT_REASON_PML_FULL]		      = handle_pml_full,
	[EXIT_REASON_INVPCID]                 = handle_invpcid,
	[EXIT_REASON_VMFUNC]		      = handle_vmx_instruction,
	[EXIT_REASON_PREEMPTION_TIMER]	      = handle_preemption_timer,
	[EXIT_REASON_ENCLS]		      = handle_encls,
	[EXIT_REASON_BUS_LOCK]                = handle_bus_lock_vmexit,
	[EXIT_REASON_NOTIFY]		      = handle_notify,
};

"randomness" In git log

Question: Does "git log" involve some stochastic operations?

Logical CPU and vCPU

A logical processor is the number of the processor's cores multiplied by the number of threads per core.

vCPUs are actually the amounts of of time a virtual machine gets on a logical processor.

(2) What is the difference between Virtual CPU and Logical CPU? - Quora

Asm #kernel #code

I guess it stands for Architecture Specific Macros (asm) initially. After that, any architecture specific stuff are placed there.

what is asm stand for in linux/include/asm - Stack Overflow

But we already has x86 folder, why add another hierachy?

Maybe the point is on Macro, not the Architecture Specific.

asm can also under uapi, such as arch/x86/include/uapi/asm/vmx.h, which means these are macros exposed to the userspace.

Uapi #kernel #code

uapi is User API.

What's the purpose of uapi folder in the kernel source tree.

The uapi folder is supposed to contain the user space API of the kernel. Then upon kernel installation, the uapi include files become the top level /usr/include/linux/ files. (I'm not entirely clear on what exceptions remain.)

The other headers in theory are then private to the kernel. This allow clean separation of the user-visible and kernel-only structures which previously were intermingled in a single header file.

networking - What's in include/uapi of kernel source project - Stack Overflow

Linux Kernel 中新增的这些 uapi 头文件,其实都是来自于各个模块原先的头文件,最先是由 David Howells 提出来的。uapi 只是把内核用到的头文件和用户态用到的头文件分开。

方便用户态的开发者,可以简单的查看 uapi 里的代码变化来确定 Linux Kernel 是否改变了系统 API。

Linux Kernel UAPI - 泰晓科技

DebugFS

并不实际存储在硬盘上,而是 Linux 内核运行起来后才建立起来。

通常情况下,最常用的内核调试手段是 printk。但 printk 并不是所有情况都好用,

  • 比如打印的数据可能过多,我们真正关心的数据在大量的输出里不是那么一目了然;
  • 或者我们在调试时可能需要修改某些内核变量,这种情况下 printk 就无能为力,而如果为了修改某个值重新编译内核或者驱动又过于低效,此时就需要一个临时的文件系统可以把我们需要关心的数据映射到用户空间。

在过去,procfs 可以实现这个目的,到了 2.6 时代,新引入的 sysfs 也同样可以实现,但不论是 procfs 或是 sysfs,用它们来实现某些 debug 的需求,似乎偏离了它们创建的本意。比如 procfs,其目的是反映进程的状态信息;而 sysfs 主要用于 Linux 设备模型。不论是 procfs 或是 sysfs 的接口应该保持相对稳定,因为用户态程序很可能会依赖它们。当然,如果我们只是临时借用 procfs 或者 sysfs 来作 debug 之用,在代码发布之前将相关调试代码删除也无不可。但如果相关的调试接口要在相当长的一段时间内存在于内核之中,就不太适合放在 procfs 和 sysfs 里了。故此,debugfs 应运而生。

默认情况下,debugfs 会被挂载在目录 /sys/kernel/debug 之下。

为什么要挂载在 /sys/kernel/debug 下,那不是和 sysfs 的挂载路径重合了嘛

挂载的路径可以是包含的关系,毕竟 sysfs 也挂载了根路径下面。

filesystems - Why can the mount points of debugfs and sysfs be overlapped? - Unix & Linux Stack Exchange

debugfs_create_u8("a", 0644, my_debugfs_root, &a);

这表示文件名为 “a”,文件属性是 0644,父目录是上面建立的 “mydebug”,对应的变量是模块中的 a。

Linux内核里的DebugFS有什么用 - 编程宝库

更多使用方法,可参考:

Debugfs [LWN.net]

A tiny example for using DebugFS

debugfs-tutorial/example1 at master · chadversary/debugfs-tutorial

Kernel make syncconfig error

git clean -xdf

How to install perf for your specific kernel?

cd <repo-root>
sudo make -C tools perf_install prefix=/usr/

Different between pipe and redirection

The difference between a pipe and a redirect is that while a pipe passes standard output as standard input to another command, a redirect sends a output to a file or reads a file as standard input to a command.

Linux piping and redirection

Vermagic

Vermagic is a magic string present in the Linux Kernel and added into the .modinfo section of the Linux Kernel Modules.

This is used to verify whether the kernel module was compiled for the particular kernel version or not.

Why in my CONFIG, the kernel version is "5.10.84-30466-gaa958a718cc1", but the result is "5.10.84-30466-gaa958a718cc1-dirty"? Where are the "dirty" suffix come from?

dirty means that you have a Git repository (or sources that sounds like a Git repository) on which there are uncommitted changes.

linux - vermagic of the module different from the kernel version that it was compiled for - Stack Overflow

Does this fail the vermagic check when insmod?

Yes.

How to avoid that?

If you think just commit the change will avoid this, then you are naive, because it will change from:

5.10.84-30466-gaa958a718cc1

to

5.10.84-30468-gfafffc884078

the 30466 increase 2, maybe indicates that I has 2 commits ahead?

If you just want to modify a kernel module, then you just need to compile the module, not the whole kernel.

Git move to child commit

Just:

git branch --contains $commit

git - How to checkout a commit's child? - Stack Overflow

Worse is better?

aka. New Jersey style.

The worse-is-better philosophy means that implementation simplicity has highest priority, which means Unix and C are easy to port on such machines.

Worse is better - Wikipedia

NVDIMM (Persistent Memory) vs Optane (Storage Class Memory)

The SNIA figure above, right, identifies the levels of the Memory Hierarchy with the NVDIMM-N represented at the DRAM level of the hierarchy and Optane DIMM appearing at the **Storage Class Memory **(SCM) level. Both are included in the Memory Level of the hierarchy because they are byte-addressable as opposed to the Storage Level, which is block addressable. The distinction is important because byte-addressable access to data down to the level of a cache line (usually 64 bytes) is the most efficient size of data for CPU L1, L2, and L3 cache movement operations.

SCM products offer a slightly different approach to the use of NAND in that they extend the apparent capacity of a standard DIMM by using NAND as a backing store and DRAM as a cache for active data. This gives the ability to deploy servers with very high DRAM capacities and at a lower cost than using traditional DRAM alone.

NVDIMMs and Optane DIMMs both provide persistent, byte-addressable memory, but nearly all similarities end with these characteristics. Within the Memory Hierarchy, the NVDIMM resides at the DRAM level and Optane DIMM at the SCM level.

What are Storage Class Memory and Persistent Memory ?

61

Git merge

In any merge, if the two sides modify adjacent lines—as is the case here—that, too, is considered a conflict (at least Git considers it as one; not all merge algorithms do that).

Note that if the two diffs modify the same line(s) in the same way—e.g., both add the same text or delete the same text—Git will take only one copy of the change, without calling it a conflict. In some cases this may be incorrect: consider. e.g., merging the debits and credits in a series of accounting records, where the dollar amounts are identical, but the transactions are different. If Alice spent 5 and Bob spent 5, the correct result is not that "5 total was spent" but rather 10.

Still, for the kinds of tasks Git is asked to merge, this is normally the correct result, so it is the result Git produces.

Git is a tool—or rather, a set of tools—and its automated work is never a substitute for expert evaluation. You, the user, must do some work here as well, to make sure that what Git did is in fact correct for your particular situation.

[Question]: Question about "cherry-pick" internal - Wang, Lei

Error during sync of the configuration

git clean -xdf

Error building latest linux kernel within VirtualBox under 18.04.1-Ubuntu - Stack Overflow

How to debug qemu using gdb

Setups For Debugging QEMU with GDB and DDD - Newbie wang - 博客园

CPUID leave and sub-leaf

CPUID's input is just 2 registers: EAX and ECX.

The value in EAX identify a leaf, and the value both in EAX and ECX identify a sub-leaf.

out: 可执行文件,相当于 win 上的 exe;

o: 编译中间目标文件;

ko: 内核模块;

so: 动态链接库,dll;

a: 静态链接库;

S: 汇编。

How to write the author when backporting patches?

Should be the original author, not the guy do the backporting.

Difference between 0x… and …H

0x is the hexadecimal prefix, H is the hexadecimal suffix

Both represent hexadecimal numbers, and there is no difference in meaning, and they are completely equal. As for when to use 0x and when to use H, it depends on what environment you are using. If it is in C/C++, it must be represented by 0x.

H cannot be used in C language.

Is there any difference between 0x and H indicating hexadecimal? - Karatos

How to use rdmsr?

rdmsr <msr_address>

A better CPUID instruction usage

cpuid --one-cpu -l <leaf>
cpuid --one-cpu -l 0x80000008 -r # EAX = 0x80000008
cpuid --one-cpu -l 1 -r # EAX = 1
cpuid --one-cpu -l 0x7 -s 0x0 # -l: EAX, -s: ECX

Icelake

不管是 client 端(Core)还是 server 端(Xeon),都叫 Icelake,也就是 Icelake 分成了服务器端和客户端,可以在 qemu 的 CPU Model 里验证这一点。

How to set the default kernel when booting from grub?

you can see all the available values by running:

cat /boot/grub/grub.cfg | grep menuentry

cat /boot/grub/grub.cfg | sed -n 's/menuentry \'\(.*,\ .*\)\' --class.*$/\1/p'

then find the GRUB_DEFAULT in the /etc/default/grub, replace the value with the value you want from above, remember to add the prefix Advanced options for Ubuntu>, then sudo update-grub.

20.04 - setting older kernel version as default - Ask Ubuntu

Tmux full command reference

tmux - Linux manual page

Sparse file

Say you have a file with many empty bytes \x00. These many empty bytes \x00 are called holes. Storing empty bytes is just not efficient, we know there are many of them in the file, so why store them on the storage device? We could instead store metadata describing those zeros. When a process reads the file those zero byte blocks get generated dynamically as opposed to being stored on physical storage.

filesystems - What is a sparse file and why do we need it? - Stack Overflow

Can a sparse file go beyond the disk size?

Sure, you can create a sparse file that has exabytes instead of terabytes in size, this is only limited by the maximum file size of a given filesystem.

Actually writing data to such a sparse file will eventually yield the common no space left on device error.

Can a sparse file go beyond the ram size? - Unix & Linux Stack Exchange

Telnet vs ssh

Telnet transfers the data in simple plain text. On other hand SSH uses Encrypted format to send data and also uses a secure channel.

Signal

Signals are similar to interrupts, the difference being that:

  • interrupts are mediated by the CPU and handled by the kernel;
  • while signals are mediated by the kernel (possibly via system calls) and handled by individual processes.

That's why MCE is handled by host and converted to sigbus, such as Safe vs. unsafe handling of uncorrectable ECC errors.

But wait…what's the LOCK# signal? it is a bus lock signal and I suppose it cannot be mediated by the kernel?

The answer is that it is an electronic signal, not equals to a signal in OS.

The kernel may pass an interrupt as a signal to the process that caused it (typical examples are SIGSEGV, SIGBUS, SIGILL and SIGFPE).

Signal - Wikipedia

How to write a signal handler for current process?

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
void sig_handler(int signum) {
    //Return type of the handler function should be void
    printf("\nInside handler function\n");
}

int main(){
    signal(SIGINT,sig_handler); // Register signal handler
    for(int i=1;;i++){    //Infinite loop
        printf("%d : Inside main function\n",i);
        sleep(1);  // Delay for 1 second
    }
    return 0;
}

How to use signal handlers in C language?

SIGTRAP

MSR passthrough and non-passthrough

When a guest wants to access an MSR, there are two common ways:

Intercept

The process is:

  1. The wrmsr or rdmsr cause a VM-Exit, CPU now in root mode;
  2. KVM see which MSR it want to access, and do some operation, such as write_vmcs;
  3. Back to root mode by VM-Entry, the VMCS is loaded so the real MSR value is the value guest wants to set;
  4. Guest starts to process…

Passthrough

The process is:

  1. Guest wrmsr and rdmsr won't VM-Exit;
  2. When Guest VM-Exit, its currently MSR value will be saved in the VMCS guest area;
  3. When VM-Entry, MSR value will be loaded from the VMCS guest area.

The above two method both can isolate the MSR value between host and guest, because no matter it intercept or passthrough, the VMCS will load and save during each VM-Entry and VM-Exit.

The intercept method has more flexibility, because it can shadow some bits if the host doesn't want to expose all the bits to the guest.

The passthrough method has higher performance, because it doesn't VM-Exit and VM-Entry, that's obvious.

These two methods both use the physical MSR.

Kernel debugging

Just like the name, pr_info is printk with the KERN_INFO priority.

Dmesg

dmesg -wH # in real time
sudo dmesg --clear # clear

Qemu with gdb

Debugging kernel and modules via gdb — The Linux Kernel documentation

Debugging linux kernel with GDB and Qemu · Yulistic.com

What is triple fault?

If the processor encounters a problem when calling the double fault handler, a triple fault is generated and the processor shuts down.

What is double fault?

A double fault exception occurs if the processor encounters a problem while trying to service a pending interrupt or exception.

An example situation when a double fault would occur is when an interrupt is triggered but the segment in which the interrupt handler resides is invalid.

其实就是硬件告诉 OS 准备死吧,给最后一个打印 call trace 的机会哈哈。

Qemu debugging

Add -D logfile option for ourputting log.

In the code, use qemu_log("something") to log.

launch.json for qemu debugging

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "cppdbg",
            "request": "launch",
            "name": "Launch QEMU",
            "cwd": "${workspaceFolder}",
            "program": "${workspaceFolder}/build/qemu-system-x86_64",
            "args": [
                "--m",
                "16G",
                "-smp",
                "16",
                "-enable-kvm",
                "/home/lei/p/lei.img",
                "-vnc",
                ":4",
                "-net",
                "nic,model=virtio",
                "-net",
                "user,hostfwd=tcp::8022-:22"
            ],
            "stopAtEntry": true
        }
    ]
}

nvim-dap can also use this to debug.

Clock (Computing)

What's the purpose?

  • hardware clock (Real Time Clock, RTC),晶振 is a type of hardware clock.
  • software clock, such that the

Paging Structures

Name Desc.
Paging Structure The whole thing
PML (Page Map Level) Its a number, indicating the level we are using.
PDE (Page Directory Entry) Levels except the last level
PTE (Page Table Entry) Last level
PSE (Page Structure Entry) All levels
EPT Paging Structure Pointed by EPTP, from GPA to HPA
Guest Paging Structure Guest's paging structure.