当前位置:文档之家› 内核中I2C体系结构-最强学习笔记!

内核中I2C体系结构-最强学习笔记!

内核中I2C体系结构-最强学习笔记!
内核中I2C体系结构-最强学习笔记!

内核中I2C体系结构

1.总体框架 (2)

1.1 I2C体系结构总体框图: (2)

1.2 组成部分: (2)

1.3 重要文件: (3)

1.4 重要函数接口与结构体 (3)

结构体: (3)

函数: (3)

各结构体的作用与它们之间的关系 (3)

1.5 i2c子系统的初始化函数的执行先后顺序 (4)

2.I2C核心 (4)

2.1 i2c_init()函数 (4)

2.1.1 i2c总线的注册 (5)

2.1.2 i2c驱动注册 (6)

2.1.3 i2c_init()函数总结 (6)

3.总线驱动 (7)

3.1 I2C platform_device初始化---smdk2440_machine_init() (7)

3.1.1 s3c_i2c_set_platdata (8)

3.1.2 i2c_register_board_info (9)

3.1.3 platform_add_devices (10)

3.2 I2C platform_drive适配器驱动初始化---i2c_adap_s3c_init() (10)

3.3 platform_bus总线 (11)

3.4总线设备和总线驱动初始化总结: (11)

3.5 probe函数——adapter_device 和client_device的注册 (12)

总结 (16)

4,设备驱动 (17)

4.1 i2c_dev_init() (17)

4.1.1 register_chardev (17)

4.1.2 i2c_add_drive 注册i2c_driver (i2cdev_driver) (18)

总结i2c_dev_init() : (20)

5,i2c子系统通信方法 (20)

5.1 open设备/dev/i2c-0 (20)

5.2 write (21)

5.3 i2cdev_ioctl (27)

5.2.1 I2C_SLA VE / I2C_SLA VE_FORCE (27)

5.2.2 I2C_RDWR (27)

6,I2C子系统总结: (29)

附录: (30)

说明:内核版本: 2.6.32 I2C设备: E2PROM (at24c02)

/************************************************\

跳过此内容不影响整体框架学习

\************************************************/

(标号)上下文相互提到

1.总体框架

1.1 I2C体系结构总体框图:

从i2c驱动架构图中可以看出,linux内核对i2c架构抽象了一个叫核心层core的中间件,它分离了设备驱动device driver和硬件控制的实现细节(如操作i2c的寄存器),core层不但为上面的设备驱动提供封装后的内核注册函数,而且还为小面的硬件事件提供注册接口(也就是i2c 总线注册接口),可以说core层起到了承上启下的作用。

1.2 组成部分:

Linux的I2C体系结构分为3个组成部分:

I2C设备驱动:提供策略,定义描述具体设备的i2c_client和可能的私有数据结构。是对I2C 硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。

主要数据结构:i2c_driver, i2c_client

I2C框架层:i2c.h和i2c-core.c为其主体框架代码,提供了核心数据结构的定义、i2c适配器驱动和设备驱动的注册、注销管理等;i2c-dev.c用于创建i2c适配器的/dev/i2c-%d设备节点,提供i2c设备的用户空间访问方法等。

I2C总线驱动:提供硬件操作能力。i2c/busses/目录下,如i2c-msm.c。描述i2c_adapter数据结构及其具体总线通信,,适配器可由CPU控制,甚至可以直接集成在CPU内部。I2C控制驱动(总线驱动)在芯片(S3C2410)生产出来的时候生产厂商就已经写好了,且永远不变(1类芯片对应1种控制器驱动,控制器驱动就是去操作各种寄存器的值,实现标准I2C时序)

1.3 重要文件:

i2c-core.c 实现I2C核心功能以及/proc/bus/i2c*接口。

i2c-dev.c 通用设备驱动。

创建i2c适配器的/dev/i2c-%d设备节点(MAJOR=89,MINOR=0-255)

每一个I2C适配器都被分配一个client。

Busses 包含I2C总线的驱动,如S3C2410,S3C2440的控制器驱动i2c-s3c2410.c Algos 实现I2C总线适配器的algorithm.

1.4 重要函数接口与结构体

结构体:

Struct i2c_adapter //描述一个i2c控制器

Struct i2c_driver //描述一个i2c设备驱动

Struct i2c_client //描述一个i2c设备(e2prom)

Struct i2c_msg //描述一个i2c消息结构体

struct i2c_algorithm //描述一个i2c算法

struct bus_type i2c_bus_type //用于管理的i2c_bus总线

struct s3c24xx_i2c i2c //i2c_adapters的algo_data类似私有信息。封装适配器的所有信息。

函数:

i2c_add_driver //加载i2c设备驱动结构体到链表里

i2c_add_adapter //加载i2c适配器结构体到适配器链表

i2c_master_send //发送数据函数

i2c_transfer //转接到底层的函数

static int s3c24xx_i2c_probe(struct platform_device *pdev) //发现合适设备时会被bus driver调用

各结构体的作用与它们之间的关系

i2c_adapter与i2c_algorithm

i2c_adapter对应物理上的适配器,用于产生I2C标准时序,产生方法由i2c_algorithm实现。i2c_driver和i2c_client

i2c_client = adapter+devinfo (_i2c_board_list链表上一个信息结构体)

每个i2c设备都需要一个i2c_client来描述

注册i2c_driver后程序调用其attach_adapter():将adapter加入到i2c_dev_list,并创建设备节点i2c-%d,应用层打开时i2c-%d,在此取出adapter。

一个i2c_driver上可以支持多个同等类型的i2c_client.

i2c_adapter和i2c_client

i2c_client依附于i2c_adapter,一个适配器上可以连接多个i2c设备,所以i2c_adapter中包含依附于它的i2c_client的链表。

1.5 i2c子系统的初始化函数的执行先后顺序

1./dricer/i2c/i2c-core.c中的函数:i2c_init()

postcore_initca级别

2./arch/arm/mach-s3c2440/mach-smdk2440.c中的函数:smdk2440_machine_init()

arch_initcall级别

3.driver/i2c/buses/i2c-s3c2410.c中的函数:i2c_adap_s3c_init()

bsys_initcall级别

4./driver/i2c/i2c-dev.c中的函数:i2c_dev_init()

module_init级别

后续将根据这个顺序进行分析

2.I2C核心

2.1 i2c_init()函数:

i2c_init() = 1,注册i2c总线

2,注册类i2c_adapter_class

3,注册空i2c driver

