1. 内核栈 在每一个进程的生命周期中,必然会通过到系统调用陷入内核。在执行系统调用陷入内核之后,这些内核代码所使用的栈并不是原先进程用户空间中的栈,而是一个单独内核空间的栈,这个称作进程内核栈。 1.1. init_task init_task,也就是bootcpu的swapper进程对应的task_struct,其内核栈是静态初始化的。 1/// init/init_task.c 2/* 3 * Set up the first task table, touch at your own risk!. Base=0, 4 * limit=0x1fffff (=2MB) 5 */ 6struct task_struct...
1. 编译选项 -fomit-frame-pointer表示在函数调用时不需要存储堆栈帧指针。此选项可减小生成的代码镜像大小, 一般在启用-On优化后会自动打开,也有的平台是默认打开的。 -fno-omit-frame-pointer表示将堆栈帧指针存储在寄存器中,帧指针是用来指示当前函数的栈帧(stack frame)的指针,在调试时可以帮助跟踪函数调用的堆栈信息。 在 AArch32 架构中,堆栈帧指针存储在寄存器R11A32代码)或寄存器R7T32代码)中. 在AArch64架构中,堆栈帧指针存储在寄存器X29中。作为帧指针使用的寄存器不能用作通用寄存器,但如果使用 -fomit-frame-pointer选项编译,则可用作...
1. Linux内核代码的编写和优化技巧 1.1. 代码编写 使用 __same_type和 typecheck编译时检查类型匹配。 __printf和 __scanf编译时检查代码。 对宏进行undef后重新定义,生成不同的代码,如 __SYSCALL配合 unistd.h生成系统调用,TRACE_EVENT生成ftrace相关的数据结构和各个函数。 使用模板宏,减少重复代码也降低出错率,如 STANDARD_PARAM_DEF生成 module_param用到的set和get函数。 使用内联汇编提升性能。 使用位图优化内存占用。 无锁队列kfifo。 1.2. 控制编译时行为 O2或 O3,编译时优化汇编代码。...
1. 背景 引入jump label的背景,参考Linux: Jump label实现简析 在内核代码中,有很多分支判断条件,它们在绝大多数情形下,都是不成立的。尽管我们已经加上unlikely修饰来进行优化,但是,读取 condition 仍然要访问内存,仍然需要用到cache;另外,也会CPU分支预测失败。虽然少数这样的代码影响不大,但当这样的条件判断代码(如内核中大量的tracepoint)增多的时候,将对cache会造成很大压力,所有这些代码导致的cache miss,以及CPU分支预测失败,所造成的性能损失,就变得可观起来。因此,内核需要一种方案,来解决这样的问题。这个解决方案,就是本文描述的 Jump label。...
保证内核启动安全的几种方式 禁止修改cmdline 禁止修改根文件系统 使能内核地址空间布局随机化(KASLR)
1. 后缀说明 acquire操作指的是在这条语句之后的所有内存操作只准在这条语句之后,不准被提前到这条语句之前。 release操作指的是在这条语句之前的所有内存操作只准在这条语句之前,不准被延后到这条语句之后。 relaxed操作指的是不保证任何的内存顺序。 2. 读写 1atomic_read(const atomic_t *v) 2atomic_read_acquire(const atomic_t *v) 3 4atomic_set(atomic_t *v, int i) 5atomic_set_release(atomic_t *v, int i) col1 col2 (const atomic_t *v)...
ARM64汇编宏:adr_l
ERR_PTR、PTR_ERR