LDD3 D08 01.08 星一

  • 20:50-21:55 p99-p120

    通常, 当你面对一个 oops, 第一件事是查看发生问题的位置, 常常与调用堆栈分开列出. 在上面展示的第一个 oops, 相关的行是:

     

    EIP is at faulty_write+0x4/0x10 [faulty]

     

    这里我们看到, 我们曾在函数 faulty_write, 它位于 faulty 模块( 在方括号中列出的 ). 16 进制数指示指令指针是函数内 4 字节, 函数看来是 10 ( 16 进制 )字节长. 常常这就足够来知道问题是什么.

     

    通过一些工作,我们可以通过栈清单确定局部变量和函数参数的值。

    【Q 哪些工作?】

     

    需要注意的是, 只有在内核编译时,打开了CONFIG_KALLSYMS 选项,我们才能看到符号化的调用栈。

     

    系统挂起

    通过在一些关键点上插入schedule调用,防止死循环。

    注意:schedule会给驱动程序带来代码重入问题。这可以通过使用合适的锁定来解决。但是一定不要在占有自旋锁的任何时候调用schedule。因为很有可能会导致系统死锁。

     

    有时候系统是假死,观察系统时钟是否还在运行可以判断。

     

    学会使用 SysRq魔法键【p100】

    SysRq功能必须在内核配置时启用。

     

    【尝试 SysRq】

     

    调试器和相关工具

    使用gdb

    要熟练使用gdb需要掌握gdb命令,目标平台的汇编代码,还要具备对源代码和优化后的汇编代码进行匹配的能力。

    一个典型的 gdb 调用看来如下:

    gdb /usr/src/linux/vmlinux /proc/kcore

     

    注意:为了使gdb使用内核的符号信息,我们必须打开CONFIG_DEBUG_INFO选项。

     

    我们现在该发出一个 gdb 命令来告诉它关于我们的模块. 我们需要的命令是 add-symble-flile;

    【尝试 gdb, 和  add-symble-flile 命令】

     

    kdb内核调试器

    【尝试p105】

     

    kgdb补丁

    p107

     

    用户模式虚拟机

     

    Linux跟踪工具包

     

    动态探测

     

    第五章 并发和 竞态

    设备驱动开发者必须在开始设计时就考虑到并发因素,并且还必须对内核提供的并发管理机制有坚实的理解。

     

    scull的缺陷

    静态会导致对共享数据的非受控访问

     

    并发及其管理

    设计驱动程序,第一个规则:只要可能,就应该避免资源共享。如尽量减少使用全局变量。

    第二点:要访问共享资源必须显示地使用访问控制技术。即锁定或互斥。

     

    当内核代码创建了一个可能和其他线程共享的对象时,该对象必须在还有其他组件引用自己的情况下保持存在。

    【q 怎样理解?】

     

    信号量和互斥体

    信号量 P和V操作。P 操作对信号量减一, V操作加一

     

    Linux信号量的实现

     

    void down(struct semaphore *sem);

    int down_interruptible(struct semaphore *sem);

    int down_trylock(struct semaphore *sem);

     

    down 减少信号量的值并在必要时一直等待。

    down_interruptible 同样, 但是操作是可中断的.  如果操作被中断, 函数返回一个非零值。 正确的使用 down_interruptible 需要一直检查返回值并且针对性地响应.

    【什么是可中断?不是原子操作?】

     

    最后的一个 down_trylock, 从不休眠; 如果信号量在调用时不可用, down_trylock 立刻返回一个非零值.

     

    completion

    内核编程的一个常见模式是,在当前线程之外初始化某个动作, 接着等待这个动作结束.

     

    自旋锁 spinlock

    和信号量不同,自旋锁可在不能休眠的代码中使用,如中断处理程序。

    【Q 信号量为什么不可以?】

     

    如果这个锁已经被别人获得, 代码进入一个紧凑的循环中反复检查这个锁, 直到它变为可用. 这个循环就是自旋锁的"自旋"部分.

    【所以此时这个线程就不会释放cpu资源? 编程测试】

     

     自旋锁 API 简介

     

    注意所有的自旋锁等待在本质上是不可中断的. 一旦你调用 spin_lock, 在获得锁之前,你将一直自旋.

     

    适用于自旋锁的核心规则是:任何代码必须, 在持有自旋锁时, 是原子性的. 它不能休眠。

    在持有自旋锁时禁止中断( 只在本地 CPU ).

    最后一个重要规则是自旋锁必须一直是尽可能短时间的持有

     

     

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值