2.1.1 i2c总线的注册

i2c_bus_type

总线提供match和probe方法:

注册i2c设备或i2c驱动时,调用match匹配client device和client driver,

匹配成功调用probe。

(1)i2c_device_match

如果该驱动不是一个new-style形式的且driver没有定义匹配的id_table都会匹配失败.

I2c_match_id()函数的作用:

匹配板文件中定义的ID和i2c_driver所支持的ID表(P338 宋宝华驱动)

(2)i2c_device_probe

通过传递进来的dev找到包含此dev的i2c_driver驱动,然后再去调用i2c_driver的probe 方法。所以在i2c总线中,驱动和设备匹配成功,就调用驱动中的probe函数。

2.1.2 i2c驱动注册

dummy_driver仅仅是注册了一个空的设备驱动。

2.1.3 i2c_init()函数总结

该过程主要完成了sysfs总线结构,最终形成如下结构:

/sys/bus/i2c/

|-- devices

|-- drivers

| |-- dummy

| |-- bind

| |-- uevent

| `-- unbind

|-- drivers_autoprobe

|-- drivers_probe

`-- uevent

/sys/class/i2c-adapter/

3.总线驱动

3.1 I2C platform_device初始化---smdk2440_machine_init()

smdk2440_machine_init() =

1.构建platform_device型设备s3c_device_i2c0。

2.将板上i2c设备信息注册到i2c设备链__i2c_board_list上。此处就为at24c02的相关参数。

3.添加platform总线

/********************************************************************************\ static struct i2c_board_info tq2440_i2c_devs[] __initdata = {

{

I2C_BOARD_INFO("24c02", 0x50),

.platform_data = &at24c02,

},

};

static struct at24_platform_data at24c02 = {

.byte_len = SZ_2K / 8,

.page_size = 8,

};

将这两句添加到smdk2440_machine_init()上面(因为此处用到)或添加到at24c04所在处(试试)

\********************************************************************************/

( i2c_register_board_info(0, tq2440_i2c_devs,

ARRAY_SIZE(tq2440_i2c_devs)); )

需要注意的是,此处的i2c_register_board_info()函数是后来添加的,原生内核此处并未调用此函数。经过分析,也许需要调用此函数,之后会实际论证。

3.1.1 s3c_i2c_set_platdata 构建platform_device s3c_device_i2c0

1,定义s3c_device_i2c0

2,s3c_i2c_set_platdata :将default_i2c_data0保存到s3c_device_i2c0的dev.platform_data

(标号D )

3,生成表1: 表1

\

slave_addr 要改成0x50?

Struct platform_device s3c_device_i2c0 Name : s3c2410-i2c Resource :s3c_i2c_resource … … Struct device dev V oid *platform_data (default_i2c_data 0) .flags = 0, .slave_addr = 0x10, .frequency = 100*1000, .sda_delay = 100, … …

If(!pd)为真(pd=null),则将default_i2c_data0赋值给pd。

通过2,3 实现将default_i2c_data0的值保存到s3c_device_i2c0的dev.platform_data下

在s3c24xx_i2c_probe函数中,对s3c2440的i2c相关控制寄存器的初始化操作会将platform_data 参数填入到相关寄存器。

3.1.2 i2c_register_board_info

i2c_register_board_info =

1,生成表2

2,将表2挂到__i2c_board_list链表(标号C)初始化client时从链表取下

struct i2c_devinfo

struct list_head

list __i2c_board_list

int busnum

struct i2c_board_info board_info (tq2440_i2c_devs)

I2C_BOARD_INFO("24c02", 0x50), .type ="24c02" .addr= 0x50

.platform_data = &at24c02, .byte_len= SZ_2K / 8 .page_size = 8,

表 2

3.1.3 platform_add_devices

将之前创建的platform_device 型设备s3c_device_i2c0添加到platform_bus 总线。

3.2 I2C platform_drive 适配器驱动初始化---i2c_adap_s3c_init()

platform_driver_register 向platform 总线注册s3c2410_i2c_driver (platform_driver 类型)

配对成功调用Probe 注册i2c_adapter 和 i2c_client 。(后面详细分析)

3.3 platform_bus总线

有设备或驱动注册时,调用platform_match函数(根据名字来配对)。如下:

到此处,之前已注册的platform_device型s3c_devicei2c0

和现在的platfor_drver型s3c24xx_i2c_drive配对成功。

3.4总线设备和总线驱动初始化总结:

Platform device 初始化:smdk2440_machine_init()

构建一个包含初始化数据的s3c_device_i2c0,并注册到总线Platform driver 初始化:i2c_adap_s3c_init()

定义s3c2410_i2c_drive,并注册到总线,匹配device,调用probe。

图1

3.5 probe函数——adapter_device 和client_device的注册

该函数的主体工作是使能硬件并申请I2C适配器使用的I/O地址,中断号等,在这些工作都完成无误后,通过I2C核心提供的i2c_add_adapter()函数添加适配器。当处理器包含多个I2C 控制器时,我们通过板文件定义的platform数据中的bus_num进行区分。(摘自宋宝华驱动。)/********************************************************************************\ probe函数的功能如下:

1.创建struct s3c24xx_i2c *i2c。

i2c相关数据的初始化来源于s3c2_device_i2c0.dev.platdata(标号D)。

2.i2c->adap.algo = &s3c24xx_i2c_algorithm;初始化algo方法。

3.init_waitqueue_head(&i2c->wait); 初始化一个等待队列

4.初始化i2c控制器,s3c24xx_i2c_init (i2c);对s3c24xx的i2c控制寄存器进行,比

如配置s3c2440i/o功能,设置从机地址,以及设置i2c时钟频率等相关操作。

5.申请中断。

request_irq(i2c->irq, s3c24xx_i2c_irq, IRQF_DISABLED,

dev_name(&pdev->dev), i2c);

6.注册i2c adapteri2c_add_numbered_adapter(&i2c->adap)

\*******************************************************************************/ s3c24xx_i2c_probe

在probe函数会调用函数i2c_add_number_adapter(),通过此函数来实现adapter device和client device的注册。

struct s3c24xx_i2c i2c //作为i2c_adapters 的algo_data 。封装适配器的所有信息

然后调用

i2c_add_number_adapter()

表3

