⑴ 为什么x86和arm的架构不同,但是都能装linux呢,他们的编译时如何实现的。
rm架构和x86架构区别:
一、性能:
X86结构的电脑无论如何都比ARM结构的系统在性能方面要快得多、强得多。X86的CPU随便就是1G以上、双核、四核大行其道,通常使用45nm(甚至更高级)制程的工艺进行生产;
而ARM方面:CPU通常是几百兆,最近才出现1G左右的CPU,制程通常使用不到65nm制程的工艺,可以说在性能和生产工艺方面ARM根本不是X86结构系统的对手。
但ARM的优势不在于性能强大而在于效率,ARM采用RISC流水线指令集,在完成综合性工作方面根本就处于劣势,而在一些任务相对固定的应用场合其优势就能发挥得淋漓尽致。
二、扩展能力:
X86结构的电脑采用“桥”的方式与扩展设备(如:硬盘、内存等)进行连接,而且x86结构的电脑出现了近30年,其配套扩展的设备种类多、价格也比较便宜,所以x86结构的电脑能很容易进行性能扩展,如增加内存、硬盘等。
ARM结构的电脑是通过专用的数据接口使CPU与数据存储设备进行连接,所以ARM的存储、内存等性能扩展难以进行(一般在产品设计时已经定好其内存及数据存储的容量),所以采用ARM结构的系统,一般不考虑扩展。基本奉行“够用就好”的原则。
三实现编译:
因为linux是系统,他支持现在大多数的结构体系。而要使他移植到相应的不同的硬件平台上时,需要对内核源码进行相对应的交叉编译处理,然后才能进行烧写运行,因为都有驱动只要那个系统有对应平台的驱动就可以。
(1)x86驱动编译扩展阅读:
Linux常用命令
1、pwd命令该命令的英文解释为print working directory(打印工作目录)。
2、输入pwd命令,Linux会输出当前目录。
3、cd命令cd命令用来改变所在目录。
4、cd / 转到根目录中
5、cd ~ 转到/home/user用户目录下
6、cd /usr 转到根目录下的usr目录中-------------绝对路径
7、cd test 转到当前目录下的test子目录中-------相对路径
8、cat命令可以用来合并文件,也可以用来在屏幕上显示整个文件的内容。
9、cat snow.txt 该命令显示文件snow.txt的内容,ctrl+D退出cat。
⑵ 如何编译加载linux驱动和内核模块
linux下编译运行驱动
嵌入式linux下设备驱动的运行和linux x86 pc下运行设备驱动是类似的,由于手头没有嵌入式linux设备,先在vmware上的linux上学习驱动开发。
按照如下方法就可以成功编译出hello world模块驱动。
1、首先确定本机linux版本
怎么查看Linux的内核kernel版本?
'uname'是Linux/unix系统中用来查看系统信息的命令,适用于所有Linux发行版。配合使用'uname'参数可以查看当前服务器内核运行的各个状态。
#uname -a
Linux whh 3.5.0-19-generic #30-Ubuntu SMPTue Nov 13 17:49:53 UTC 2012 i686 i686 i686 GNU/Linux
只打印内核版本,以及主要和次要版本:
#uname -r
3.5.0-19-generic
要打印系统的体系架构类型,即的机器是32位还是64位,使用:
#uname -p
i686
/proc/version 文件也包含系统内核信息:
# cat /proc/version
Linux version 3.5.0-19-generic(buildd@aatxe) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) ) #30-UbuntuSMP Tue Nov 13 17:49:53 UTC 2012
发现自己的机器linux版本是:3.5.0-19-generic
2、下载机器内核对应linux源码
⑶ 怎么用Visual Studio编译内核驱动
在Win8以前开发内核驱动,准备编译环境是个较繁琐的事情。程序员需要手动下载WDK并安装(注1),开发环境就在安装好的WDK中。WDK是Windows Driver Kit缩写,即Windows驱动开发包。它提供的开发环境简陋得很,它不是一个便于开发的IDE环境,而仅仅是一些散装的编译工具包。
安装好WDK后,WDK的编译环境链接就显示在开始菜单中了,要小心不能将它们删掉,否则会麻烦,因为手动生成链接是麻烦事,后文会讲。
编译环境是分类的。首先根据目标系统分类,也就是要编译生成运行在什么OS上的目标文件。微软大部分的产品都保持了向后兼容的习惯,这条规律也适用于此处:使用Win7子系统环境编译出来的驱动文件,一般都能运行在Vista和XP系统上,反之就不会成立(注2)。
其次根据硬件平台分类,现在Windows系统能够运行的平台有四个:X86,X64,IA64和ARM。其中ARM是Win8才开始的故事,这里还轮不到它出场,这样就只有前面三个硬件平台(注3)。
最后又要根据编译版本来分,即Checked(也可认做Debug)和Free(也可认作Release)这两种。这样来看,每个OS组别下面,就一定有6个编译环境链接。
在这本书里面,如果用旧版本WDK编译驱动,就默认使用Win7目标系统的编译环境,生成Checked版本,目标平台是X86或X64。所以就只会选两种:X86 Checked Build Environment和X64 Checked Build Environment.
编译环境打开来其实就是个控制台。它当然不同于直接从cmd.exe运行起来的控制台环境,区别在哪里呢?我们已经知道,上图的这些黑色的编译环境图标,其实都是快捷方式。不妨就看看它的快捷方式的Target内容,或许就知道端倪了。以X64 Checked Build Environment这个环境为例,打开来看到如下内容:
C:\Windows\System32\cmd.exe /k C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinDDK\7600.16385.1\ chk x64 WIN7
这一行内容仔细一看就很简单了。原来所谓的编译环境,就是一个运行cmd.exe的控制台进程,只不过它执行了用于初始化的/k参数。在Cmd.exe命令的帮助中,/k参数是这样描述的:Carries out the command specified by string but remains(执行一个命令,执行完之后不退出程序)。也就是说,启动控制台进程并执行命令,执行完后,控制台程序留给用户继续使用。
那么/k之后的所有内容,都是一条初始化的命令:
C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinDDK\7600.16385.1\ chk x64 WIN7
它却又可拆成几个部分来分析。第一个setenv.bat是初始化编译环境的批文件。后面的是它的参数:第一个参数,是WDK的路径,通过它可以找到编译器程序;第二个参数是指明要编译生成checked版本目标文件;第三个指明硬件平台是x64;第三个指明目标系统是Win7。
位于WDK中的Setenv.bat文件是负责编译环境配置的总厨,你把什么参数递给它,它就给你配出什么类型的编译环境来(菜也)。
怎么在这个控制台里面编译驱动呢?我们统一用使用以下步骤:
通过CD命令,定位到含有source文件的那个驱动目录;
输入build或bld(build –cz的简写)命令进行编译;
如果编译成功,将生成驱动文件,否则会有错误或警告信息显示出来;也可通过查看目录文件夹下面的相关log文件查看详细的错误或警告信息。
走到这里,编译的事情算弄明白了。可能还会有朋友问我,我用什么东西写代码呢?不好意思,关于这个问题,此时还没有康庄大道供大家驷马高车,不过千万条小路却是现成的。您可以用notepad记事本或者任何文本编辑器来编辑代码,如果不嫌麻烦,用Visual Studio写代码也可以,只不过仅作代码编辑而已。
⑷ vs2015驱动开发编译错误
楼主 你解决了吗 我也遇到这样的问题 好烦人 以前都没有遇到过
⑸ android 移植到x86 怎么移植驱动 有没有详细的教程 要有实例的 感谢
基本上来说,你直接下个android-x86版本的源代码,编译成ISO镜像就可以了,别人都已经做好了的。或者你干脆下个android-liveCD,直接可以在电脑上跑的
⑹ 如何编译一个linux下的驱动模块
linux下编译运行驱动
嵌入式linux下设备驱动的运行和linux x86 pc下运行设备驱动是类似的,由于手头没有嵌入式linux设备,先在vmware上的linux上学习驱动开发。
按照如下方法就可以成功编译出hello world模块驱动。
1、首先确定本机linux版本
怎么查看Linux的内核kernel版本?
'uname'是Linux/unix系统中用来查看系统信息的命令,适用于所有Linux发行版。配合使用'uname'参数可以查看当前服务器内核运行的各个状态。
#uname -a
Linux whh 3.5.0-19-generic #30-Ubuntu SMPTue Nov 13 17:49:53 UTC 2012 i686 i686 i686 GNU/Linux
只打印内核版本,以及主要和次要版本:
#uname -r
3.5.0-19-generic
要打印系统的体系架构类型,即的机器是32位还是64位,使用:
#uname -p
i686
/proc/version 文件也包含系统内核信息:
# cat /proc/version
Linux version 3.5.0-19-generic(buildd@aatxe) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) ) #30-UbuntuSMP Tue Nov 13 17:49:53 UTC 2012
发现自己的机器linux版本是:3.5.0-19-generic
2、下载机器内核对应linux源码
到下面网站可以下载各个版本linux源码https://www.kernel.org/
如我的机器3.5.0版本源码下载地址为:https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.tar.bz2
下载完后,找一个路径解压,如我解压到/linux-3.5/
然后很重要的一步是:执行命令uname -r,可以看到Ubuntu的版本信息是3.5.0-19-generic
。进入linux源码目录,编辑Makefile,将EXTRAVERSION = 修改为EXTRAVERSION= -19-generic。
这些都是要配置源码的版本号与系统版本号,如果源码版本号和系统版本号不一致,在加载模块的时候会出现如下错误:insmod: error inserting 'hello.ko': -1 Invalid mole format。
原因很明确:编译时用的hello.ko的kenerl 不是我的pc的kenerl版本。
执行命令cp /boot/config-3.5.0-19-generic ./config,覆盖原有配置文件。
进入linux源码目录,执行make menuconfig配置内核,执行make编译内核。
3、写一个最简单的linux驱动代码hello.c
/*======================================================================
Asimple kernel mole: "hello world"
======================================================================*/
#include <linux/init.h>
#include <linux/mole.h>
MODULE_LICENSE("zeroboundaryBSD/GPL");
static int hello_init(void)
{
printk(KERN_INFO"Hello World enter\n");
return0;
}
static void hello_exit(void)
{
printk(KERN_INFO"Hello World exit\n ");
}
mole_init(hello_init);
mole_exit(hello_exit);
MODULE_AUTHOR("zeroboundary");
MODULE_DESCRIPTION("A simple HelloWorld Mole");
MODULE_ALIAS("a simplestmole");
4、写一个Makefile对源码进行编译
KERN_DIR = /linux-3.5
all:
make-C $(KERN_DIR) M=`pwd` moles
clean:
make-C $(KERN_DIR) M=`pwd` clean
obj-m += hello.o
5、模块加载卸载测试
insmod hello.ko
rmmod hello.ko
然后dmesg|tail就可以看见结果了
最后,再次编译驱动程序hello.c得到hello.ko。执行insmod ./hello.ko,即可正确insert模块。
使用insmod hello.ko 将该Mole加入内核中。在这里需要注意的是要用 su 命令切换到root用户,否则会显示如下的错误:insmod: error inserting 'hello.ko': -1 Operation not permitted
内核模块版本信息的命令为modinfo hello.ko
通过lsmod命令可以查看驱动是否成功加载到内核中
通过insmod命令加载刚编译成功的time.ko模块后,似乎系统没有反应,也没看到打印信息。而事实上,内核模块的打印信息一般不会打印在终端上。驱动的打印都在内核日志中,我们可以使用dmesg命令查看内核日志信息。dmesg|tail
可能还会遇到这种问题insmod: error inserting 'hello.ko': -1 Invalid mole format
用dmesg|tail查看内核日志详细错误
disagrees about version of symbolmole_layout,详细看这里。
http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmoles/index.html
在X86上我的办法是:
make -C/usr/src/linux-headers-3.5.0-19-generic SUBDIRS=$PWD moles
⑺ 怎么编译linux x86
首先你需要设置一下emulator工具的目录之类的,这个不细说了,
要在.bashrc中新增环境变量,如下
ANDROID_PRODUCT_OUT=~/android/out/target/proct/generic
ANDROID_PRODUCT_OUT_BIN=~/android/out/host/linux-x86/bin
这里是设置你的输出文件的位置和bin工具目录,不用多解释吧?
然后在命令行输入:
export PATH=${PATH}:${ANDROID_PRODUCT_OUT_BIN}:${ANDROID_PRODUCT_OUT};
上面是导入了相关的配置,然后使之生效。
source ~/.bashrc
接着切换到输出的system文件夹
cd ~/android/out/target/proct/generic
然后来创建模拟器
emulator -system system.img -data userdata.img -ramdisk ramdisk.img
如果你运气够好的话,也许现在已经在运行了,不过我运气明显不够好。
提示一:
emulator: ERROR: You did not specify a virtual device name, and the system
directory could not be found.
If you are an Android SDK user, please use ‘@<name>’ or ‘-avd <name>’
to start a given virtual device (see -help-avd for details).
Otherwise, follow the instructions in -help-disk-images to start the emulator
既然人家提示了,那就按照步骤走吧,输入命令:
emulator -help-avd
接着提示如下:
use ‘-avd <name>’ to start the emulator program with a given Android
Virtual Device (a.k.a. AVD), where <name> must correspond to the name
of one of the existing AVDs available on your host machine.
See -help-virtual-device to learn how to create/list/manage AVDs.
As a special convenience, using ‘@<name>’ is equivalent to using
‘-avd <name>’.
跟着提示继续走,输入命令:
emulator -help-virtual-device
又是提示了:
An Android Virtual Device (AVD) models a single virtual
device running the Android platform that has, at least, its own
kernel, system image and data partition.
Only one emulator process can run a given AVD at a time, but
you can create several AVDs and run them concurrently.
You can invoke a given AVD at startup using either ‘-avd <name>’
or ‘@<name>’, both forms being equivalent. For example, to launch
the AVD named ‘foo’, type:
emulator @foo
The ‘android’ helper tool can be used to manage virtual devices.
For example:
android create avd -n <name> -t 1 # creates a new virtual device.
android list avd # list all virtual devices available.
Try ‘android –help’ for more commands.
Each AVD really corresponds to a content directory which stores
persistent and writable disk images as well as configuration files.
Each AVD must be created against an existing SDK platform or add-on.
For more information on this topic, see -help-sdk-images.
⑻ (pc安装)安卓x86,如何安装无线网卡驱动linux版
最佳答案 tar.gz(bz或bz2等) 一、安装 1、打开一个SHELL,即终端 2、用cd 命令进入源代码压缩包所在的目录 3、根据压缩包类型解压缩文件(*代表压缩包名称) tar -zxvf ****.tar.gztar -jxvf ****.tar.bz(或bz2) 4、用CD命令进入解压缩后的目录 5、输入编译文件命令:./configure(有的压缩包已经 编译过,这一步可以省去) 6、然后是命令:make 7、再是安装文件命令:make install 8、安装完毕
⑼ 最近研究了一下Android x86想了解一下,能不能把nvidia的linux驱动编译进Android x86
理论可以,实际上很困难。android只是用了linux的底层内核,与当前的LINUX发行版相比差了太多,需要很复杂的编译知识,要借助很多API,LZ没有到一定境界的话还是算了。NVIDIA将来在TRGEA的影响下会出驱动的。
⑽ x86架构下linux驱动编程 看什么书
编写好驱动,通过挂载的方法将驱动程序挂载到内核里面,大致步骤如下:
一: 1>建立以.c为后缀的c语言程序文件(里面包含了设备名及设备号等)
2>建立Makefile文件(作用是通过make来产生设备文件*.ko文件,里面可以建立自己的平台所需的设备文件如:arm等).make产生相应的设备文件
二: 要在/dev下建立相应的设备结点(设备名),用insomd *.ko命令将相应的驱动设备文件挂载到内核中.
三:编写测试文件(.c文件)用来测试内核是否已近成功挂载到内核.(编写好相应的测试文件后,用gcc –o Filename Filename.c(测试文件名)来产生相应的可执行文件).
四:如果设备驱动挂载成功,当执行测试文件(./Filename)时会产生相应的结果.
五:可能用到的相关命令:
1.lsmod:列出内核已经载入模块的专题.
输出:
Mole(模块名)size(大小)used by (被..使用)
2.demop:分析可加载模块的依赖性,生成moles.dep文件和映射文件
3.uname –r 显示内核版本(在编写Makefile时使用到)
4.modprobe : linux内核添加和删除模块(相关参数请查看man帮助文档)
5.modinfo:显示内核模块的信息.
6.insmod: 向linux内核中加载一个模块,用法:insmod[filename] [mole options…]
7.rmmod: 删除内核中的模块, 用法: rmmod [-f,w,s,v][molename]
8.dmesg: 显示内核缓冲区,内核的各种信息,内核启动时的信息会写入到/var/log/下.
六.例子1:
第一步:增加头文件和宏定义
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/mole>
#include <linux/kernel>
第二步:添加与字符设备定义及注册有关的数据成员
//定义设备名称
#define DEVICE_NAME "test" //设备名
#define BUF_SIZE 1024
static char tmpbuf[BUF_SIZE];
//定义主次设备号
static unsigned int TestMajor=0; //主
static unsigned int TestMinor=0; //次
static struct cdev *test_cdev;
static dev_t dev;
第三步:增加open/release函数
static int test_chardev_open(struct inode *inode,struct file *file)
{
printk("open major=%d, minor=%d\n", imajor(inode),
iminor(inode));
return 0;
}
static int test_chardev_release(struct inode *inode,struct file *file)
{
printk("close major=%d,minor=%d\n",imajor(inode),
iminor(inode));
return 0;
}
第四步:增加read函数
static ssize_t test_chardev_read(struct file *file,char __user *buf,
size_t const count,loff_t *offset)
{
if(count < BUF_SIZE)
{
if(_to_user(buf,tmpbuf,count))
{
printk(" to user fail \n");
return -EFAULT;
}
}else{
printk("read size must be less than %d\n", BUF_SIZE);
return -EINVAL;
}
*offset += count;
return count;
}
第五步:增加write函数
static ssize_t test_chardev_write(struct file *file, const char __user*buf,size_t const count,loff_t *offset)
{
if(count < BUF_SIZE)
{
if(_from_user(tmpbuf,buf,count))
{
printk(" from user fail \n");
return -EFAULT;
}
}else{
printk("size must be less than %d\n", BUF_SIZE);
return -EINVAL;
}
*offset += count;
return count;
}
第六步:添加增加file_operations成员
static struct file_operations chardev_fops={
.owner = THIS_MODULE,
.read = test_chardev_read,
.write = test_chardev_write,
.open = test_chardev_open,
.release = test_chardev_release,
};
第七步:在模块的入口添加设备的设备号获取及设备注册
static int __init chrdev_init(void)
{
int result;
if(TestMajor)
{
dev=MKDEV(TestMajor,TestMinor);//创建设备编号
result=register_chrdev_region(dev,1,DEVICE_NAME);
} else {
result=alloc_chrdev_region(&dev,TestMinor,1,DEVICE_NAME);
TestMajor=MAJOR(dev);
}
if(result<0)
{
printk(KERN_WARNING"LED: cannot get major %d \n",TestMajor);
return result;
}
test_cdev=cdev_alloc();
cdev_init(test_cdev,&chardev_fops);
//test_cdev->ops=&chardev_fops;
test_cdev->owner=THIS_MODULE;
result=cdev_add(test_cdev,dev,1);
if(result)
printk("<1>Error %d while register led device!\n",result);
return 0;
}
第八步:在模块的出口函数增加设备设备号释放及设备注销函数
unregister_chrdev_region(MKDEV(TestMajor,TestMinor),1);
cdev_del(test_cdev);
第九步:编译并加载该模块
第十步:根据设备号的设置,在文件系统中建立对应的设备节点
#mknod /dev/test c XXX XX
例子2:
驱动文件:
#include <linux/init.h>
#include <linux/mole.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#define DEVICENAME "ccccc"
unsigned int major=221;
unsigned int minor=0;
struct cdev *abc;
dev_t dev;
static char bufrh[1024]="read success!";
static int aaaaa_open(struct inode *inodep, struct file *filep)
{
printk("read success!\n");
return 0;
}
int aaaaa_release(struct inode *inodep, struct file *filep)
{
return 0;
}
static ssize_t aaaaa_read (struct file *filep, char __user *buf, size_tcount, loff_t *offset)
{
if(_to_user(buf, bufrh, 1))
{
printk("_to_user fail!\n");
}
return 0;
}
ssize_t aaaaa_write (struct file *filep, const char __user *buf,size_t count, loff_t *offse)
{
printk("write!\n");
return 0;
}
static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = aaaaa_open,
.release = aaaaa_release,
.read = aaaaa_read,
.write = aaaaa_write,
};
static int __init aaaaa_init(void)
{
int a;
dev=MKDEV(major, minor);
a=register_chrdev_region(dev, 1, DEVICENAME);
abc=cdev_alloc();
abc->owner=THIS_MODULE;
cdev_init(abc, &fops);
cdev_add(abc, dev, 1);
return 0;
}
static void __exit aaaaa_cleanup(void)
{
cdev_del(abc);
unregister_chrdev_region(dev, 1);
}
mole_init(aaaaa_init);
mole_exit(aaaaa_cleanup);
MODULE_LICENSE("GPL ");
Makefile文件:
obj-m += firstqd.o(相应设备文件名)
KERDIR = /usr/src/linux-headers-2.6.32-24-generic
#KERDIR=/home/linux2.6/linux #arm骞冲彴
PWD=$(shell pwd)
moles:
$(MAKE) -C $(KERDIR) M=$(PWD)moles
pc:
gcc -o fristqd firstqd.c
arm:
arm-linux-gcc -o fristqd firstqd.c
clean:
rm -rf *.o *~core *.depend *.cmd *.ko *.mod.c *.tmp_versions
测试文件(test.c):
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
char buf[1024];
char bufw[1024]="write success";
int main()
{
int fd,m,n;
fd=open("/dev/aaa",O_RDWR);
if (fd)
{
m=read(fd,buf,100);
printf("read kernel:%s\n",buf);
n=write(fd,bufw,10);
}
//printf("ni hao");
return 0;
}