博文

目前显示的是 一月, 2011的博文

XEN-ARM定时器管理算法简要总结

/* XEN-ARM的定时器优先队列管理算法采用的是最小堆。关于最小堆的知识,请参考 《算法导论》第二版第6章堆。 下面是简要流程。欢迎讨论 */ /*初始化定时器*/ void __init timer_init(void) { static struct timer *dummy_heap; int i; open_softirq(TIMER_SOFTIRQ, timer_softirq_action); /* * All CPUs initially share an empty dummy heap. Only those CPUs that * are brought online will be dynamically allocated their own heap. */ SET_HEAP_SIZE(&dummy_heap, 0); SET_HEAP_LIMIT(&dummy_heap, 0); for ( i = 0; i < NR_CPUS; i++ ) { spin_lock_init(&timers[i].lock); timers[i].heap = &dummy_heap; } } /* 当软中断发生时,函数执行 在定时器优先队列中查找满足expires的定时器,从队列中摘除,然后执行之 */ static void timer_softirq_action(void) { int           cpu = smp_processor_id(); struct timer *t, **heap; s_time_t      now; void        (*fn)(void *); void         *data; DPRINTK(5, "%s:%d\n", __FUNCTION__, __LINE__); spin_lock_irq(&timers[cpu].lock); do { heap = timers[cpu].heap; now  = NOW(); //以此取定时器优先队列中最优先定时器 //然后执行其过程 while ( (GET_HEAP_SIZE(heap) != 0) && ( (t = heap[1])->expi...

gcc装载具体库的的方法总结

注:该总结主要来自: bugfly z 的buzz.感谢bugfly z,以及回帖的盆友,如果有不完善的地方,欢迎拍砖。 1.环境变量LD_PRELOAD LD_PRELOAD 后面接的是具体的库文件全路径,可以接多个 参考:http://blog.csdn.net/haoel/archive/2007/05/09/1602108.aspx 2.是方案1的变体。直接把库名加到列表加到/etc/ld.so.preload. 该方法会影响到系统里所有应用。 程序加载时,LD_PRELOAD加载路径优先级高于/etc/ld.so.preload 3. 环境变量LD_LIBRARY_PATH LD_LIBRARY_PATH 指定查找路径,这个路径优先级别高于系统预设的路径 假如现在需要在已有的环境变量上添加新的路径名,则采用如下方式: LD_LIBRARY_PATH=NEWDIRS:$LD_LIBRARY_PATH.(newdirs是新的路径串) 4. gcc 中的 -L 和 -l参数  -Wl参数 放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放在这三个目录里,而是放在其他目录里,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。 -Wl,表示后面的参数将传给link程序ld 5.LD程序硬编码了一些库搜索路径 查看方法: 00653000-0066e000 r-xp 00000000 08:07 1320479 /lib/ld-2.11.1.so 0066e000-0066f000 r--p 0001a000 08:07 1320479 /lib/ld-2.11.1.so 0066f000-00670000 rw-p 0001b000 08:07 1320479 /lib/ld-2.11.1.so $ strings /lib/ld-2.11.1.so | grep lib ... display library search paths /lib/ /usr/lib/ /lib/i486-linux-gnu/ /usr/lib/i486-linux-gnu/ ...

xenarm irq routine

/*  当一个异常出现以后,ARM微处理器会执行以下几步操作: (这些是中断发生时,自动处理的)  1、 将下一条指令的地址存入相应连接寄存器LR,以便程序在处理异常返回时能从正确的位置重新开始执行。若异常是从ARM状态进入,LR寄存器中保存的是下一 条指令的地址(当前PC+4或PC+8,与异常的类型有关);若异常是从Thumb状态进入,则在LR寄存器中保存当前 PC的偏移量,这样,异常处理程序就不需要确定异常是从何种状态进入的。例如:在软件中断异常SWI,指令MOV PC,R14_svc总是返回到下一条指令,不管SWI是在ARM状态执行,还是在Thumb状态执行。  2、将CPSR复制到相应的SPSR中。  3、根据异常类型,强制设置CPSR的运行模式位。  4、 强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。还可以设置中断禁止位,以禁止中断发生.当有异常发生时,处理器会跳转 到对应的0xffff0000起始的向量处取指令,然后,通过b指令散转到异常处理代码.因为ARM中b指令是相对跳转,而 且只有+/-32MB的寻址范围,所以把__stubs_start~__stubs_end之间的异常处理代码复制到了0xffff0200起始处.这 里可直接用b指令跳转过去,这样比使用绝对跳转(ldr)效率高。   */         b       vector_undefined_instruction + stubs_offset         ldr     pc, .LCvswi + stubs_offset         b       vector_prefetch_abort + stubs_offset         b       vector_data_abort + stubs_offset         b       vector_addrexcptn + stubs_offset         b       vector_irq + stubs_offset         b       vector_FIQ + stubs_offset #define INSTALL_VECTOR_STUB(name, offset, mode, correction, branch_table)         ...