![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
内核之美
文章平均质量分 75
zwmyxfbenet
这个作者很懒,什么都没留下…
展开
-
Linux内核参数
/* *在include/linux/autoconf.h中定义,也即是在通过make menuconfig中进行手动配置产生的*/#define CONFIG_CMDLINE "console=ttySAC0,115200" static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CM原创 2014-05-06 14:58:16 · 671 阅读 · 0 评论 -
Linux中断子系统
这个中断系列文章主要针对移动设备中的Linux进行讨论,文中的例子基本都是基于ARM这一体系架构,其他架构的原理其实也差不多,区别只是其中的硬件抽象层。内核版本基于3.3。虽然内核的版本不断地提升,不过自从上一次变更到当前的通用中断子系统后,大的框架性的东西并没有太大的改变。 /************************************************转载 2014-06-05 15:04:40 · 415 阅读 · 0 评论 -
linux UART驱动 三
当我们打开一个串口(UART)设备的时候,实际上调用的是 tty_open 函数static int tty_open(struct inode *inode, struct file *filp){int ret;lock_kernel();ret = __tty_open(inode, filp);unlock_kernel();return ret原创 2014-06-25 14:41:20 · 908 阅读 · 0 评论 -
linux等待队列
等待队列头的结构体声明如下:定义并初始化一个等待队列头#define DECLARE_WAIT_QUEUE_HEAD(name) \wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \.lock原创 2014-06-26 16:16:46 · 423 阅读 · 0 评论 -
工作队列
工作队列是一种将工作推后执行的机制。工作队列可以把工作推后,交由一个内核线程去执行,它是中断下半部分实现的一种形式,而且它总是会在进程上下文中执行。这样,通过工作队列执行的代码能占尽进程上下文的所有优势。最重要的就是工作队列允许重新调度甚至是睡眠。工作的结构体声明typedef void (*work_func_t)(struct work_struct *work);原创 2014-06-27 15:12:38 · 429 阅读 · 0 评论 -
中断上下文和进程上下文
内核空间和用户空间是操作系统理论的基础之一,即内核功能模块运行在内核空间,而应用程序运行在用户空间。现代的CPU都具有不同的操作模式,代表不同的级别,不同的级别具有不同的功能,在较低的级别中将禁止某些操作。Linux系统设计时利用了这种硬件特性,使用了两个级别,最高级别和最低级别,内核运行在最高级别(内核态),这个级别可以进行所有操作,而应用程序运行在较低级别(用户态),在这个级别,处理器控制着对转载 2014-07-01 11:26:51 · 466 阅读 · 0 评论 -
ARM Linux对中断的处理--相关数据结构
中断处理依赖于中断的类型:I/O中断、时钟中断和处理器间中断。不管引起中断的电路的种类如何,所有I/O中断处理程序都执行四个相同的基本操作:1、在内核态堆栈中保存IRQ的值和寄存器的内容。2、为正在给IRQ线服务的PIC发送一个应答,这将允许PIC进一步发出中断。3、执行共享这个IRQ的所有设备的中断服务例程。与中断处理相关的数据结构Linux系统里每个中断通过一个称为中断转载 2014-07-01 15:20:52 · 680 阅读 · 0 评论 -
ARM Linux对中断的处理--中断处理
中断处理OK,接下来,终于可以来研究中断处理了,也就是,我们辛辛苦苦添加进系统的中断处理例程被调用的整个过程。不过,在分析源代码之前,还是让我们先了解一些原理性的东西, 我们都知道在处理中断时要保存现场,然后才能处理中断,处理完之后还要把现场状态恢复过来才能返回到被中断的地方继续执行,这里要说明的是在指令跳转到中断向量的地方开始执行之前,由CPU自动帮我们做了哪些事情: R14_i转载 2014-07-01 15:49:46 · 726 阅读 · 0 评论 -
devices_init
int __init devices_init(void){ devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); if (!devices_kset) return -ENOMEM; dev_kobj = kobject_create_and_add("dev", NULL); if (!d原创 2014-06-11 14:30:36 · 650 阅读 · 0 评论 -
ARM Linux对中断的处理--中断管理系统的初始化
中断管理系统的初始化中断管理系统的初始化我们先来看一下Linux系统中,中断管理系统的初始化。中断系统的初始化主要由几个函数来完成。在系统初始化的start_kernel()函数 (在文件init/main.c中定义)中可以看到:asmlinkage void __init start_kernel(void){…… trap_init();…… early_irq_转载 2014-07-01 15:30:22 · 952 阅读 · 0 评论 -
ARM Linux对中断的处理--中断处理
中断处理OK,接下来,终于可以来研究中断处理了,也就是,我们辛辛苦苦添加进系统的中断处理例程被调用的整个过程。不过,在分析源代码之前,还是让我们先了解一些原理性的东西, 我们都知道在处理中断时要保存现场,然后才能处理中断,处理完之后还要把现场状态恢复过来才能返回到被中断的地方继续执行,这里要说明的是在指令跳转到中断向量的地方开始执行之前,由CPU自动帮我们做了哪些事情: R14_i转载 2014-07-01 15:54:23 · 424 阅读 · 0 评论 -
中断处理
中断处理OK,接下来,终于可以来研究中断处理了,也就是,我们辛辛苦苦添加进系统的中断处理例程被调用的整个过程。不过,在分析源代码之前,还是让我们先了解一些原理性的东西, 我们都知道在处理中断时要保存现场,然后才能处理中断,处理完之后还要把现场状态恢复过来才能返回到被中断的地方继续执行,这里要说明的是在指令跳转到中断向量的地方开始执行之前,由CPU自动帮我们做了哪些事情: R14_i转载 2014-07-01 15:57:31 · 582 阅读 · 0 评论 -
ARM Linux对中断的处理--中断注册方法
中断注册方法在驱动程序中,要想使设备能够产生中断,则首先需要调用request_irq()来分配中断线。在通过request_irq()函数注册中断服务程序的时候,将会把设备中断处理程序添加进系统,以在中断发生的时候调用相应的中断处理程序。我们来看一下request_irq()函数的定义:---------------------------------------------------转载 2014-07-01 15:34:35 · 1502 阅读 · 0 评论 -
linux UART驱动 二
module_init(s3c2440_serial_init);static int __init s3c2440_serial_init(void){ return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);}int s3c24xx_serial_init(struct platform_driv原创 2014-06-25 11:08:54 · 693 阅读 · 0 评论 -
I/O端口
I/O端口 关键词:设备管理、驱动程序、I/O端口、资源 申明:这份文档是按照自由软件开放源代码的精神发布的,任何人可以免费获得、使用和重新发布,但是你没有限制别人重新发布你发布内容的权利。发布本文的目的是希望它能对读者有用,但没有任何担保,甚至没有适合特定目的的隐含的担保。更详细的情况请参阅GNU通用公共许可证(GPL),以及GNU自由文档协议(GFDL)。 几转载 2014-06-04 15:20:02 · 507 阅读 · 0 评论 -
内核判断大小端的代码
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };#define ENDIANNESS ((char)endian_test.l)原创 2014-06-04 09:33:38 · 546 阅读 · 0 评论 -
find_node_limits
#define PAGE_SHIFT 12#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) /*=4KB*/#define PAGE_MASK (~(PAGE_SIZE-1)) /*=0xffff f000*/#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)#define bank_p原创 2014-05-09 10:58:30 · 445 阅读 · 0 评论 -
find_bootmap_pfn
static unsigned int __initfind_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages){ unsigned int start_pfn, i, bootmap_pfn; /*_end 表示内核映像的结束地址(虚拟地址) __pa(_end) 表示内核映像的结束地址(物原创 2014-05-13 11:19:59 · 533 阅读 · 0 评论 -
free_bootmem_node
假如内存的物理起始地址为:0x30000000, 大小为:0x1000000void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, unsigned long size){ unsigned long start, end; //空函数 kmemleak_free_part(__原创 2014-05-13 14:41:44 · 492 阅读 · 0 评论 -
reserve_node_zero
假如内存的物理起始地址为:0x30000000, 大小为:0x1000000void __init reserve_node_zero(pg_data_t *pgdat){ unsigned long res_size = 0; /* * Register the kernel text and data with bootmem. * Note that this c原创 2014-05-13 15:22:17 · 486 阅读 · 0 评论 -
bootmem_bootmap_pages
unsigned long __init bootmem_bootmap_pages(unsigned long pages){ unsigned long bytes = bootmap_bytes(pages); return PAGE_ALIGN(bytes) >> PAGE_SHIFT;}原创 2014-05-13 10:49:25 · 683 阅读 · 0 评论 -
reserve_bootmem_node
假如内存的物理起始地址为:0x30000000, 大小为:0x1000000原创 2014-05-13 15:11:14 · 628 阅读 · 0 评论 -
init_bootmem_node
unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn){ return init_bootmem_core(pgdat->bdata, freepfn, startpfn, endpfn);原创 2014-05-13 11:58:52 · 570 阅读 · 0 评论 -
MACHINE_START
#define MACHINE_START(_type,_name) \static const struct machine_desc __mach_desc_##_type \ __used \ __attribute__((__section__(".arch.info.init"))) = { \ .nr = MACH_TYPE_##_type, \ .nam原创 2014-05-14 14:29:47 · 1020 阅读 · 0 评论 -
Linux内核 ALIGN PAGE_ALIGN
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)写简单点,宏ALIGN实际上是这样定义的#define ALIGN(x, a) (x + (a - 1)) & ~(a - 1)并且在计算的过程中将a强制转换成x的类型该宏原创 2014-05-13 10:09:08 · 1641 阅读 · 0 评论 -
bootmem_free_node
假如内存的物理起始地址为:0x30000000, 大小为:0x1000000原创 2014-05-14 13:12:37 · 775 阅读 · 0 评论 -
create_mapping
本文描述的是关于MINI2440开发板上的SDRAM的内存映射(bootmem阶段)硬件的基本参数为:起始物理地址:0x30000000物理内存大小:0x1000000 [16MB]那么基于以上信息,在初始化过程中下面的变量已经被赋为如下的值:bank.start = 0x30000000 bank.size = 0x1000000[16MB]通过阅读代码可以原创 2014-05-12 17:53:00 · 1056 阅读 · 0 评论 -
htons htonl
#define ___htons(x) __cpu_to_be16(x)#define __force __attribute__((force))typedef unsigned short __u16;typedef __u16 __bitwise __be16;#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))//l原创 2014-06-04 11:00:44 · 679 阅读 · 0 评论 -
linux UART驱动
module_init(s3c24xx_serial_modinit);static int __init s3c24xx_serial_modinit(void){ int ret; ret = uart_register_driver(&s3c24xx_uart_drv); if (ret < 0) { printk(KERN_ERR "failed to register原创 2014-06-24 17:54:50 · 877 阅读 · 0 评论 -
s3c2440 UART设备结构体的定义
static int __init s3c_arch_init(void){ int ret; // do the correct[正确的] init for cpu if (cpu == NULL) panic("s3c_arch_init: NULL cpu\n"); ret = (cpu->init)(); if (ret != 0) return ret; r原创 2014-06-19 14:22:12 · 739 阅读 · 0 评论