当前位置:首页 » 安卓系统 » android内核模块编译

android内核模块编译

发布时间: 2023-03-27 22:45:45

Ⅰ 如何添加iptables/netfilter模块到安卓内核

所以要实现netfilter(iptables)就要从两方面来着手:1)内核支持netfilter;2)用户层的iptables配置命令。
1、编译内核,支持netfilter
在宿主机上进入linux内核目录,配置所需的内核模块:cd/usr/SRC/linuxmakemenuconfig
选中如下内核选项:
Generalsetup---
[*]Sysctlsupport(在ROMFS文件系统中/proc/syS/Net/ipv4/出现ip_forward)
Networkingoptions---[*]NetworkPACketfiltering(replaceSIPchains)IP:NetfilterConfiguration---(全部选择即可)
这样在内核中就选择支持了netfilter。接下来只需编译并生成内核映像文件并烧写到嵌入式系统即可。如果烧写后重起成功进入Linux,则说明新的支持netfiter的内核已经正常运行。(注意,这里的内核选项只是一些支持netfilter/iptables的选项。这里假设原有内核已支持嵌入式系统的相关硬件,并能在嵌入式平台上运行)。
2、编译生成iptables命令
iptables工具包可以免费从网上获得。下载iptables工具包后,进入下载目录,进行编译生成可执行文件,编译方法具体可以参考iptables目录下的INSTALL文件:
cd/root/iptables
makeKERNEL_DIR=/usr/src/linux(指定内核目录)
makeNO。SHARED_LIBS=1(静态链接编译生成可执行文件)
把生成的iptables可执行文件到ramdisk再下载到嵌入式系统中就可以运行。

Ⅱ 已经编译好的内核怎么修改vermagic

修改include/linux/vermagic.h里面的VERMAGIC_STRING值即可。(默认是把不同部分组合起来,你直接用固定字符串硬写,把-svn2067去掉)

Ⅲ Android源码解析RPC系列(一)---Binder原理

看了几天的Binder,决定有必要写一篇博客,记录一下学习成果,Binder是Android中比较综合的一块知识了,目前的理解只限于java层。首先Binder是干嘛用的?不用说,跨进程通信全靠它,操作系统的不同进程之间,数据不共享,对于每个进程来说,它都天真地以为自己独享了整个系统,完全不知道其他进程的存在,进程之间需要通信需要某种系统机制才能完成,在Android整个系统架构中,采用了大量的C/S架构的思想,所以Binder的作用就显得非常重要了,但是这种机制为什么是Binder呢?在Linux中的RPC方式有管道,消息队列,共享内存等,消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,这样就有两次拷贝过程。共享内存不需要拷贝,但控制复杂,难以使用。Binder是个折中的方案,只需要拷贝一次就行了。其次Binder的安全性比较好,好在哪里,在下还不是很清楚,基于安全性和传输的效率考虑,选择了Binder。Binder的英文意思是粘结剂,Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,这个进程一般是Server端,该对象提供了一套方法用以实现对服务的请求,而它的引用却遍布于系统的各个进程(Client端)之中,这样Client通过Binder的引用访问Server,所以说,Binder就像胶水一样,把系统各个进程粘结在一起了,废话确实有点多。

为了从而保障了系统的安全和稳定,整个系统被划分成内核空间和用户空间
内核空间:独立于普通的应用程序,可以访问受保护的内存空间,有访问底层硬件设备的所有权限。
用户空间:相对与内核空间,上层运用程序所运行的空间就是用户空间,用户空间访问内核空间的唯一方式就是系统调用。一个4G的虚拟地址空间,其中3G是用户空间,剩余的1G是内核空间。如果一个用户空间想与另外一个用户空间进行通信,就需要内核模块支持,这个运行在内核空间的,负责各个用户进程通过Binder通信的内核模块叫做Binder驱动,虽然叫做Binder驱动,但是和硬件并没有什么关系,只是实现方式和设备驱动程序是一样的,提供了一些标准文件操作。

