Linux Kernel development (3)

Kernel Data Structures

The linked-list code is declared in the header file and the data structure is simple:

Usage is slightly different in kernel versions prior to 2.6.33—doublecheck before writing code

rbtrees The Linux implementation of red-black trees is called rbtrees.They are defined in lib/rbtree.c

 

Interrupts and Interrupt Handlers

Interrupt Handlers

The interrupt handler for a device is part of the device’s driver—the kernel code that manages the device.

Top Halves Versus Bottom Halves

These two goals—that an interrupt handler execute quickly and perform a large amount of work—clearly conflict with one another.

Because of these competing goals, the processing of interrupts is split into two parts, or halves.The interrupt handler is the top half. The top half is run immediately upon receipt of the interrupt and performs only the work that is time-critical, such as acknowledging receipt of the interrupt or resetting the hardware.Work that can be performed later is deferred until the bottom half.

Registering an Interrupt Handler

/* request_irq: allocate a given interrupt line */
int request_irq(unsigned int irq,
irq_handler_t handler,
unsigned long flags,
const char *name,
void *dev)

On registration, an entry corresponding to the interrupt is created in /proc/irq.The function proc_mkdir() creates new procfs entries.

Writing an Interrupt Handler

static irqreturn_t intr_handler(int irq, void *dev)

Interrupt Context

Therefore, you cannot call certain functions from interrupt context. If a function sleeps, you cannot use it from your interrupt handler—this limits the functions that one can call from an interrupt handler.

Interrupt context is time-critical because the interrupt handler interrupts other code. Code should be quick and simple. Busy looping is possible, but discouraged.This is an
important point; always keep in mind that your interrupt handler has interrupted other code (possibly even another interrupt handler on a different line!).

Early in the 2.6 kernel process, an option was added to reduce the stack size from two pages down to one, providing only a 4KB stack on 32-bit systems.This reduced memory pressure because every process on the system previously needed two pages of contiguous, nonswappable kernel memory.To cope with the reduced stack size, interrupt handlers were given their own stack, one stack per processor, one page in size.

Implementing Interrupt Handlers

image

unsigned int do_IRQ(struct pt_regs regs)

kernel/irq/handler.c

/proc/interrupts

Interrupt Control

Because Linux supports multiple processors, kernel code more generally needs to obtain some sort of lock to prevent another processor from accessing shared data simultaneously.These locks are often obtained in conjunction with disabling local interrupts.

Disabling and Enabling Interrupts

local_irq_disable();
/* interrupts are disabled .. */
local_irq_enable();

In other words, they disable and enable interrupt delivery on the issuing processor.

Disabling a Specific Interrupt Line

All three of these functions can be called from interrupt or process context and do not sleep. If calling from interrupt context, be careful! You do not want, for example, to enable an interrupt line while you are handling it. (Recall that the interrupt line of a handler is masked out while it is serviced.)

Status of the Interrupt System

in_interrupt()
in_irq()
The most useful is the first: It returns nonzero if the kernel is performing any type of interrupt handling.This includes either executing an interrupt handler or a bottom half handler.The macro in_irq() returns nonzero only if the kernel is specifically executing an interrupt handler.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值