2023-04 Monthly Archive
PCI transactions / TLP (transaction layer protocol)
The Transaction Layer is located between the Application Layer and the Data Link Layer.
PCI Express transactions can be grouped into four categories: 1) memory, 2) IO, 3) configuration, and 4) message transactions.
Transactions are defined as a series of one or more packet transmissions required to complete an information transfer …
Introduction to PCI Express Transactions - PCI Express System Architecture [Book]
Chip selection signal
When an engineer needs to connect several devices to the same set of input wires (e.g., a computer bus), but retain the ability to send and receive data or commands to each device independently of the others on the bus, they can use a chip select. When the chip select pin is in:
- The inactive state, the chip or device is "deaf", and pays no heed to changes in the state of its other input pins;
- The active state, the chip or device assumes that any input changes it "hears" are meant for it, and responds as if it is the only chip on the bus. Because the other chips have their chip select pins in the inactive state, their outputs are high impedance, allowing the single selected chip to drive its outputs.
QEMU bottom half(bh)
QEMU actually uses a hybrid architecture:
- Parallel architecture splits work into processes or threads that can execute simultaneously. I will call this threaded architecture.
- Event-driven architecture reacts to events by running a main loop that dispatches to event handlers. This is commonly implemented using the select(2) or poll(2) family of system calls to wait on multiple file descriptors.
Bottom half 本身就是一种事件循环,并不是用 thread 来实现的。和它在作用上等效的是一个直接 expire 的 timer,区别是 timer 是真的异步,bottom half 是借时间循环来异步。
意义是什么?avoid reentrancy and overflowing the call stack,相当于直接把 call stack 返回了第 0 层。适用于不断调用自己的函数或者调用层级比较多的函数。
深入理解 qemu 事件循环 —— 下半部_享乐主的博客 - CSDN 博客
Stefan Hajnoczi: QEMU Internals: Overall architecture and threading model
pthread_create()
// start_routine: the real thread function need to run
// arg: Arguments need to be passed to "start_routine"
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void *),
void *restrict arg);
小狼毫/Weasel 调色
Madvise / madvise()
Give (Note: not get) advice about use of memory about the given address range. I.e., use huge page or not.
madvise() only operates on whole page, therefore addr
must be page-aligned.
In most cases, the goal of such advice is to improve system or application performance.
MADV_DONTDUMP
: Exclude from a core dump those pages in the range specified by addr and length. This is useful in applications that have large areas of memory that are known not to be useful in a core dump.
MADV_DONTFORK
: Do not make the pages in this range available to the child after a fork. This is useful to prevent copy-on-write semantics from changing the physical location of a page if the parent writes to it after a fork.
Gdb frame
When your program is started, the stack has only one frame, that of the main()
. This is called the initial frame or the outermost frame. Each time a function is called, a new frame is made.
Mermaid 画时序图
可以用 Gantt 图来画:
如何让 tag (milestone) 不重叠?
Typedef function pointer
typedef void (*myfunc)();
myfunc f; // compile equally as void (*f)();
c++ - Typedef function pointer? - Stack Overflow
iovec
In kernel, scatter/gather IO, readv
/writev
为了提高从磁盘读到内存的效率,引入了 struct iovec
,主要在 readv
和 writev
中使用。
// readv:从 fd 中读 count 个数据段到多个 buffers 中,每一个 buffer 是一个 struct iovec,参数 iov 表示这些 iovec。
// iovcnt 表示 iov 中 iovec 的数量,writev 类似。
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
// Compared to read and write, readv has a higher performance,
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
这里有一个简单的性能对比:readv/writev分析 - 知乎
可以看到,主要节省的是系统调用的开销。
struct iovec {
void *iov_base; /* Pointer to data. */
size_t iov_len; /* Length of data. */
};
Userspace use case:
int main() {
struct iovec iov[3];
int fd, i;
char *buf[] = {
"The term buccaneer comes from the word boucan.\n",
"A boucan is a wooden frame used for cooking meat.\n",
"Buccaneer is the West Indies name for a pirate.\n"
};
fd = open("buccaneer.txt", O_WRONLY | O_CREAT | O_TRUNC);
for(i = 0; i < 3; i++){
iov[i].iov_base = buf[i];
iov[i].iov_len = strlen(buf[i]);
}
writev(fd, iov, 3);
close(fd);
return 0;
}
KVM device framework
struct kvm_device_ops {
const char *name;
int (*create)(struct kvm_device *dev, u32 type);
void (*init)(struct kvm_device *dev);
void (*destroy)(struct kvm_device *dev);
void (*release)(struct kvm_device *dev);
int (*set_attr)(struct kvm_device *dev, struct kvm_device_attr *attr);
int (*get_attr)(struct kvm_device *dev, struct kvm_device_attr *attr);
int (*has_attr)(struct kvm_device *dev, struct kvm_device_attr *attr);
long (*ioctl)(struct kvm_device *dev, unsigned int ioctl,
unsigned long arg);
int (*mmap)(struct kvm_device *dev, struct vm_area_struct *vma);
};
The reason why there is ioctl
and set_attr
is ioctl
callback is used to handle the default operations.
MONITOR/MWAIT Instruction
SSE3 提供的 MONITOR/MWAIT
的目标是供系统软件用于提供更有效的线程同步原件。
OS 可以在其 idle loop(被称为 C0 循环)中使用 MONITOR
和 MWAIT
来减少电能消耗。
For a spin lock, a while check loop is performed until the value is changed. This can be enhanced using MONITOR/MWAIT
:
-
MONITOR
建立一个有效的寻址范围,用于监视对存储器写的活动; -
MWAIT
将处理器置于一个优化的状态,直到一次对被监视的地址范围的写发生。
引入了 monitor
和 mwait
指令后,避免了 hlt
导致的唤醒延迟。
Intel系统编程指南第八章——8.10 空闲和阻塞情况的管理_zenny_chen的博客-CSDN博客
Introduction to hlt/pause/monitor/mwait instruction - L
assembly - Uses of the monitor/mwait instructions - Stack Overflow
Anonymous structure/union (unnamed structure/union) in C
struct {
int a;
struct {
int b;
};
union {
int c;
};
} foo;
You can foo.a
, foo.b
and foo.c
.
Bit field in C
struct date {
// d has value between 0 and 31, so 5 bits
// are sufficient
int d : 5;
// m has value between 0 and 15, so 4 bits
// are sufficient
int m : 4;
int y;
};
Defconfig
defconfig
一般在 arch/arm64/configs/
目录下,是一个没有展开的内核配置,需要配合 Kconfig 展开成 .config
.
从 defconfig 到.config 不是简单的复制操作,而是 make ARCH=arm64 defconfig
.confg 也不是直接拷贝成 defconfig,而是使用 make ARCH=arm64 savedefconfig
linux kernel: defconfig和.config_defconfig和config_hello_courage的博客-CSDN博客
Merge 2 kernel configs
scripts/kconfig/merge_config.sh -m <base_config> <merge_config>
Get kernel config for currently running system
Make sure CONFIG_IKCONFIG_PROC=y
when building the kernel, then:
modprobe configs
cat /proc/config.gz | gunzip > running.config
BMC
Baseboard Management Controller.
BMC 是独立于服务器系统之外的小型操作系统,是一个集成在主板上的芯片。
A baseboard management controller (BMC) is a service processor which is capable of monitoring the physical state of servers, computers or other hardware devices with help of sensors.
What is SeaBIOS and the relationship with OVMF?
SeaBIOS 是 16bit BIOS 的一个实现,是 QEMU 默认使用的。
QEMU, by default, uses a BIOS called SeaBios. It is a pretty good option and most can be used with most bootloaders. And naturally, every guest machine is loaded with the SeaBios and you don't have to do anything. However, you might want, or need, to use UEFI instead. 这个时候就需要用 OVMF 了,其加入了对于 UEFI 的支持。
一句话,能用 OVMF 就用 OVMF。
Vmexit reasons
It is a 32-bit field in VMCS.
Volume 3. SDM APPENDIX C VMX BASIC EXIT REASONS
How to see processor stepping?
BIOS -> Socket Configuration -> Processor BSP Revision
跳线 Jumpers
Reboot to BIOS/UEFI
systemctl reboot --firmware-setup
"invalid For another…" on Ubuntu
service ntp stop
Configure NTP server by editing /etc/ntp.conf
(replace the server with yours):
tinker panic 0
disable monitor
restrict <server1> nomodify notrap nopeer noquery
restrict <server2> nomodify notrap nopeer noquery
restrict <server3> nomodify notrap nopeer noquery
server <server1> iburst
server <server2> iburst
server <server3> iburst
driftfile /var/lib/ntp/drift
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
restrict 127.0.0.1
restrict ::1
restrict source notrap nomodify noquery
ntpd -gq
service ntp start
How to create extensions for Thunderbird
A Guide to Extensions - Thunderbird
Why x64 doesn't have r0-r7 registers?
Wrong.
With x86_64 came another doubling of register size, as well as the addition of some new registers. These registers are 64 bits wide and are named (slash used to show alternate register name): RAX/r0, RCX/r1, RDX/r2, RBX/r3, RSP/r4, RBP/r5, RSI/r6, RDI/r7, R8, R9, R10, R11, R12, R13, R14, R15.
assembly - Why did they use numbers for register names in x86-64? - Stack Overflow