在写AIDL的时候,一般情况下,我们有两个进程,一个作为Server端提供某种服务,然后另外一个进程作为Client端,连接Server端之后,就 可以使用Server里面定义的服务。这种思想是一种典型的C/S的思想。值得注意的是Android系统中的Binder自身也是C/S的架构,也有Server端与Client端。一个大的C/S架构中,也有一个小的C/S架构。

先笼统的说一下,在整个Binder框架中,由系列组件组成,分别是Client、Server、ServiceManager和Binder驱动程序,其中Client、Server和ServiceManager运行在用户空间,Binder驱动程序运行内核空间。运行在用户空间中的Client、Server和ServiceManager,是在三个不同进程中的,Server进程中中定义了服务提供给Client进程使用,并且Server中有一个Binder实体,但是Server中定义的服务并不能直接被Client使用,它需要向ServiceManager注册,然后Client要用服务的时候,直接向ServiceManager要,ServiceManager返回一个Binder的替身(引用)给Client,这样Client就可以调用Server中的服务了。

场景 :进程A要调用进程B里面的一个draw方法处理图片。

分析 :在这种场景下,进程A作为Client端,进程B做为Server端,但是A/B不在同一个进程中,怎么来调用B进程的draw方法呢,首先进程B作为Server端创建了Binder实体,为其取一个字符形式,可读易记的名字,并将这个Binder连同名字以数据包的形式通过Binder驱动发送给ServiceManager,也就是向ServiceManager注册的过程,告诉ServiceManager,我是进程B,拥有图像处理的功能,ServiceManager从数据包中取出名字和引用以一个注册表的形式保留了Server进程的注册信息。为什么是以数据包的形式呢,因为这是两个进程,直接传递对象是不行滴,只能是一些描述信息。现在Client端进程A联系ServiceManager,说现在我需要进程B中图像处理的功能,ServiceManager从注册表中查到了这个Binder实体,但是呢,它并不是直接把这个Binder实体直接给Client,而是给了一个Binder实体的代理,或者说是引用,Client通过Binder的引用访问Server。分析到现在,有个关键的问题需要说一下,ServiceManager是一个进程,Server是另一个进程,Server向ServiceManager注册Binder必然会涉及进程间通信。当前实现的是进程间通信却又要用到进程间通信,这就好象蛋可以孵出鸡前提却是要找只鸡来孵蛋,确实是这样的,ServiceManager中预先有了一个自己的Binder对象(实体),就是那只鸡,然后Server有个Binder对象的引用,就是那个蛋,Server需要通过这个Binder的引用来实现Binder的注册。鸡就一只,蛋有很多,ServiceManager进程的Binder对象(实体)仅有一个,其他进程所拥有的全部都是它的代理。同样一个Server端Binder实体也应该只有一个,对应所有Client端全部都是它的代理。

我们再次理解一下Binder是什么?在Binder通信模型的四个角色里面;他们的代表都是“Binder”,一个Binder对象就代表了所有,包括了Server,Client,ServiceManager,这样,对于Binder通信的使用者而言,不用关心实现的细节。对Server来说,Binder指的是Binder实体,或者说是本地对象,对于Client来说,Binder指的是Binder代理对象,也就是Binder的引用。对于Binder驱动而言,在Binder对象进行跨进程传递的时候,Binder驱动会自动完成这两种类型的转换。

简单的总结一下,通过上面一大段的分析,一个Server在使用的时候需要经历三个阶段

1、定义一个AIDL文件
Game.aidl

GameManager .aidl

2、定义远端服务Service
在远程服务中的onBind方法,实现AIDL接口的具体方法,并且返回Binder对象

3、本地创建连接对象

以上就是一个远端服务的一般套路,如果是在两个进程中,就可以进程通信了,现在我们分析一下,这个通信的流程。重点是GameManager这个编译生成的类。

从类的关系来看,首先接口GameManager 继承 IInterface ,IInterface是一个接口,在GameManager内部有一个内部类Stub,Stub继承了Binder,(Binder实现了IBinder),并且实现了GameManager接口,在Stub中还有一个内部类Proxy,Proxy也实现了GameManager接口,一个整体的结构是这样的

