如何将linux驱动程序添加到内核中

如何将linux驱动程序添加到内核中,第1张

工具/原料

Ubuntu12.04 *** 作系统和测试驱动程序(beep_arv.c)

方法/步骤

在介绍2种方法前,必须知道的知识点:

1.关联文件Makefile:

Makefile:分布在Linux内核源代码中的Makefile用于定义Linux内核的编译规则;

2.管理文件Kconfig:

给用户提供配置选择的功能;

配置工具:

1)包括配置命令解析器;

2)配置用户界面;menuconfig || xconfig;

3)通过脚本语言编写的;

3.

---tristate 代表三种状态:1.[ ]不选择,2.[*]选择直接编译进内核,加载驱动到内核里,3.[m]动态加载驱动;

---bool 代表两种状态,1.[ ]不选择,2.[*]选择;

---"Mini2440 module sample"这个是在make menuconfig时刷出的提示字符;

---depends on MACH_MINI2440 这个配置选项出现在make menuconfig菜单栏下,在内核配置中必须选中、MACH_MINI2440;

---default m if MACH_MINI2440 这个如果选中了MACH_MINI2440,默认是手

动加载这个驱动;

help:提示帮助信息;

在了解了基本的知识点,便开始进行第一种添加驱动的方法,本次交流是以beep_arv.c蜂鸣驱动程序为基础的

方法一:

1)进入内核的驱动目录;

#cp beep_arv.c /XXX/.../linux-XXXl/drivers/char

2)进入Kconfig添加驱动信息;

#cd /XXX/linux-XXX/.../drivers/char

#vim Kconfig

添加基本信息:

config BEEP_MINI2440

tristate "---HAH--- BEEP"

default

help

this is test makefile!

3)进入Makefile添加驱动编译信息;

#vim Makefile

添加基本信息:

obj-$(CONFIG-BEEP_MINI2440) +=beep_drv.o

方法一结果:

在--Character devices下就能看到配置信息了;

方法二:

1)进入驱动目录,创建BEED目录;

#cd /XXX/.../linux-XXX/drivers/char

#mkdir beep

2)将beep_arv.c驱动程序复制到新建目录下;

#cp beep_arv.c /XXX/.../linux-XXXl/drivers/char/beep

3)创建Makefile和Kconfig文件

#cd char/beep

#mkdir Makefile Kconfig

#chmod 755 Makefile

#chmod 755 Kconfig

4)进入Kconfig添加驱动信息;

#vim Kconfig

添加基本信息:

config BEEP_MINI2440

tristate "---HAH--- BEEP"

default

help

this is test makefile!

5)进入Makefile添加驱动编译信息;

#vim Makefile

添加基本信息:

obj-$(CONFIG_BEEP_MINI2440) +=beep_drv.o

6)并且要到上一级目录的Makefile和Kconfig添加驱动信息;

#cd ../

#vim Makefile

#vim Kconfig

Linux内核的最初部分代码是用汇编语言写的(文件是boot/bootsect.s)。(我的汇编水平有限,暂且不看),它首先把自身这部分代码移到绝对地址0x90000,把下面的2K代码从引导设备加载到地址0x90200上,内核的其余部分加载到地址0x10000处。在加载系统时显示“loading...”. 然后,程序控制权交给另一个实模式汇编程序(boot/Setup.S)。

接下来,此程序把整个系统从地址0x10000移到地址0x1000,进入保护模式。程序控制转给系统的其余部分即地址0x1000。

下一个步骤是系统内核的解压过程,这部分代码在地址0x1000(文件/Boot/head.S),该段程序初始化寄存器,然后执行decompress_kernel(),这个函数源于zBoot/inflate.c、zBoot/unzip.c和zBoot/misc.c三个文件

Loading ....[ bootsect.S ]

uncompress .....[ decompress_kernel() ]

main.c ---> start_kernel() 开始.

开始 printk(banner)

Linux version 2.2.6 (root@lance) (gcc version 2.7.2.3) (检查一下GCC 的版本号, 在/init/main.c 中如果gcc 的版本号不够,时不允许编译内核的)

#40 Sun Apr 18 17:44:20 CST 1999

调用init_time()打印出以下内容:

Detected 199908264 Hz processor.

然后运行 console_init() --> drivers/char/tty_io.c */

Console: colour VGA+ 80x25

运行一个循环,测量一下 MIPS – 据说是要用一个确定的机器指令周期来实现实时的延迟.

Calibrating delay loop... 199.48 BogoMIPS

初始化内存/* init_mem */

