KDIR ?= $(shell uname -r)
Run Code Online (Sandbox Code Playgroud)
是什么意思?=?
我已经明白之间的差别:=,+=并=从堆栈溢出可用,但无法另一个线程来寻找解释?=.
我正在尝试编写一些简单的测试代码作为挂钩系统调用表的演示.
"sys_call_table"不再在2.6中导出,所以我只是从System.map文件中获取地址,我可以看到它是正确的(通过我发现的地址查看内存,我可以看到指向系统调用).
但是,当我尝试修改此表时,内核给出"Oops","无法在虚拟地址c061e4f4处理内核分页请求"并且机器重新启动.
这是运行2.6.18-164.10.1.el5的CentOS 5.4.是否有某种保护或我只是有一个错误?我知道它带有SELinux,我已经尝试将它放入许可模式,但它并没有什么区别
这是我的代码:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
void **sys_call_table;
asmlinkage int (*original_call) (const char*, int, int);
asmlinkage int our_sys_open(const char* file, int flags, int mode)
{
printk("A file was opened\n");
return original_call(file, flags, mode);
}
int init_module()
{
// sys_call_table address in System.map
sys_call_table = (void*)0xc061e4e0;
original_call = sys_call_table[__NR_open];
// Hook: Crashes here
sys_call_table[__NR_open] = our_sys_open;
}
void cleanup_module()
{
// Restore the original call
sys_call_table[__NR_open] = original_call;
}
Run Code Online (Sandbox Code Playgroud) Linux编程接口在第3章中有一个练习,如下所示:
当使用Linux特有重新启动()系统调用来重新启动系统,第二个参数,magic2,必须被指定为一组幻数(例如,LINUX_REBOOT_MAGIC2)中的一个.这些数字有什么意义?(将它们转换为十六进制提供了线索.)
该手册页告诉我们magic2可以LINUX_REBOOT_MAGIC2(672274793),LINUX_REBOOT_MAGIC2A(85072278),LINUX_REBOOT_MAGIC2B(369367448),或LINUX_REBOOT_MAGIC2C(537993216)之一.我没能用十六进制解读它们的含义.我也看了一下/usr/include/linux/reboot.h,也没有给出任何有用的评论.
然后我在内核的源代码中搜索了它sys_reboot的定义.我发现的只是头文件中的声明.
因此,我的第一个问题是,这些数字有什么意义?我的第二个问题是,在哪里sys_reboot定义,你是如何找到它的?
编辑:我在中找到了定义kernel/sys.c.我只是贪图sys_reboot,忘了grep的MAGIC数字.我认为定义必须隐藏在一些宏技巧背后,所以我查看了下面的System.map文件/boot,并在旁边找到它ctrl_alt_del.然后我抓住那个符号,这导致我找到了正确的文件.如果我从源代码编译内核,我可以尝试找到定义符号的对象文件,并从那里开始.
在这个问题的帮助下,我想学习并填补我的知识空白.
因此,用户正在运行一个线程(内核级),它现在调用yield(我假设的系统调用).调度程序现在必须将当前线程的上下文保存在TCB中(存储在内核中的某个地方)并选择另一个线程来运行并加载其上下文并跳转到它CS:EIP.为了缩小范围,我正在开发基于x86架构的Linux.现在,我想了解详细信息:
所以,首先我们有一个系统调用:
1)包装函数yield将把系统调用参数推送到堆栈.按下返回地址并产生一个中断,系统调用号码被推到某个寄存器上(比方说EAX).
2)中断将CPU模式从用户更改为内核并跳转到中断向量表并从那里到内核中的实际系统调用.
3)我猜调度程序现在被调用,现在它必须保存TCB中的当前状态.这是我的困境.因为,调度器将使用内核堆栈,而不是用于执行其操作(这意味着该用户堆栈SS和SP必须被改变),它是如何存储的用户的状态,而不会在该过程修改任何寄存器.我在论坛上看到有关于保存状态的特殊硬件指令,但是调度程序如何访问它们以及谁运行这些指令以及何时执行?
4)调度程序现在将状态存储到TCB中并加载另一个TCB.
5)当调度程序运行原始线程时,控件返回到包装器函数,该函数清除堆栈并恢复线程.
附带问题:调度程序是否作为仅内核线程(即只能运行内核代码的线程)运行?每个内核线程或每个进程都有一个单独的内核堆栈吗?
在Linux实时进程优先级范围1到99中,我不清楚哪个是最高优先级,1或99.
"理解Linux内核"(O'Reilly)的第7.2.2节说1是最高优先级,考虑到正常进程具有从100到139的静态优先级,其中100是最高优先级,这是有意义的:
"每个实时进程都与实时优先级相关联,实时优先级是从1(最高优先级)到99(最低优先级)的值."
另一方面,sched_setscheduler手册页(RHEL 6.1)声称99是最高的:
"在一个实时策略(SCHED_FIFO,SCHED_RR)下调度的进程的sched_priority值在1(低)到99(高)范围内."
哪个是最高的实时优先级?
我希望有人可以解释linux内核源代码中使用的__user宏的细微差别.
首先,宏观:
# define __user __attribute__((noderef, address_space(1)))
Run Code Online (Sandbox Code Playgroud)
现在,经过一些谷歌搜索后,我读到这个宏允许一个指针指定属于用户地址空间,并且不应该取消引用它.
我可能会遗漏一些明显的事实,但有人可以解释这样一个宏的含义吗?例如,这个宏的使用位置有什么好的例子?如果我错过了一些明显的东西,请再次原谅我.
为了把它放在某些环境中,我在检查一些USB代码(linux/usbdevice_fs.h)时遇到了宏.我只是在寻找对内核中使用的这个宏(或其他类似的宏)的一般理解.
谢谢你的期待!
在kernel.h中, min定义为:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
Run Code Online (Sandbox Code Playgroud)
我不明白这行(void) (&_min1 == &_min2);是做什么的.是某种类型检查还是什么?
static struct ctl_table ip_ct_sysctl_table[] = {
{
.procname = "ip_conntrack_max",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
// ...
{
.procname = "ip_conntrack_log_invalid",
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &log_invalid_proto_min,
.extra2 = &log_invalid_proto_max,
},
{ }
};
Run Code Online (Sandbox Code Playgroud)
这里的结构数组以{ }. 添加的目的是什么?
顺便说一句,在这段代码上方有另一个structs 数组,但最后没有空大括号。
什么时候应该在结构数组的末尾使用空大括号?
借助Android 4.4 KitKat,Google正在将Linux内核升级到3.8版,这是Docker所需的内核版本.
我不知道AUFS部分,但有没有办法在Android上使用此更新运行docker容器?
我以前想过平台驱动程序以及普通设备驱动程序,如:
普通设备驱动程序适用于与proccesor芯片连接的驱动程序.在遇到一个i2c驱动程序之前.
但在这里,我正在阅读通过定义为平台驱动程序的多功能i2c驱动程序.我通过了https://www.kernel.org/doc/Documentation/driver-model/platform.txt.但是仍然无法清楚地想出如何定义驱动程序,例如onchip和接口设备.我也经历了这个链接.. http://meld.org/discussion/general-discussion/platform-driver-vs-ordinary-device-drivers
请有人解释一下.