现在的问题是,Stub是什么?Proxy又是什么?在上面说了在Binder通信模型的四个角色里面;他们的代表都是“Binder”,一个Binder对象就代表了所有,包括了Server,Clinet,ServiceManager,为了两个进程的通信,系统给予的内核支持是Binder,在抽象一点的说,Binder是系统开辟的一块内存空间,两个进程往这块空间里面读写数据就行了,Stub从Binder中读数据,Proxy向Binder中写数据,达到进程间通信的目的。首先我们分析Stub。

Stub 类继承了Binder ,说明了Stub有了跨进程传输的能力,实现了GameManager接口,说明它有了根据游戏ID查询一个游戏的能力。我们在bind一个Service之后,在onServiceConnecttion的回调里面,就是通过asInterface方法拿到一个远程的service的。

asInterface调用queryLocalInterface。

mDescriptor,mOwner其实是Binder的成员变量,Stub继承了Binder,在构造函数的时候,对着两个变量赋的值。

如果客户端和服务端是在一个进程中,那么其实queryLocalInterface获取的就是Stub对象,如果不在一个进程queryLocalInterface查询的对象肯定为null,因为不同进程有不同虚拟机,肯定查不到mOwner对象的,所以这时候其实是返回的Proxy对象了。拿到Stub对象后,通常在onServiceConnected中,就把这个对象转换成我们多定义AIDL接口。

比如我们这里会转换成GameManager,有了GameManager对象,就可以调用后querryGameById方法了。如果是一个进程,那直接调用的是自己的querryGameById方法,如果不是一个进程,那调用了就是代理的querryGameById方法了。

看到其中关键的一行是

mRemote就是一个IBinder对象,相对于Stub,Proxy 是组合关系(HAS-A),内部有一个IBinder对象mRemote,Stub是继承关系(IS-A),直接实现了IBinder接口。

transact是个native方法,最终还会回掉JAVA层的onTransact方法。

onTransact根据调用号(每个AIDL函数都有一个编号,在跨进程的时候,不会传递函数,而是传递编号指明调用哪个函数)调用相关函数;在这个例子里面,调用了Binder本地对象的querryGameById方法;这个方法将结果返回给驱动,驱动唤醒挂起的Client进程里面的线程并将结果返回。于是一次跨进程调用就完成了。

***Please accept mybest wishes for your happiness and success ! ***

Ⅳ 怎么在Android程序里加载linux内核模块

工具/原料

Android程序里加载linux内核模块
方法/步骤

java层。 java.lang.Runtime's exec() methods:native层就是jni了。
可以用popen() 。
但指令知否支持就得看bionic了。
也可以尝试system() and pipe。
普通apk不可能有root权限,除非机器被root了,使用Runtime.exec之类的执行su -c insmod xx.kosu为root的象征,配合superuser使用 。
在终端下使用su进入root用户,然后insmod xx.ko这个肯定可以成功的,因为insmod在root用户下执行的。但是Java的Runtime.exec()也好,Native层execl()也好,只能用su -c命令临时在root用户下执行一条指令。adb shell进入终端,普通用户下执行su -c insmod xx.ko,会发现命令执行失败,失败原因就是需要注意的地方,su的-c参数只把下一个变量作为可执行的指令,因此其执行的命令是insmod而参数并没有传递过去,xx.ko作为了su的参数,因此如果想执行成功我们需要使用su -c "insmod xx.ko",将传递给insmod的参数和命令组合成一个参数。这样的话在Java层和Native层执行失败的问题也可以解决了,在Runtime.exec()中将命令格式进行格式化,比如Runtime.exec(“su -c ” + "\"insmod xx.ko\"" ),或者在Native中执行execl("/sytem/bin/su","/sytem/bin/su","-c","insmod xx.ko", NULL),这样最终传递给shell的命令就是su -c "insmod xx.ko"了。

Ⅳ 安卓编译内核生成的是o文件吗,然后再打包进boot.img

.o是中间文件,.ko是内核模块
kernel是一个可执行的bzImage,简单来讲就是由.o链接生成的目标文件,不是像你说的那样n多.o
.ko可以编译进内核,也可以不编译进内核,作为插件的形式存在
安装内核的意思就是把内核到启动分区,然后安装内核模块,以及一些其他的东西。。
每次开机直接把内核装载到内存里面去不就行了吗,这也得先安装才行不是。

