Tag: 内核

为什么操作系统需要/维护内核线程?

以下是我遇到的三种线程模型。 基于以下3种体系结构,对于我来说,除了作为POSIX.1C的一部分引入的用户线程之外,还存在一些称为内核线程的新内容。 这是1-1型号 这是N-1型号。 这是混合模型。 对于内核线程,我已经经历了很多关于SO的问题。 这看起来更相关的链接以便澄清。 在进程级别,对于Linux加载器(例如)加载的每个用户进程,内核不会为执行用户进程提出的机器指令分配相应的内核进程。 用户进程只需要内核模式执行,当它需要来自内核模块的工具时[如malloc()/ fork()]。 用户进程的调度由OS调度程序完成并分配CPU核心。 例如,用户进程不需要内核执行模式来执行指令 a=a+2;//a is my local variable in a user level C function 我的问题: 1)那么,内核级线程的目的是什么? 为什么操作系统需要为用户级进程的相应用户线程维护内核线程(另外)? 用户模式编程器是否可以通过编程为给定的用户进程选择上述三种线程模型中的任何一种? 在我理解第一个问题的答案后,一个相关的补充是, 2)内核线程实际上是由OS调度程序而不是用户线程调度的吗?

错误13:使用字符串文字在grub中启动简单内核时,可执行文件无效或不受支持

我写了一个简单的内核,试图将两个字符写入帧缓冲区。 如果我在内核中定义一个字符串文字,我在启动时会得到以下输出: Booting ‘os’ kernel /boot/kernel.elf Error 13: Invalid or unsupported executable format Press any key to continue… 否则,如果我定义了两个字符,我得到以下内容(注意输出开头的’ab’): abBooting ‘os’ kernel /boot/kernel.elf [Multiboot-elf, , , shtab=0x102168, entry=0x1001f0] 装载机 我在汇编中编写了加载程序: global loader ; the entry symbol for ELF MAGIC_NUMBER equ 0x1BADB002 ; define the magic number constant FLAGS equ 0x0 ; multiboot flags CHECKSUM equ […]

为什么这个0((类型*)0) – >成员在C?

Linux内核中的container_of()宏定义为: #define container_of(ptr, type, member) ({ \ const typeof( ((type*)0)->member) * __mptr =(ptr);\ (type*)( (char*)__mptr – offsetof(type,member) );}) 为什么这样使用((type*)0)->member ,而不是(type*)->member ?

如何在内核模块代码中包含C backtrace?

所以我试图找出哪些内核进程正在调用块驱动程序中的某些函数。 我认为在C库中包含backtrace()会让它变得简单。 但我无法加载回溯。 我复制了这个示例函数来显示回溯: http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html 所有编译尝试都在一个或另一个地方发生错误,导致无法找到文件或未定义函数。 这是最接近的。 在Makefile中我放了编译器指令: -rdynamic -I/usr/include 如果我省略第二个,-I / usr / include,那么编译器报告它找不到所需的头文件execinfo.h。 接下来,在我想要做回溯的代码中,我从示例中复制了该函数: //trying to include the c backtrace capability #include void show_stackframe() { void *trace[16]; char **messages = (char **)NULL; int i, trace_size = 0; trace_size = backtrace(trace, 16); messages = backtrace_symbols(trace, trace_size); printk(KERN_ERR “[bt] Execution path:\n”); for (i=0; i<trace_size; ++i) […]

在intel 64bit机器上启用/禁用缓存:CD位始终设置?

我试图在Xen中禁用我的机器Intel(R)Xeon(R)CPU E5-1650 v2 @ 3.50GHz的所有级别的缓存。 我写了一个工具来调用以下汇编代码来禁用/启用缓存并显示CR0寄存器的值。 case XENMEM_disable_cache: __asm__ __volatile__( “pushq %%rax\n\t” “movq %%cr0,%%rax\n\t” “orq $0x40000000,%%rax\n\t” “movq %%rax,%%cr0\n\t” “movq %%cr0, %0\n\t” “wbinvd\n\t” “popq %%rax” : “=r”(cr0) : :); // gdprintk(XENLOG_WARNING, “gdprintk:XENMEM_disable_cache disable cache! // TODO IMPLEMENT\n”); printk(“printk: disable cache! cr0=%#018lx\n”, cr0); rc = 0; break; case XENMEM_enable_cache: __asm__ __volatile__( “pushq %%rax\n\t” “movq %%cr0,%%rax\n\t” “andq $0xffffffffbfffffff,%%rax\n\t” […]

