《Linux Device Drivers》第十一章 核心数据类型——note

  • 基本介绍

    • 因为Linux多平台特性,不管是哪一个重要驱动力应该是便携
    • 与内核代码相关的核心问题应该是访问的同时是数据项的已知长度。能力和利用不同的处理器
    • 内核使用的数据类型主要分为三类
      • 类似int这种标准C语言类型
      • 类似u32这种有确定大小的类型
      • 像pid_t这种用于特定内核对象的类型
    • 本章将讨论在什么情况下使用这三种类型以及怎样使用
  • 使用标准C语言类型
    • 当我们须要“两个字节的填充符”或者“用四个字节字符串表示的某个东西”时。我们不能使用标准类型,由于在不同的体系架构上。普通C语言的数据类型所占空间在大小并不同样
    • 内核中的普通内存地址一般是unsigned long。在当前Linux支持的全部平台上,指针和long整形的大小总是同样的
    • C99标准定义了intptr_t和uintptr_t类型,它们是可以保存指针值的整形变量
  • 为数据项分配确定的空间大小
    • <asm/types.h>
    • <linux/types.h>
    • u8, s8
    • u16, s16
    • u32, s32
    • u64, s64
    • 假设一个用户空间程序须要使用这些类型,它能够在名字前加上两个下划线作为前缀
    • __u8
    • __u32
    • 使用新编译器的系统将支持C99标准类型,如uint8_t和uint32_t
  • 接口特定的类型

    • 内核中最经常使用的数据类型由它们自己的typedef声明。这样能够防止出现不论什么移植性问题
    • “接口特定(interface-specific)”是指由某个库定义的一种数据类型,以便为某个特定的数据结构提供接口
    • 完整的_t类型在<linux/types.h>中定义
    • _t数据项的主要问题是在我们须要打印它们的时候,不太easy选择正确的printk或者printf的输出格式
  • 其它有关移植的问题
    • 一个通用的原则是要避免使用显式的常量值
    • 时间间隔
      • 使用jiffies计算时间间隔的时候,应该用HZ来衡量
    • 页大小
      • 内存页的大小是PAGE_SIZE字节
      • PAGE_SHIFT
      • <asm/page.h>
      • getpagesize库函数
      • get_order函数
    • 字节序
      • <asm/byteorder.h>

        • __BIG_ENDIAN
        • __LITTLE_ENDIAN
      • u32 cpu_to_le32 (u32);
      • u32 le32_to_cpu(u32);
      • be64_to_cpu
      • le16_to_cpus
      • cpu_to_le32p
    • 数据对齐
      • <asm/unaligned.h>

        • get_unaligned(ptr);
        • put_unaligned(val, ptr);
    • 指针和错误值
      • 很多内核接口通过把错误值编码到一个指针值中来返回错误信息
      • <linux/err.h>
        • void *ERR_PTR(long error);
        • long IS_ERR(const void *ptr);
        • long PTR_ERR(const void *ptr);
  • 链表
    • <linux/list.h>

      • struct list_head

        • struct list_head *next, *prev;
      • INIT_LIST_HEAD(&list);
      • LIST_HEAD(list);
      • list_add(struct list_head *new, struct list_head *head);
      • list_add_tail(struct list_head *new, struct list_head *head);
      • list_del(struct list_head *entry);
      • list_del_init(struct list_head *entry);
      • list_move(struct list_head *entry, struct list_head *head);
      • list_move_tail(struct list_head *entry, struct list_head *head);
      • list_empty(struct list_head *head);
      • list_splice(struct list_head *list, struct list_head *head);
      • list_entry(struct list_head *ptr, type_of_struct, field_name);
      • list_for_each(struct list_head *cursor, struct list_head *list)
      • list_for_each_prev(struct list_head *cursor, struct list_head *list)
      • list_for_each_safe(struct list_head *cursor, struct list_head *next, struct list_head *list)
      • list_for_each_entry(type *cursor, struct list_head *list, member)
      • list_for_each_entry_safe(type *cursor, type *next, struct list_head *list, member)

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-27 07:52:00

《Linux Device Drivers》第十一章 核心数据类型——note的相关文章

《Linux Device Drivers》 第九章 与硬件通信

概述,本章正式接触真正的硬件. 将介绍对设备提供I/O访问的方法和函数,用于从设备读取数据或将数据写入到设备 并详细说明I/O端口和I/O内存 I/O端口和I/O内存 每种外设都通过读写寄存器进行控制 在硬件层,内存区域和I/O区域没有概念上的区别:它们都通过向地址总线和控制总线发送电平信号进行访问,再通过数据总线读写数据 I/O寄存器和常规内存 I/O寄存器和RAM的最主要区别就是I/O操作具有边际效应,而内存操作则没有 内存写操作的唯一结果就是在指定位置存储一个数值 内存读操作则仅仅返回指定