/********************************************************************************\ i2c_add_number_adapter()函数如下:

int i2c_add_numbered_adapter(struct i2c_adapter *adap) {

s3c24xx_i2c

*i2c 值

tx_setup 50

clk clk_get(&pdev->dev, "i2c");

dev &pdev ->dev 注:struct platform_device *pdev

ioarea

request_mem_region (res->start,(res->end-res->start)+1, pdev->name); // request IO

regs ioremap (res->start, (res->end-res->start)+1); adapter name "s3c2410-i2c" owner THIS_MODULE algo &s3c24xx_i2c_algorithm retries 2 class I2C_CLASS_HWMON | I2C_CLASS_SPD algo_data i2c (即这个表格) nr pdata->bus_num dev parent &pdev ->dev name "i2c-%d" class &i2c_adapter_class release &i2c_adapter_dev_release

……

if (status == 0)

status = i2c_register_adapter(adap);

return status;

}

最重要的就是i2c_register_adapter()

通过以下函数将名为i2c-0的adapter设备注册到i2c_bus_type型的i2c总线上,其中通过

指定了本次注册的设备类型为i2c_adapter_class(因为还有client设备同时需要注册到这条i2c总线上)。

在后面注册适配器驱动时(标号E)会在i2c_adapter_class这个类中找适配器设备,也就是这个adaper.

最后device_register()将adapter注册到i2c总线上。

\********************************************************************************/ 在函数i2c_register_adapter中注册adapter后紧接着注册client。

判断if是否成立,此处成立。__i2c_first_dynamic_bus_num的判断分析待续

执行i2c_scan_static_board_info(adap);

从__i2c_board_list链表上获取一个devinfo信息结构体,(标号C)。

i2c_new_device:利用__i2c_board_list链表上一个devinfo信息结构体和刚注册的adapter创建一个client

client(从设备

at24c02)

数据adapter adap(表3)

name Info->type

dev platform_dat

a info->platform_data 表2

(tq2440_i2c_devs)

parent &client->adapter->de

v

bus &i2c_bus_type

flags info->flags

addr info->addr

irq info->irq

表4

/********************************************************************************\

i2c_attach_client()填充client成员且向总线注册client。

\********************************************************************************/

此i2c总线同时包含了adapter和client,即i2c主机(s3c2440的i2c控制器)、i2c从设备at24c02。到这一步内核实现了adapter device和client device的注册,接着要通过函数bus_for_each_drv()来扫描i2c总线,检测刚注册到i2c总线的adapter是否有对应的驱动。

不过目前肯定失败,因为到目前为止还未注册adapter driver。

总结

至此,执行完i2c_add_numbered_adapter函数后,i2c总线上已有adapter device和client device,但是i2c总线此时还未有adapter driver和client driver。

总线挂载如图:

4,设备驱动

i2c adapter的驱动通过i2cdev_driver这个通用驱动的attach方法来实现注册。在/dev目录下生成i2c设备文件等操作

4.1 i2c_dev_init()

1,创建字符设备

2,创建i2c_dev_class类(标号B )

3,注册驱动

4.1.1 register_chardev

i2cdev_fops如下:

4.1.2 i2c_add_drive 注册i2c_driver (i2cdev_driver)

i2c_add_driver = 1,注册i2cdev_driver

(如果未初始化driver->detect 将adapter加入到i2c_dev_list)2,创建设备文件“i2c-%d ”

/*************************************************************************\ class_for_each_device()

在新的驱动加入内核时调用该函数,在类i2c_adapter_class中找一个适配器设备

与新驱动匹配。(标号E)

class_for_each_device并不执行匹配的操作,只是简单的取出所有的驱动或是适配器。

真正的匹配是在函数i2c_detect和attach_adapter中进行的。

由于此处驱动并未初始化driver->detect,所以i2c_detect函数未执行有效操作就会退出。

接着通过传统方式执行driver->attach_adapter方法。

\*************************************************************************/

绕了一大圈,其实就是注册i2c_driver类型的i2cdev_driver到i2c bus 上,

然后调用驱动本身的attach_adapter:将adapter加入到i2c_dev_list,和创建设备文件

/*****************************************************************************\

i2cdev_attach_adapter =

1,将adapter加入到i2c_dev_list。应用层打开i2c-0设备文件时,在此取出adapter。(标号A)

2,调用device_create()函数,通过之前class_create的类信息(标号B )在/dev下自动创建设备文件。

到此i2c部分的初始化就完成了,可以通过read write来操作设备了。

\*****************************************************************************/总结i2c_dev_init() :

1通过register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);

创建主设备号=I2C_MAJOR,操作函数集=i2cdev_fops 的字符设备2,然后通过i2c_add_driver(&i2cdev_driver); 注册i2驱动i2cdev_driver,

创建主设备号=I2C_MAJOR,次设备号为nr的设备文件,i2c-%d。

这样以后就可以通过操作i2c-%d节点来操作设备文件i2c,(其实是操作i2cdev_fops)5,i2c子系统通信方法

5.1 open设备/dev/i2c-0

open通过系统调用最后调用到fops的i2cdev_open函数

i2cdev_open = 1,根据/dev/i2c-%d的设备号找到i2c_dev_list链表中的i2c_dev (标号A)

取出对应的adapter.

2,将adapter保存到临时变量client中,存入file->private_data

供ioctl() write() open()等操作使用。

Linux内核修改与编译图文教程

Linux 内核修改与编译图文教程 1

1、实验目的 针对Ubuntu10.04中,通过下载新的内核版本,并且修改新版本内核中的系统调用看,然后,在其系统中编译,加载新内核。 2、任务概述 2.1 下载新内核 https://www.doczj.com/doc/496709552.html,/ 2.2 修改新内核系统调用 添加新的系统调用函数,用来判断输入数据的奇偶性。 2.3 进行新内核编译 通过修改新版内核后,进行加载编译。最后通过编写测试程序进行测试 3、实验步骤 3.1 准备工作 查看系统先前内核版本: (终端下)使用命令:uname -r 2

3.2 下载最新内核 我这里使用的内核版本是 3.3 解压新版内核 将新版内核复制到“/usr/src”目录下 在终端下用命令:cd /usr/src进入到该文件目录 解压内核:linux-2.6.36.tar.bz2,在终端进入cd /usr/src目录输入一下命令: bzip2 -d linux-2.6.36.tar.bz2 tar -xvf linux-2.6.36.tar 文件将解压到/usr/src/linux目录中 3

使用命令: ln -s linux-2.6.36 linux 在终端下输入一下命令: sudo apt-get install build-essential kernel-package libncurses5-dev fakeroot sudo aptitude install libqt3-headers libqt3-mt-dev libqt3-compat-headers libqt3-mt 4