Ⅵ 如何向android添加内核驱动模块

1,同目录下的makefile,如
#
# Makefile for instrial I/O Magnetometer sensors
#

obj-$(CONFIG_SENSORS_AK8975) += ak8975.o
obj-$(CONFIG_SENSORS_HMC5843) += hmc5843.o

2,同目录下的kconfig

#
# Magnetometer sensors
#
comment "Magnetometer sensors"

config SENSORS_AK8975
tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
depends on I2C
help
Say yes here to build support for Asahi Kasei AK8975 3-Axis
Magnetometer.

To compile this driver as a mole, choose M here: the mole
will be called ak8975.

3,总的config(配置变量为Y)
各项目配置文件的位置不同,
coffee:kernel/arch/arm/configs/M7023Q-debug-perf_defconfig
juice:common/customer/configs
配置信息如下:
# CONFIG_CFG80211 is not set
CONFIG_EXPERIMENTAL=y
CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
CONFIG_SWAP=y
CONFIG_ZRAM=m
CONFIG_SYSVIPC=y
CONFIG_SENSORS_AK8975=y
......

查看变量是否在编译时配置成功:
out/target/proct/m7023q/obj/KERNEL_OBJ/include/generated/Autoconf.h
查找CONFIG_SENSORS_AK8975
若在编译时有配置成功,将找到这一行:
#define CONFIG_SENSORS_AK8975 1

4、修改板级文件:
4.0及后续项目统一在:kernel/arch/arm/mach-msm/board-qrd7627a.c
注意juice中,很多配置(如tp)写在kernel/arch/arm/mach-msm/board-msm7627a-io.c
在代码中增加新模块的内容,应该有两处,第一处设置函数和结构体,第二处实际调用,注意引用上述第3步新增的编译开关将代码限制起来。
这些内容大多可以拷贝其它模块,但是名字要和driver中的相同,注意要改的地方除了名字之外,还有中断脚和I2C脚。其中固定模块的中断脚大部分时候不会改变(如tp就是int:48,reset:26),除非板子的datasheet特别注明才需要改变。但是I2C脚是会随着slaver device的改变而改变的,需要查清楚。
配置platform_data:
一般需要初始化一个xxx_platform_data结构体(这个结构体的声明应该让驱动文件可视,probe中才知道去读某个platformdata.yyy),并在i2c_board_info结构体中用.platform_data指向它,然后这个i2c_board_info将在板级文件中被注册(作为函数i2c_register_board_info()的参数)。而这个.platform_data很有可能在驱动的probe函数中调用到,例如:
static struct msg2133_ts_platform_data msg2133_platformdata= {
.irq = 0,
.reset = GPIO_TP_RESET,
};

static struct i2c_board_info i2c_info_msg2133_dpt = {
I2C_BOARD_INFO("msg2133", 0x27),
.platform_data = &msg2133_platformdata,
};
i2c_info_msg2133_dpt.platform_data->irq = gpio_to_irq(GPIO_TP_INT);//结构体初始化的时候只能以常量赋值,因为此处需要做GPIO到irq的映射,所以要在此处赋值。
i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID, &i2c_info_msg2133_dpt, 1);
在驱动的probe中:pdata =client->dev.platform_data;
...... = pdata.yyy; ......//(msg2133_ts_platform_data在该文件中可见)

热点内容
java的开发流程 发布:2025-07-05 12:45:11 浏览:669
怎么看内存卡配置 发布:2025-07-05 12:29:19 浏览:271
访问学者英文个人简历 发布:2025-07-05 12:29:17 浏览:820
1970linux 发布:2025-07-05 12:12:43 浏览:109
解压挑刺 发布:2025-07-05 12:12:12 浏览:537
rarlinux压缩 发布:2025-07-05 12:08:52 浏览:399
手机点菜app怎么连接电脑服务器 发布:2025-07-05 11:13:05 浏览:943
配置控制台干什么用的 发布:2025-07-05 10:54:51 浏览:962
连信从哪里改登录密码 发布:2025-07-05 10:54:12 浏览:399
怎么修改查询密码 发布:2025-07-05 10:49:48 浏览:967