《Linux Device Drivers》第八章 分配内存——note

本章主要介绍Linux内核的内存管理. kmalloc函数的内幕 不正确所获取的内存空间清零 分配的区域在物理内存中也是连续的 flags參数 <linux/slab.h> <linux/gfp.h> GFP_KERNEL 在空暇内存较少时把当前进程转入休眠以等待一个页面 分配内存的函数必须是可重入的 GFP_ATOMIC 用于在中断处理例程或其它执行于进程上下文之外的代码中分配内存,不会休眠 GFP_USER 用于为用户空间页分配内存.可能会休眠 GFP_HIGHUSER 类似于

linux device drivers - debugging之proc

在书籍"linux device drivers"的第四章,专门介绍驱动开发中的debugging技术. printk只是其中一种技术,这种技术要求printk打印消息,并且会写入到磁盘里的文件中,这会拖慢整个代码的执行速度. 还有其中的debugging技术,并且对代码执行速度的影响比prink小. 其中讲到了,我们可以让驱动程序在proc文件系统里面创建文件,并且将需要的debugging信息写入到这个文件里面. linux内核提供了相应的API,来和proc文件系统交互,例如创建

《Linux Device Drivers》第十四章 Linux 设备模型

简介 2.6内核的设备模型提供一个对系统结构的一般性抽象描述,用以支持多种不同的任务 电源管理和系统关机 与用户空间通信 热插拔设备 设备类型 对象生命周期 kobject.kset和子系统 kobject是组成设备模型的基本结构 对象的引用计数 sysfs表述 数据结构关联 热插拔事件处理 kobject基础知识 <linux/kobject.h> 嵌入的kobject 内核代码很少去创建一个单独的kobject对象,kobject用于控制对大型域相关对象的访问 kobject的初始化 首先

Linux device drivers,LDD阅读笔记

第一章       惯例,泛泛而谈的第一章.但我注意到一个关键字“linux的模块”. 第二章       令人激动的hello world.这一章要开始实践了,所以先下载虚拟机和linux吧.

《Linux Device Drivers》第十一章 内核的数据类型——note

简介 由于Linux的多平台特性,任何一个重要的驱动程序都应该是可移植的 与内核代码相关的核心问题是应该能够同时访问已知长度的数据项,并充分利用不同处理器的能力 内核使用的数据类型主要被分成三类 类似int这样的标准C语言类型 类似u32这样的有确定大小的类型 像pid_t这样的用于特定内核对象的类型 本章将讨论在什么情况下使用这三种类型以及如何使用 使用标准C语言类型 当我们需要"两个字节的填充符"或者"用四个字节字符串表示的某个东西"时,我们不能使用标准类型,因

《Linux Device Drivers》第十二章 PCI驱动程序——note

简介 本章给出一个高层总线架构的综述 讨论重点是用于访问Peripheral Component Interconnect(PCI,外围设备互联)外设的内核函数 PCI总线是内核中得到最好支持的总线 本章主要介绍PCI驱动程序如果寻找其硬件和获得对它的访问 本章也会介绍ISA总线 PCI接口 PCI是一组完整的规范,定义了计算机的各个不同部分之间应该如何交互 PCI规范涵盖了与计算机接口相关的大部分问题 PCI架构被设计为ISA标准的替代品,有三个主要目标 获得在计算机和外设之间传输数据时更好的

《Linux Device Drivers》 第十七章 网络驱动程序——note

简介 网络接口是第三类标准Linux设备,本章将描述网络接口是如何与内核其余的部分交互的 网络接口必须使用特定的内核数据结构注册自身,以备与外界进行数据线包交换时调用 对网络接口的常用文件操作是没有意义的,因此在它们身上无法体现Unix的"一切都是文件"的思想 网络驱动程序异步自外部世界的数据包 网络设备向内核请求把外部获得的数据包发送给内核 Linux内核中的网络子系统被设计成完全与协议无关 在网络世界中使用术语"octet"指一组8个的数据位,它是能为网络设备和

《Linux Device Drivers》第十五章 内存映射和DMA——note

简单介绍 很多类型的驱动程序编程都须要了解一些虚拟内存子系统怎样工作的知识 当遇到更为复杂.性能要求更为苛刻的子系统时,本章所讨论的内容迟早都要用到 本章的内容分成三个部分 讲述mmap系统调用的实现过程 讲述怎样跨越边界直接訪问用户空间的内存页 讲述了直接内存訪问(DMA)I/O操作,它使得外设具有直接訪问系统内存的能力 Linux的内存管理 地址类型 Linux是一个虚拟内存系统,这意味着用户程序所使用的地址与硬件使用的物理地址是不等同的 有了虚拟内存,在系统中执行的程序能够分配比物理内存很