Linux内核崩溃原因分析及错误跟踪技术

Linux内核崩溃原因分析及错误跟踪技术 随着嵌入式Linux系统的广泛应用,对系统的可靠性提出了更高的要求,尤其是涉及到生命财产等重要领域,要求系统达到安全完整性等级3级以上[1],故障率(每小时出现危险故障的可能性)为10-7以下,相当于系统的平均故障间隔时间(MTBF)至少要达到1141年以上,因此提高系统可靠性已成为一项艰巨的任务。对某公司在工业领域14 878个控制器系统的应用调查表明,从2004年初到2007年9月底,随着硬软件的不断改进,根据错误报告统计的故障率已降低到2004年的五分之一以下,但查找错误的时间却增加到原来的3倍以上。 这种解决问题所需时间呈上升的趋势固然有软件问题,但缺乏必要的手段以辅助解决问题才是主要的原因。通过对故障的统计跟踪发现,难以解决的软件错误和从发现到解决耗时较长的软件错误都集中在操作系统的核心部分,这其中又有很大比例集中在驱动程序部分[2]。因此,错误跟踪技术被看成是提高系统安全完整性等级的一个重要措施[1],大多数现代操作系统均为发展提供了操作系统内核“崩溃转储”机制,即在软件系统宕机时,将内存内容保存到磁盘[3],或者通过网络发送到故障服务器[3],或者直接启动内核调试器[4]等,以供事后分析改进。 基于Linux操作系统内核的崩溃转储机制近年来有以下几种: (1) LKCD(Linux Kernel Crash Dump)机制[3]; (2) KDUMP(Linux Kernel Dump)机制[4]; (3) KDB机制[5]; (4) KGDB机制[6]。 综合上述几种机制可以发现,这四种机制之间有以下三个共同点: (1) 适用于为运算资源丰富、存储空间充足的应用场合; (2) 发生系统崩溃后恢复时间无严格要求; (3) 主要针对较通用的硬件平台,如X86平台。 在嵌入式应用场合想要直接使用上列机制中的某一种,却遇到以下三个难点无法解决: (1) 存储空间不足 嵌入式系统一般采用Flash作为存储器,而Flash容量有限,且可能远远小于嵌入式系统中的内存容量。因此将全部内存内容保存到Flash不可行。

如何自行编译一个Linux内核的详细资料概述

如何自行编译一个Linux内核的详细资料概述 曾经有一段时间,升级Linux 内核让很多用户打心里有所畏惧。在那个时候,升级内核包含了很多步骤,也需要很多时间。现在,内核的安装可以轻易地通过像 apt 这样的包管理器来处理。通过添加特定的仓库,你能很轻易地安装实验版本的或者指定版本的内核(比如针对音频产品的实时内核)。 考虑一下,既然升级内核如此容易,为什么你不愿意自行编译一个呢?这里列举一些可能的原因: 你想要简单了解编译内核的过程 你需要启用或者禁用内核中特定的选项,因为它们没有出现在标准选项里 你想要启用标准内核中可能没有添加的硬件支持 你使用的发行版需要你编译内核 你是一个学生,而编译内核是你的任务 不管出于什么原因,懂得如何编译内核是非常有用的,而且可以被视作一个通行权。当我第一次编译一个新的Linux 内核(那是很久以前了),然后尝试从它启动,我从中(系统马上就崩溃了,然后不断地尝试和失败)感受到一种特定的兴奋。 既然这样,让我们来实验一下编译内核的过程。我将使用Ubuntu 16.04 Server 来进行演示。在运行了一次常规的 sudo apt upgrade 之后,当前安装的内核版本是 4.4.0-121。我想要升级内核版本到 4.17,让我们小心地开始吧。 有一个警告:强烈建议你在虚拟机里实验这个过程。基于虚拟机,你总能创建一个快照,然后轻松地从任何问题中回退出来。不要在产品机器上使用这种方式升级内核,除非你知道你在做什么。 下载内核 我们要做的第一件事是下载内核源码。在 Kernel 找到你要下载的所需内核的URL。找到URL 之后,使用如下命令(我以 4.17 RC2 内核为例)来下载源码文件: wget https://git.kernel/torvalds/t/linux-4.17-rc2.tar.gz

Linux下I2C驱动介绍

1、I2C概述 I2C是philips公司提供的外设总线,I2C有两条数据线,一条是串行数据线SDA、一条是时钟线SCL,使用SDA和SCL实现了数据的交换,便于布线。I2C总线方便用在EEPROM、实时钟、小型LCD等与CPU外部的接口上。 2、Linux下的驱动思路 Linux系统下编写I2c驱动主要有两种方法:一种是把I2C当做普通字符设备来使用;另一种利用Linux下驱动的体系结构来实现。 第一种方法: 优点:思路比较直接,不用花费大量时间去了解Linux系统下I2C体系结构 缺点:不仅对I2C设备操作要了解,还有了解I2C的适配器操作 不仅对I2C设备器和设备操作需要了解,编写的驱动移植性差,内核 提供的I2C设备器都没有用上。 第二种方法: 第一种的优点就是第二种的缺点,第一种的缺点就是第二种的优点。 3、I2C框架概述 Linux的I2C体系结构分为3部分: 1)I2C核心I2C核心提供了I2C总线驱动和设备驱动的注册和注销的方法,I2C 通信方法(algorithm)上层,与具体适配器无关的代码,检测设备上层的代 码等。 2)I2C总线驱动I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可以直接受CPU来控制。 3)I2C设备驱动I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备端挂在受CPU控制的适配器上,通过I2C适配器与CPU交换数据。 Linux下的I2C体系结构: 1)Linux下的I2C体系结构 4、I2C设备驱动编写方法 首先让我们明白适配器驱动的作用是让我们能够通过它发出标准的I2C时序,在linux