Memory: 63396k/65536k available (848k kernel code, 408k reserved, 856k data

, 28k

/** dquote_init() **/

VFS: Diskquotas version dquot_6.4.0 initialized

察看cpu 的类型(在2.2.14 以后听说增加了对多种cpu 的支持, 以后我可得用心看看,if I can find a bug of intel then ……)

CPU: Intel Pentium Pro stepping 09

初始或处理器与协处理器,对于比较老的处理器, linux 会用软件模拟协处理器?

Checking 386/387 coupling... OK, FPU using exception 16 error reporting.

检查治理的合法性

Checking 'hlt' instruction... OK.

POSIX conformance testing by UNIFIX

此后调用 linux_thread(init ,..,..,)(arch/i386/kernel/process.c)

创建一个运行 init 的进程.

进入了第二阶段用户模式 ( user_mode )End of start_kerne最后进入cpu_idle ( arch/i386/kernel/process.c )

第二部分 设备的初始化

对设备的初始化调用. init()--->do_basic_init()--+

pci_init() 对pci 设备的初始化( 在main.c文件中有这样一段 ifdef PCI …..需要看一下)下面打印出结果:

PCI: PCI BIOS revision 2.10 entry at 0xfd8d1

PCI: Using configuration type 1

PCI: Probing PCI hardware

对Socket的初始化,socket_init() (这里也许就是linux 的网络秘密所在吧,以后我的注意) -Linux NET4.0 for Linux 2.2

Based upon Swansea University Computer Society NET3.039

NET4: Unix domain sockets 1.0 for Linux NET4.0.

NET4: Linux TCP/IP 1.0 for NET4.0

IP Protocols: ICMP, UDP, TCP

Starting kswapd v 1.5 kswapd_setup()

调用 device_setup()

Detected PS/2 Mouse Port.

初始化 声卡

Sound initialization started

Sound initialization complete

初始化 软驱

Floppy drive(s): fd0 is 1.44M

FDC 0 is a National Semiconductor PC87306

SCSI 设备的初始化

(scsi0)  found at PCI 13/0

(scsi0) Wide Channel, SCSI ID=7, 16/255 SCBs

(scsi0) Downloading sequencer code... 419 instructions downloaded

scsi0 : Adaptec AHA274x/284x/294x (EISA/VLB/PCI-Fast SCSI) 5.1.10/3.2.4

scsi : 1 host.

Vendor: SEAGATE Model: ST32155W Rev: 0596

ype: Direct-Access ANSI SCSI revision: 02

Detected scsi disk sda at scsi0, channel 0, id 0, lun 0

Vendor: SEAGATE Model: ST32155W Rev: 0596

Type: Direct-Access ANSI SCSI revision: 02

Detected scsi disk sdb at scsi0, channel 0, id 1, lun 0

scsi : detected 2 SCSI disks total.

(scsi0:0:0:0) Synchronous at 40.0 Mbyte/sec, offset 8.

SCSI device sda: hdwr sector= 512 bytes. Sectors= 4197405 [2049 MB] [2.0 GB ](scsi0:0:1:0) Synchronous at 40.0 Mbyte/sec, offset 8.

SCSI device sdb: hdwr sector= 512 bytes. Sectors= 4197405 [2049 MB] [2.0 GB]Partition check: sda: sda1 |

sdb: sdb1 sdb2  |

安装 文件系统 filesystem_setup()

安装设备驱动程序 mount_root()

VFS: Mounted root (ext2 filesystem) readonly.

Freeing unused kernel memory: 28k freed

Adding Swap: 66540k swap-space (priority -1)

Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996

SB 3.01 detected OK (220)

at 0x220 irq 5 dma 1

YM3812 and OPL-3 driver Copyright (C) by Hannu Savolainen, Rob Hooft 1993-1

996 at 0x388

NET4: AppleTalk 0.18 for Linux NET4.0

eth0: Intel EtherExpress Pro 10/100 at 0xf800, 00:A0:C9:49:2F:FF, IRQ 9.

Board assembly 645520-034, Physical connectors present: RJ45

Primary interface chip DP83840 PHY #1.

DP83840 specific setup, setting register 23 to 8462.

General self-test: passed.

Serial sub-system self-test: passed.

Internal registers self-test: passed.

ROM checksum self-test: passed (0x49caa8d6).

Receiver lock-up workaround activated.

NET4: AppleTalk 0.18 for Linux NET4.0

结束 do_basic_setup()

open("/dev/console", O_RDWR, 0)

开始执行 /sbin/init ( execv(...) )

内核就此启动完毕...

不行,

内核是内核,只提供最基本的服务。很多服务可以编译成模块装入内核,但是模块也不是无限多的。你编译过内核吗?内核文件不大,解压出来有200多M吧,如果全部功能编译的话,一般电脑没有几天可能下不来。

把程序编译到内核,不是不行,不过你的程序要修改。如果你能为linux内核提供代码的水平,估计离你说的就不远了。

你的想法有点...... 在你硬盘上读点东西就那么吝啬吗?

我Linux4G多的文件,分了6G数据空间,还有2G的交换文件,我都没心疼。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8368523.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-15
下一篇 2023-04-15

发表评论

登录后才能评论

评论列表(0条)

保存