关于软中断和系统调用的一点分析
来源:互联网 发布:六场预测法 知乎 编辑:程序博客网 时间:2024/06/06 03:50
感觉之前对于软中断一直有一些误解。
软中断的定义:
软中断是利用硬件中断的概念,用软件方式进行模拟,实现宏观上的异步执行效果。很多情况下,软中断和“信号”类似。同时,软中断又是和硬中断相对应的,“硬中断是外部设备对CPU的中断”,“软中断通常是硬件中断服务程序对内核的中断”
作为系统调用而言,对于i386则是通过软中断int80实现
对于其它的软中断,则是在硬件中断之后触发的软中断。
系统调用在Linux2.6中的实现
set_system_trap_gate(SYSCALL_VECTOR, &system_call);# define SYSCALL_VECTOR0x80ENTRY(system_call)RING0_INT_FRAME# can't unwind into user space anywaypushl_cfi %eax# save orig_eaxSAVE_ALLGET_THREAD_INFO(%ebp)# system call tracing in operation / emulationtestl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)jnz syscall_trace_entrycmpl $(nr_syscalls), %eaxjae syscall_badsyssyscall_call:call *sys_call_table(,%eax,4)movl %eax,PT_EAX(%esp)# store the return value ENTRY(sys_call_table).long sys_restart_syscall/* 0 - old "setup()" system call, used for restarting */.long sys_exit.long ptregs_fork.long sys_read.long sys_write.long sys_open/* 5 */.long sys_close.long sys_waitpid.long sys_creat.long sys_link.long sys_unlink/* 10 */.long ptregs_execve.long sys_chdir.long sys_time.long sys_mknod.long sys_chmod/* 15 */.long sys_lchown16.long sys_ni_syscall/* old break syscall holder */.long sys_stat.long sys_lseek.long sys_getpid/* 20 */.long sys_mount.long sys_oldumount...
对于软中断而言,则稍微复杂些
1.注册软中断当然是通过open_softirq
例子如下:
[cpp]
view plain
copy
- void __init init_timers(void)
- {
- int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
- (void *)(long)smp_processor_id());
- init_timer_stats();
- BUG_ON(err == NOTIFY_BAD);
- register_cpu_notifier(&timers_nb);
- open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
- }
- void open_softirq(int nr, void (*action)(struct softirq_action *))
- {
- softirq_vec[nr].action = action;
- }
软中断TIMER_SOFTIRQ的中断处理函数为:run_timer_softirq
之所以成为softirq,是因为这些中断是由硬件中断来间接触发的,如何间接触发的呢:
硬件中断处理函数-->对软中断的相应位置位-->唤醒ksoftirqd线程-->执行软中断的中断处理函数
2.硬件中断如何通过置位唤醒ksoftirqd线程
timer interrupthandler->
timer_tick->
update_process_times->
run_local_timers->
hrtimer_run_queues()和raise_softirq(TIMER_SOFTIRQ)->
raise_softirq_irqoff->
__raise_softirq_irqoff{ or_softirq_pending(1UL << (nr)); }
即(local_softirq_pending() |= (x))
3.如何执行软中断的action<中断处理函数>
对于TIMER_SOFTIRQ来说,每次system clock产生中断时,即一个tick到来时,在system clock的中断处理函数中会调用run_local_timers来设置TIMER_SOFTIRQ触发条件;也就是当前CPU对应的irq_cpustat_t结构体中的__softirq_pending成员的第TIMER_SOFTIRQ个BIT被置为1。而当这个条件满足时,ksoftirqd线程(入口函数run_ksoftirqd,cpu_callback:kthread_create(run_ksoftirqd,hcpu, "ksoftirqd/%d", hotcpu);)会被唤醒,然后按照下面的流程调用TIMER_SOFTIRQ在数组softirq_vec中注册的action,即run_timer_softirq。
run_ksoftirqd--->do_softirq--->__do_softirq--->softirq_vec[TIMER_SOFTIRQ].action
[cpp]
view plain
copy
- static int run_ksoftirqd(void * __bind_cpu)
- {
- set_current_state(TASK_INTERRUPTIBLE);
- while (!kthread_should_stop()) {
- preempt_disable();
- if (!local_softirq_pending()) {
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
- __set_current_state(TASK_RUNNING);
- while (local_softirq_pending()) {
- /* Preempt disable stops cpu going offline.
- If already offline, we'll be on wrong CPU:
- don't process */
- if (cpu_is_offline((long)__bind_cpu))
- goto wait_to_die;
- do_softirq();
- preempt_enable_no_resched();
- cond_resched();
- preempt_disable();
- rcu_sched_qs((long)__bind_cpu);
- }
- preempt_enable();
- set_current_state(TASK_INTERRUPTIBLE);
- }
- __set_current_state(TASK_RUNNING);
- return 0;
- wait_to_die:
- preempt_enable();
- /* Wait for kthread_stop */
- set_current_state(TASK_INTERRUPTIBLE);
- while (!kthread_should_stop()) {
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- }
- __set_current_state(TASK_RUNNING);
- return 0;
- }
From <http://blog.csdn.net/myarrow/article/details/7064060>
从上面两种情况的对比可以看出,系统调用的中断由于是软件触发的中断,所以称为软中断,而对于后者的软中断,虽然也是软件触发,但是并不经过中断向量表。
- 关于软中断和系统调用的一点分析
- 关于中断和系统调用
- 中断的系统调用
- 中断的系统调用
- 个人学习笔记---软中断(下半部)和软件中断(系统调用)的区别
- linux内核中断、异常、系统调用的分析以及实践
- linux内核中断、异常、系统调用的分析以及实践
- linux内核中断、异常、系统调用的分析以及实践
- linux内核中断、异常、系统调用的分析以及实践
- 关于信号中断与慢系统调用的深度发现
- Linux系统的中断、系统调用和调度概述
- Linux系统的中断、系统调用和调度概述
- 中断、异常和系统调用
- 中断、异常和系统调用
- 中断、异常和系统调用
- 关于Windows中断的一点疑惑
- 关于函数调用和尾递归的一点认识
- linux 系统中断的分析
- 第一章 系统环境 1.5习题 1.6上机实训
- ZigBee研究之旅(二)---IAR软件设置
- Android 防止控件被重复点击
- channelartlist|频道文档
- 参加工作已经5个月了
- 关于软中断和系统调用的一点分析
- C++中Operator类型强制转换成员函数
- 编译ffmpeg neon时出现的问题
- 次时代的交互新体验 - DS325上手测评
- java日期时间格式
- 使用intent.setflags来区分Activity是否打开
- 堆排序
- 一份诚恳的互联网找工作总结和感想(附:怎样花两年时间去面试一个人)
- MCI(媒体控制接口)相关知识