内核源代码中driver/I2C/buss包含一些适配器的驱动,例如s3c2410的驱动I2C-s3c2410.c,适配器被加载到内核中,接下的任务就是实现设备驱动的编写。编写设备驱动的方法主要分为两种方法: 第一种:利用设备提供的I2C-dev.c来实现I2C适配器设备文件,然后通过上层应用程序来操作I2C设备器来控制I2C设备。 第二种:为I2C设备独立编写一个设备驱动 注意:第二种方法不能用设备提供的I2C-dev.c 5、I2C系统下的文件架构 在linux下driver下面有个I2C目录,在I2C目录下包含以下文件和文件夹 1)I2C-core.c 这个文件实现I2C核心功能以及/proc/bus/I2C*接口 2)I2C-dev.c 实现I2C适配器设备文件的功能,每个I2C适配器被分配一个设备,通过 适配器访问设备的时候,主设备号是89,此设备号是0-255. I2C-dev.c并没有针对特定设备而设计,只提供了read() write()和ioctl()等接口,应用层可以通过这些接口访问挂在适配器上的I2C设备存储空间和寄存器,并控制I2C设备的工作方式。 3)Chips 这个文件下面包含特定的I2C设备驱动。 4)Busses 这个文件包含一些I2C总线驱动。 5)Algos文件夹下实现了I2C总线适配器的algorithm 6、重要结构体 1)在内核中的I2C.h这个头文件中对I2C_driver;I2C_client;I2C_adapter和I2C_algorithm 这个四个结构体进行了定义。理解这4个结构体的作用十分关键。 i2c_adapter结构体 struct i2c_adapter { struct module *owner; //所属模块 unsigned int id; //algorithm的类型,定义于i2c-id.h, unsigned int class; const struct i2c_algorithm *algo; //总线通信方法结构体指针 void *algo_data;//algorithm数据 struct rt_mutex bus_lock; //控制并发访问的自旋锁 int timeout; int retries; //重试次数 struct device dev; //适配器设备 int nr; char name[48]; //适配器名称 struct completion dev_released; //用于同步 struct list_head userspace_clients; //client链表头

嵌入式Linux系统内核的配置、编译和烧写

实验二 嵌入式Linux系统内核的配置、编译和烧写 1.实验目的 1)掌握交叉编译的基本概念; 2)掌握配置和编译嵌入式Linux操作系统内核的方法; 3)掌握嵌入式系统的基本架构。 2.实验环境 1)装有Windows系统的计算机; 2)计算机上装有Linux虚拟机软件; 3)嵌入式系统实验箱及相关软硬件(各种线缆、交叉编译工具链等等)。 3.预备知识 1)嵌入式Linux内核的配置和裁剪方法; 2)交叉编译的基本概念及编译嵌入式Linux内核的方法; 3)嵌入式系统的基本架构。 4.实验内容和步骤 4.1 内核的配置和编译——配置内核的MMC支持 1)由于建立交叉编译器的过程很复杂,且涉及汇编等复杂的指令,在这里 我们提供一个制作好的编译器。建立好交叉编译器之后,我们需要完成 内核的编译,首先我们要有一个完整的Linux内核源文件包,目前流行 的源代码版本有Linux 2.4和Linux 2.6内核,我们使用的是Linux 2.6内核; 2)实验步骤: [1]以root用户登录Linux虚拟机,建立一个自己的工作路径(如用命令 “mkdir ‐p /home/user/build”建立工作路径,以下均采用工作路径 /home/user/build),然后将“cross‐3.3.2.tar.bz2、dma‐linux‐2.6.9.tar.gz、 dma‐rootfs.tar.gz”拷贝到工作路径中(利用Windows与虚拟机Linux 之间的共享目录作为中转),并进入工作目录; [2]解压cross‐3.3.2.tar.bz2到当前路径:“tar ‐jxvf cross‐3.3.2.tar.bz2”; [3]解压完成后,把刚刚解压后在当前路径下生成的“3.3.2”文件夹移 动到“/usr/local/arm/”路径下,如果在“/usr/local/”目录下没有“arm” 文件夹,用户创建即可; [4]解压“dma‐linux‐2.6.9.tar.gz”到当前路径下:

Linux下I2C驱动架构全面分析概要

