linux内核开发时需要注意以下几个问题:
1.不能访问C库,内核不能使用标准库。这个可以在编译链接内核以后从内核目录下的.vmlinux.cmd可以看出:arm-xxx-ld -nostdlib ... ... 。不过内核在lib下实现了部分常用的函数,如memset,strcpy这类函数,还有可能针对具体体系结构进行优化的代码,一般在arch/xxx/lib下。
2.内核编程使用的GNU C,而不是我们的标准C语言语法。看看内核的代码就知道。
3.因为是内核,所以其内存没有保护机制的。因为内核是在裸机上跑的,不像应用程序是在系统基础上运行的。这个搞过嵌入式开发的人都应该懂的。
4.要慎用内核栈,尽量用全局变量或者动态分配。因为内核栈被分配了比较小的空间,稍微大一点的数据就可能溢出,而且内核栈的底部保存着有关进程的信息。
5.不要轻易使用浮点数。
6.要注意同步和并发。多处理器,内核抢占,中断都有可能会产生竞争。
内核代码还要注意可移植性,因为它可能被移植到各种平台上去。要保证代码可移植性要主要以下问题:
1.字长和数据类型
各种不同的体系结构其字长是不一样的。我们用的ARM平台,其字长为4个字节。数据类型考虑一下方面:
1).不透明数据类型。这些数据类型一般由内核定义,其之所以这样做,为了方便兼容和后续升级。像pid_t,dev_t,atomic_t等。对这些数据类型的操作,如果内核提供了相关操作函数,应该使用这些函数,而不要手工去操作。
2).指定数据类型。内核有些函数需要使用指定类型,那就一定要使用该类型。否则可能会出问题。
3).长度明确的类型。像网络包有一个16字节的段。这样类型可以使用u8,u16,u32还有带符号的,不过一般使用的比较少。
4).char符号问题。最好明确是使用是带符号的还是不带符号的。
2.数据对齐。这个在ARM平台我们应该碰到过,不小心就有可能产生取数异常。ARM7,ARM9是不支持非对齐访问的,否则异常对待。新的ARMv7体系结构的芯片可以支持非对齐访问了。
3.字节顺序。主要是字中各种字节存放的顺序。有little-endian和big-endian。
4.使用内核定义的宏,不要使用魔幻数,不要对内核做任何假设。像使用HZ,PAGE_SHIFT来代替某些假的的数字。
上面是一些基础知识,那么要进行内核编程,还需要了解哪些了。这就要看我们的内核提供了那些设施。以下是学习驱动编写的一些基础知识:
1).并发和竞态
信号量,互斥量
completion
spinlock_t
atomic_t
2).阻塞,非阻塞,异步通知
wait_queue_t
异步通知
3).内存管理
kmalloc/kfree
get_free_pages/free_gages
4).I/O操作
register_region_mem/release_region_mem
ioremap/iounmap
ioread/8/16/32
iowrite8/16/32
5).中断管理
request_irq
下半部机制:软中断,tasklets,工作队列(work queue)
6).DMA
7).时间函数
延时函数,timer
有了这些基础,我们就可以进入驱动编程了。不过要理解上面的这些设施除了多看书还要多看代码,并手动去写写才能理解。看看它们的实现。
写驱动的话还需要链接下面这些基础:
字符驱动注册 regiser_chrdev_region/alloc_chrdev_region cdev_alloc/cdev_init/cdev_add/cdev_del
块设备注册和相关接口实现
网络设备驱动net_device
另外了解一下linux设备驱动模型,bus,class,device,device_driver等。使用udev/mdev来动态生成/dev目录是,需要用到/sys下的class和block目录。
然后可以了解各种框架:
misc_dev
platform_devices
i2c
rtc
spi
frame buffer/LCD
usb
mmc
tty
input/keyboard/touchscreen
sound
V4L2
MTD
Bluetooth
Infrared
WIFI Driver
参考书籍:
1).Linux Kernel Development Second Edition. By , ,
阅读(399) | 评论(0) | 转发(0) |