通过C中的Netlink从内核到用户空间的多播

我试图编写一个使用Netlink在内核和用户空间之间进行通信的简单程序。 基本上这就是我想要实现的目标: 用户空间程序开始绑定到用户定义的多播组。 插入内核模块 内核模块向此多播组发送消息 用户空间程序接收消息 这是我的代码: ======用户空间程序====== #include #include #include #include #include #include #include #define MYPROTO NETLINK_USERSOCK #define MYMGRP 0x21 //User defined group, consistent in both kernel prog and user prog int open_netlink() { int sock = socket(AF_NETLINK,SOCK_RAW,MYPROTO); struct sockaddr_nl addr; memset((void *)&addr, 0, sizeof(addr)); if (sock<0) return sock; addr.nl_family = AF_NETLINK; addr.nl_pid = […]

直接打印到文本video内存时出现意外输出

我正在用C开发一个内核,并在屏幕上创建了一些可以在video内存上打印的内容。 我预计video内存中的第一个字节将是要打印的字符,第二个字节会告诉颜色。 但我的程序有一些不同,但它的工作原理! 这是非常意外和不寻常的。 我的内核代码 – #define VIDEO_MEM 0xb8000 void write_string( int colour, const unsigned char *string ); void main() { unsigned char *vid = (unsigned char*) VIDEO_MEM; int i=0; for (i = 0; i < 2000; i++) { *vid = ' '; *(vid+2) = 0x1f; vid += 2; } write_string(0x1f,"The Kernel has been loaded […]

内核模块上的addr2line

我正在尝试调试内核模块。 我怀疑有一些内存泄漏。 为了检查它,我准备了内核和模块的内存泄漏调试的构建。 我得到了一些警告: [11839.429168] slab error in verify_redzone_free(): cache `size-64′: memory outside object was overwritten [11839.438659] [] (unwind_backtrace+0x0/0x164) from [] (kfree+0x278/0x4d8) [11839.447357] [] (kfree+0x278/0x4d8) from [] (some_function+0x18/0x1c [my_module]) [11839.457214] [] (some_function+0x18/0x1c [my_module]) from [] (some_function+0x174/0x718 [my_module]) [11839.470184] [] (some_function+0x174/0x718 [my_module]) from [] (some_function+0x12c/0x16c [my_module]) [11839.483917] [] (some_function+0x12c/0x16c [my_module]) from [] (some_function+0x8/0x10 [my_module]) [11839.496368] [] […]

如何从另一个模块调用导出的内核模块函数?

我正在编写一个API作为内核模块,为设备驱动程序提供各种function。 我在mycode.c中写了三个函数。 然后我构建并加载了模块,然后将mycode.h复制到 / include / linux中 。 在设备驱动程序中,我有一个#include 并调用这三个函数。 但是当我构建驱动程序模块时,我收到三个链接器警告,说明这些函数是未定义的 。 笔记: 函数在mycode.h中声明为extern 使用mycode.c中的EXPORT_SYMBOL(func_name)导出函数 运行命令nm mycode.ko显示符号表中可用的所有三个函数(它们旁边的大写字母T,表示符号在文本(代码)部分中找到) 加载模块后,命令grep func_name / proc / kallsyms将所有三个函数显示为已加载 很明显,函数正确导出,内核知道它们的位置和位置。 那么为什么司机不能看到他们的定义呢? 知道我错过了什么吗? 编辑:我在这里找到了一些相关信息: http : //www.kernel.org/doc/Documentation/kbuild/modules.txt 有时,外部模块使用来自另一个外部模块的导出符号。 kbuild需要完全了解所有符号,以避免吐出有关未定义符号的警告。 这种情况存在三种解决方案。 注意:建议使用顶级kbuild文件的方法,但在某些情况下可能不切实际。 使用顶级kbuild文件如果你有两个模块,foo.ko和bar.ko,其中foo.ko需要来自bar.ko的符号,你可以使用一个通用的顶层kbuild文件,所以这两个模块都是用同一个编译的建立。 请考虑以下目录布局: ./foo/ <= contains foo.ko ./bar/ <= contains bar.ko The top-level kbuild file would then look like: #./Kbuild (or ./Makefile): […]