Linux下I2C驱动架构全面分析 I2C概述 I2C是philips提岀的外设总线. I2C只有两条线,一条串行数据线:SDA, —条是时钟线SCL,使用SCL , SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线。 因此,I2C总线被非常广泛地应用在EEPROM,实时钟,小型LCD等设备与CPU的接口中。 linux下的驱动思路 在linux系统下编写I2C驱动,目前主要有两种方法,一种是把I2C设备当作一个普通的字符设备来处理,另一种是利用linux下I2C驱动体系结构来完成。下面比较下这两种方法: 第一种方法: 优点:思路比较直接,不需要花很多时间去了解linux中复杂的I2C子系统的操作方法。 缺点: 要求工程师不仅要对I2C设备的操作熟悉,而且要熟悉I2C的适配器(I2C控制器)操作。要求工程师对I2C的设备器及I2C的设备操作方法都比较熟悉,最重要的是写岀的程序可以移植性差。 对内核的资源无法直接使用,因为内核提供的所有I2C设备器以及设备驱动都是基于I2C 子系统的格式。 第一种方法的优点就是第二种方法的缺点, 第一种方法的缺点就是第二种方法的优点。 I2C架构概述 Linux的I2C体系结构分为3个组成部分: I2C核心:I2C核心提供了I2C总线驱动和设备驱动的注册,注销方法,I2C通信方法 (” algorithm 上层的,与具体适配器无关的代码以及探测设备,检测设备地址的上层代码等。 I2C总线驱动:I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。 I2C设备驱动:I2C设备驱动(也称为客户驱动)是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。

linux、内核源码、内核编译与配置、内核模块开发、内核启动流程

linux、内核源码、内核编译与配置、内核模块开发、内核启动流程(转) linux是如何组成的? 答:linux是由用户空间和内核空间组成的 为什么要划分用户空间和内核空间? 答:有关CPU体系结构,各处理器可以有多种模式,而LInux这样的划分是考虑到系统的 安全性,比如X86可以有4种模式RING0~RING3 RING0特权模式给LINUX内核空间RING3给用户空间 linux内核是如何组成的? 答:linux内核由SCI(System Call Interface)系统调用接口、PM(Process Management)进程管理、MM(Memory Management)内存管理、Arch、 VFS(Virtual File Systerm)虚拟文件系统、NS(Network Stack)网络协议栈、DD(Device Drivers)设备驱动 linux 内核源代码 linux内核源代码是如何组成或目录结构? 答:arc目录存放一些与CPU体系结构相关的代码其中第个CPU子目录以分解boot,mm,kerner等子目录 block目录部分块设备驱动代码 crypto目录加密、压缩、CRC校验算法 documentation 内核文档 drivers 设备驱动 fs 存放各种文件系统的实现代码 include 内核所需要的头文件。与平台无关的头文件入在include/linux子目录下,与平台相关的头文件则放在相应的子目录中 init 内核初始化代码 ipc 进程间通信的实现代码 kernel Linux大多数关键的核心功能者是在这个目录实现(程序调度,进程控制,模块化) lib 库文件代码 mm 与平台无关的内存管理,与平台相关的放在相应的arch/CPU目录net 各种网络协议的实现代码,注意而不是驱动 samples 内核编程的范例 scripts 配置内核的脚本 security SElinux的模块 sound 音频设备的驱动程序 usr cpip命令实现程序 virt 内核虚拟机 内核配置与编译 一、清除 make clean 删除编译文件但保留配置文件

linux下iic(i2c)读写AT24C02

https://www.doczj.com/doc/496709552.html,/jammy_lee/ https://www.doczj.com/doc/496709552.html, linux下iic(i2c)读写AT24C02 linux驱动2010-02-09 16:02:03 阅读955 评论3 字号:大中小订阅 linux内核上已有iic的驱动,因此只需要对该iic设备文件进行读写则能够控制外围的iic器件。这里以AT24C02为对象,编写一个简单的读写应用程序。iic设备文件在我的开发板上/dev/i2c/0 ,打开文件为可读写。AT24C02的器件地址为0x50 ,既是iic总线上从器件的地址,每次只读写一字节数据。 /************************************************************/ //文件名:app_at24c02.c //功能:测试linux下iic读写at24c02程序 //使用说明: (1) // (2) // (3) // (4) //作者:jammy-lee //日期:2010-02-08 /************************************************************/ //包含头文件 #include #include #include #include #include #include #include

#include #include #include //宏定义 #define Address 0x50 //at24c02地址 #define I2C_RETRIES 0x0701 #define I2C_TIMEOUT 0x0702 #define I2C_SLAVE 0x0703 //IIC从器件的地址设置 #define I2C_BUS_MODE 0x0780 typedef unsigned char uint8; uint8 rbuf[8] = {0x00}; //读出缓存 uint8 wbuf[8] = {0x01,0x05,0x06,0x04,0x01,0x01,0x03,0x0d}; //写入缓存int fd = -1; //函数声明 static uint8 AT24C02_Init(void); static uint8 i2c_write(int fd, uint8 reg, uint8 val); static uint8 i2c_read(int fd, uint8 reg, uint8 *val); static uint8 printarray(uint8 Array[], uint8 Num); //at24c02初始化 static uint8 AT24C02_Init(void) { fd = open("/dev/i2c/0", O_RDWR); //允许读写 if(fd < 0) { perror("Can't open /dev/nrf24l01 \n"); //打开iic设备文件失败 exit(1);

Linux内核移植开发手册

江苏中科龙梦科技有限公司 Linux内核移植开发手册 修 订 记 录 项 次 修订日期 版 本修订內容修订者审 核 1 2009‐02‐04 0.1 初版发行陶宏亮, 胡洪兵 2 2009‐11‐20 0.2 删除一些 多余文字 陶宏亮, 胡洪兵

DISCLAIMER THIS DOCUMENTATION IS PROVIDED FOR USE WITH LEMOTE PRODUCTS. NO LICENSE TO LEMOTE PROPERTY RIGHTS IS GRANTED. LEMOTE ASSUMES NO LIABILITY, PROVIDES NO WARRANTY EITHER EXPRESSED OR IMPLIED RELATING TO THE USAGE, OR INTELLECTUAL PROPERTY RIGHT INFRINGEMENT EXCEPT AS PROVIDED FOR BY LEMOTE TERMS AND CONDITIONS OF SALE. LEMOTE PRODUCTS ARE NOT DESIGNED FOR AND SHOULD NOT BE USED IN ANY MEDICAL OR LIFE SUSTAINING OR SUPPORTING EQUIPMENT. ALL INFORMATION IN THIS DOCUMENT SHOULD BE TREATED AS PRELIMINARY. LEMOTE MAY MAKE CHANGES TO THIS DOCUMENT WITHOUT NOTICE. ANYONE RELYING ON THIS DOCUMENTATION SHOULD CONTACT LEMOTE FOR THE CURRENT DOCUMENTATION AND ERRATA. JIANGSU LEMOTE TECHNOLOGY CORPORATION LIMITED MENGLAN INDUSTRIAL PARK,YUSHAN,CHANGSHU CITY,JIANGSU PROVINCE,CHINA Tel: 0512‐52308661 Fax: 0512‐52308688 Http: //https://www.doczj.com/doc/496709552.html,

linux内核编译和生成makefile文件实验报告

操作系统实验报告 姓名:学号: 一、实验题目 1.编译linux内核 2.使用autoconf和automake工具为project工程自动生成Makefile,并测试 3.在内核中添加一个模块 二、实验目的 1.了解一些命令提示符,也里了解一些linux系统的操作。 2.练习使用autoconf和automake工具自动生成Makefile,使同学们了解Makefile的生成原理,熟悉linux编程开发环境 三、实验要求 1使用静态库编译链接swap.c,同时使用动态库编译链接myadd.c。可运行程序生成在src/main目录下。 2要求独立完成,按时提交 四、设计思路和流程图(如:包括主要数据结构及其说明、测试数据的设计及测试结果分析) 1.Makefile的流程图: 2.内核的编译基本操作 1.在ubuntu环境下获取内核源码 2.解压内核源码用命令符:tar xvf linux- 3.18.12.tar.xz 3.配置内核特性:make allnoconfig 4.编译内核:make 5.安装内核:make install

6.测试:cat/boot/grub/grub.conf 7.重启系统:sudo reboot,看是否成功的安装上了内核 8.详情及结构见附录 3.生成makefile文件: 1.用老师给的projec里的main.c函数。 2.需要使用automake和autoconf两个工具,所以用命令符:sudo apt-get install autoconf 进行安装。 3.进入主函数所在目录执行命令:autoscan,这时会在目录下生成两个文件 autoscan.log和configure.scan,将configure.Scan改名为configure.ac,同时用gedit打开,打开后文件修改后的如下: # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([main.c]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE(main,1.0) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT(Makefile) 4.新建Makefile文件,如下: AUTOMAKE_OPTIONS=foreign bin_PROGRAMS=main first_SOURCES=main.c 5.运行命令aclocal 命令成功之后,在目录下会产生aclocal.m4和autom4te.cache两个文件。 6.运行命令autoheader 命令成功之后,会在目录下产生config.h.in这个新文件。 7.运行命令autoconf 命令成功之后,会在目录下产生configure这个新文件。 8.运行命令automake --add-missing输出结果为: Configure.ac:11:installing./compile’ Configure.ac:8:installing ‘.install-sh’ Configure.ac:8:installing ‘./missing’ Makefile.am:installing ‘./decomp’ 9. 命令成功之后,会在目录下产生depcomp,install-sh和missing这三个新文件和执行下一步的Makefile.in文件。 10.运行命令./configure就可以自动生成Makefile。 4.添加内核模块

实例解析linux内核I2C体系结构(2)

实例解析linux内核I2C体系结构(2) 华清远见刘洪涛四、在内核里写i2c设备驱动的两种方式 前文介绍了利用/dev/i2c-0在应用层完成对i2c设备的操作,但很多时候我们还是习惯为i2c设备在内核层编写驱动程序。目前内核支持两种编写i2c驱动程序的方式。下面分别介绍这两种方式的实现。这里分别称这两种方式为“Adapter方式(LEGACY)”和“Probe方式(new style)”。 (1)Adapter方式(LEGACY) (下面的实例代码是在2.6.27内核的pca953x.c基础上修改的,原始代码采用的是本文将要讨论的第2种方式,即Probe方式) ●构建i2c_driver static struct i2c_driver pca953x_driver = { .driver = { .name= "pca953x", //名称 }, .id= ID_PCA9555,//id号 .attach_adapter= pca953x_attach_adapter, //调用适配器连接设备 .detach_client= pca953x_detach_client,//让设备脱离适配器 }; ●注册i2c_driver static int __init pca953x_init(void) { return i2c_add_driver(&pca953x_driver); } module_init(pca953x_init); ●attach_adapter动作 执行i2c_add_driver(&pca953x_driver)后会,如果内核中已经注册了i2c适配器,则顺序调用这些适配器来连接我们的i2c设备。此过程是通过调用i2c_driver中的attach_adapter方法完成的。具体实现形式如下: static int pca953x_attach_adapter(struct i2c_adapter *adapter) { return i2c_probe(adapter, &addr_data, pca953x_detect); /* adapter:适配器 addr_data:地址信息 pca953x_detect:探测到设备后调用的函数 */ } 地址信息addr_data是由下面代码指定的。 /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,I2C_CLIENT_END}; I2C_CLIENT_INSMOD;

嵌入式Linux之Kernel(裁减移植)启动调试、打印技术 printascii(补充)、内核调试

嵌入式系统搭建过程中,对于系统平台搭建工程师在完成Bootloader 的调试之后就进入Kernel 裁减移植的阶段,其中最重要的一步是Kernel 启动的调试,在调试Kernel 过程中通常遇到最常见的问题是启动异常: Uncompressing Linux............................................................ ........................... done, booting the kernel.( 挂死在此处) 注意:这里是arch/arm/boot/compressed/head.S的解压过程,调用了decompress_kernel()(同目录下的misc.c)->include/asm-arm/arch-xxx/uncompress.h的putc()实现。这是在uboot中初始化的,用的是物理地址,因为此时内核还没有起来。 而printascii则是调用了汇编。printascii()位于arch/arm/kernel/debug.S,他需要调用虚拟地址,此虚拟地址通过machine_start提供,而相关的宏在include/asm/arch-xxx/debug-macro.S实现,这下明白了。 10-05-14添加:debug.s里面需要判断一下当前是否打开了mmu,然后指定uart的基址。在解压阶段的head.s,mmu是1:1映射,目的是加快速度。到了内核的head.s,就是真正的mmu了,此时就是虚拟地址了。 导致驱动异常(启动挂死)的原因有很多,如基于EVM 板的硬件做了修改(如更改了FLASH 空间大小、地址和型号,更改了SDRAM 、DDR SDRAM 空间大小、地址和型号,更改了晶振频率等),板卡ID号不支持等。那么如何进行调试那,其实有两种调试技术比较有效。 Kernel 启动调试技术- 使用printascii() 函数跟踪start_kernel() 有没运行,在booting the kernel 之后Kernel 最先执行的是start_kernel() 函数,确认start_kernel() 有否执行就是在其开始代码段添加printascii("start_kernel …") ,如果串口没有打印出start_kernel …,说明start_kernel() 没有运行,那么可能的原因有Bootloader 配置的启动参数错误、 Kernel 加载到(DDR) SDRAM 的地址不正确, Kernel 编译时指定的(DDR) SDRAM 运行地址不正确等。这样就需要一项一项排查错误,当错误被排查完毕,通常打印出start_kernel …是种必然,如果打印出这仪信息说明 Kernel已进入到start_kernel() 执行,如果此时有串口启动打印就比较成功了,如果仍然没有打印启动信息,就需要另外一种调试技术。 附代码修改:init/main.c <<- … extern void printascii(const char*); // Modify asmlinkage void __init start_kernel(void)

使用QEMU+GDB调试Linux内核

使用QEMU调试Linux内核 一.使用QEMU安装Ubuntu10.04 1.安装qemu ubuntu下使用sudo apt-get install 安装的qemu版本是0.12.3,该版本中存在bug,使得无法在断点处停下;因此需要在qemu官方网站https://www.doczj.com/doc/496709552.html,/Download上下载最新的版本qemu-0.12.5.tar.gz的源代码包自己进行编译安装: ●Sudo apt-get install zlib1g-dev libsdl-dev ●解压源代码后,进入源代码所在目录执行./confingure ●执行make ●执行sudo make install 2.创建QEMU格式的硬盘 qemu-img create –f qcow2name.img size 例如:qemu-img create –f qcow2 ubuntu10.04.img 4GB 3.在创建的硬盘上安装操作系统 qemu–hdaname.img–cdrom ~/Download/ubuntu10.04.iso –boot d 说明:使用hda指定硬盘镜像,使用CDROM选定光驱。-boot d 指从cdrom启动,-boot a是软盘,-boot c 是硬盘;使用qemu或qemu-system-x86_64(64为机子),有时安装系统会很慢,这是可以考虑使用kvm来代替。 例如:kvm–hda ubuntu10.04.img –cdrom ./ubuntu-10.04.iso -boot

d 4.从已经装好操作系统的硬盘启动 qemu–hda ubuntu10.04.img 5.在64位的主机上要使用qemu-system-x86_64命令来代替qemu 二.自己编译内核 现将Linux的编译调节过程简述为: 1. 下载自己要调试的Linux内核的源代码,这个可以从Linux内 核的官方网站上得到:https://www.doczj.com/doc/496709552.html, 2. 编译内核最主要的便是配置文件.config,为了能够准确的得到 结果(第一次不要求编译时间),将本机的config文件直接拷 贝到解压后的源代码中。 3.然后进行make操作,结束后将产生的bzImage文件拷到boot 目录下,重启,选择自己编译的内核,这样一般不会出问题,但时间较慢,大约编译一次需要40分钟。 3.1以前编译内核是为调试内核服务的,现在做华为的项目, 发现需要在实际的机器上运行自己编译的内核,参考网站: https://www.doczj.com/doc/496709552.html,/tips/compiling-linux-kernel-26.html 4.为了降低编译时间,就需要对配置文件进行裁剪,在配置文件 中有好多是本机不需要的模块,参考: https://www.doczj.com/doc/496709552.html,/Linux/kernel_options.html。另外调试内 核与模块无关,所以辨识为M的直接可以不选。 5.剪裁的时候采用“逐步瘦身”法,先剪裁掉某个或某几个模块, 然后在进行编译,若没错,在进行模块裁剪,这样可以最大程

Linux_I2C总线分析(主要是probe的方式)1

Linux I2C 总线浅析 ㈠ Overview 内核空间层次! i2c adapter 是一个struct, 用来抽象一个物理i2c bus ,而且还和linux 设备驱动架构柔和在一起.. 如果只说硬件的话,就是在CPU内部集成的一个I2C控制器(提供给用户的就是那几个register),硬件上并没的所谓的adapter,client这些东东,,adapter和client都是linux 驱动软件抽象出来的东西 资料帖子: i2c_algorithm { /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated

using common I2C messages */ /* master_xfer should return the number of messages successfully processed, or a negative value on error */ i nt (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); i nt (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data); /* To determine what the adapter supports */ u32 (*functionality) (struct i2c_adapter *); }; /* * i2c_adapter is the structure used to identify a physical i2c bus along * with the access algorithms necessary to access it. */ struct i2c_adapter { s truct module *owner; u nsigned int id; u nsigned int class; /* classes to allow probing for */ c onst struct i2c_algorithm *algo; /* the algorithm to access the bus */ v oid *algo_data; /* data fields that are valid for all devices */ u8 level; /* nesting level for lockdep */ s truct mutex bus_lock; i nt timeout; /* in jiffies */ i nt retries; s truct device dev; /* the adapter device */ i nt nr; c har name[48]; s truct completion dev_released; }; Linux的I2C体系结构分为3个组成部分: 1·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即“algorithm”)上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。这部分是与平台无关的。 2·I2C总线驱动: I2C总线驱动是对I2C硬件体系结构中适配器端的实现。I2C总线驱动主要包含了I2C适配

在vmware虚拟机上调试内核

安装系统(在创建一个新的虚拟机时一定要用IDE硬盘) 1、在vmware上安装一个linux虚拟机(我用的软件版本:vmware 5.5, fedora 6) 从Internet下载源代码 1、linux-2.6.16 2、kgdb-2.6.16 编译内核 1、将kgdb-2.6.16补丁打到Linux内核源码里。 2、编译内核(make menuconfig, make, make modules_install, make install) 在内核配置菜单的Kernel hacking选项中选择kgdb调试项,例如: [*] KGDB: kernel debugging with remote gdb [*] KGDB: Console messages through gdb Method for KGDB communication (KGDB: On generic serial port (8250)) ---> < > KGDB: On ethernet [*] Simple selection of KGDB serial port (115200) Debug serial port baud rate (0) Serial port number for KGDB 3、修改grub.conf 例如: title Fedora Core (2.6.16) root (hd0,0) kernel /vmlinuz-2.6.16 ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.16_debug.img 改为: title Fedora Core (2.6.16) root (hd0,0) kernel /vmlinuz-2.6.16 ro root=/dev/VolGroup00/LogVol00 kgdb8250=0,115200 initrd /initrd-2.6.16_debug.img 4、请检验新编译的内核是否可用。如果不能启动,可能是编译选项没有选好(一直困扰我的问题。实在不行就多选点)。如果没有问题,关闭这个linux虚拟机,进入下一步。

linux2.6内核的编译步骤及模块的动态加载-内核源码学习-linux论坛

[原创]linux2.6内核的编译步骤及模块的动态加载-内核源码 学习-linux论坛 05年本科毕业设计做的是Linux下驱动的剖析,当时就买了一本《Linux设备驱动程序(第二版)》,但是没有实现将最简单的helloworld程 序编译成模块,加载到kernel里。不过,现在自己确实打算做一款芯片的Linux的驱动,因此,又开始看了《Linux设备驱动程序》这本书,不过已 经是第三版了。第二版讲的是2.4的内核,第三版讲的是2.6的内核。两个内核版本之间关于编译内核以及加载模块的方法都有所变化。本文是基于2.6的内核,也建议各位可以先看一下《Linux内核设计与实现(第二版)》作为一个基础知识的铺垫。当然,从实践角度来看,只要按着以下的步骤去做也应该可以实现成功编译内核及加载模块。个人用的Linux版本为:Debian GNU/Linux,内核版本为:2.6.20-1-686.第一步,下载Linux内核的源代码,即构建LDD3(Linux Device Drivers 3rd)上面所说的内核树。 如过安装的Linux系统中已经自带了源代码的话,应该在/usr/src目录下。如果该目录为空的话,则需要自己手动下载源代码。下载代码的方法和链接很多,也可以在CU上通过

https://www.doczj.com/doc/496709552.html,/search/?key=&;q=kernel&a mp;frmid=53去下载。不过,下载的内核版本最好和所运行的Linux系统的内核版本一致。当然,也可以比Linux系统内核的版本低,但高的话应该不行(个人尚未实践)。 Debian下可以很方便的通过Debian源下载: 首先查找一下可下载的内核源代码: # apt-cache search linux-source 其中显示的有:linux-source-2.6.20,没有和我的内核版本完全匹配,不过也没关系,直接下载就可以了: # apt-get install linux-source-2.6.20 下载完成后,安装在/usr/src下,文件名为: linux-source-2.6.20.tar.bz2,是一个压缩包,解压缩既可以得到整个内核的源代码: # tar jxvf linux-source-2.6.20.tar.bz2

相关主题
文本预览
相关文档 最新文档