加载中…
个人资料
Steven天天Helloworld
Steven天天Helloworld
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,931
  • 关注人气:4
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
访客
加载中…
好友
加载中…
评论
加载中…
留言
加载中…
博文
本文注释主要参考一本棒子的android书籍,《android框架揭秘》。
代码参考Michael Richarddson公布在github上的Android-HelloWorldService代码。

首先,android的service framework由三部分构成:
1.服务接口
2.服务
3.服务代理

首先,看服务接口:
先看头文件:
#ifndef IHELLOWORLDSEVICE_H
#define IHELLOWORLDSEVICE_H

#include <binder/IInterface.h>

namespace android{
enum{
    HW_HELLOWORLD = IBinder::FIRST_CALL_TRANSACTION,
};

class IHelloWorldService: public IInterface{
public:
    //服务接口宏
    DECLARE_META_INTERFACE(HelloWorldService);------------<1>
    //服务函数
    virtual status_t helloWorld(const char *str)=0;---------<2>
};//class IHelloWorldService
};//namespace android

#endif

-------------IHelloWorldService.
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
首先,我在网上并没有找到如何把android的JNI层以下的代码导入eclipse开发环境的好方法,如果谁找到,希望能告诉我。
所以,上篇博文的代码最好的办法是用vi编辑,然后把代码放到代码数的指定目录下,通过写Android.mk文件,指定依赖关系。然后用make编译。
首先是代码的具体路径:
在/frameworks/base/include路径下建立一个helloworld文件夹,把所有服务接口,服务和服务代理的头文件放到这个目录下:BnHelloWorldService.h,BpHelloWorldService.h,HelloWorldService.h,IHelloWorldService.h。
在/frameworks/base/libs路径下建立一个helloworld文件夹,把上述头文件对应的cpp文件放到这里:
BnHelloWorldService.cpp,BpHelloWorldService.cpp,HelloWorldService.cpp,IHelloWorldService.cpp。
上面的文件编译好了,会生成一个libhelloworld.so的函数库。
然后在/frameworks/base/cmds路径下建立一个helloworld文件夹,把启动程序放到这里:
helloworldservice.cpp,helloworldclient.cpp
上面的代码编译后会生成一个两个可执行文件,helloworldservice和helloworldclient。

下面要编写Android.mk
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 

Binder Driver的工作主要可以分为3类,服务注册,服务查询,服务使用。

Binder Driver的工作流程大致分为6步:

1.接收端开放监听,等待接收IPC数据

2.发送端发送IPC数据

3.发送端等待接收端的应答数据而阻塞

4.接收端接收IPC数据并传递至用户空间

5.接收端发送应答数据

6.原发送端接收应答数据并传送至用户空间

 

首先,关注服务注册阶段:

首先,服务注册阶段binder driver要在内核空间生成binder_node节点,并把节点的ref注册到Context Manager中,把node注册到服务提供者的proc中。

1.阶段:

Context Manage调用binder_open()打开binder设备,创建binder_proc结构体,然后调用binder_mmap函数,使用内存映射开辟缓存区。

生成binder_write_read结构体,这里面保存着读写数据数据的相关信息。

调用ioctl(),生成工作线程thread,把binder_write_read拷贝到内核空间,通过分析binder_write_read中wrire和read的缓冲区大小,来决定执行读操作还是写操作。执行binder_thread_read(),进入阻塞状态。

2.阶段:

同样,先执行binder_open(),和binde

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

it

分类: Android驱动学习笔记

Binder Driver内的各种数据结构繁复,这几天连蒙带猜,终于有了一点感觉,写个blog记录一下,很可能哪里说得不对,希望指正。

首先,对Binder数据结构的讨论,就从所谓的“Binder Driver的根结构”---binder_proc结构体开始讨论。

binder_proc结构体是在进程打开binder driver的时候创建的,也就是调用binder_open()的时候,反过来讲就是所有打开binder_proc的进程,在Binder Driver中都有一个binder_proc的数据镜像,这个数据镜像保存着进程与binder_driver交互的各种信息。所有的binder_proc结构体在内核中的组织方法是双向链表。

binder_proc中的数据主要分成几部分:

1.提供服务和使用服务的相关信息

2.用户和内核间内存映射的相关信息

3.等待队列

4.工作队列

5.工作线程相关信息

6.Binder状态和优先级

首先头两个,1和2项的信息比较麻烦,放到后面介绍,先说说比较简单的等待队列、工作队列、工作线程相关信息。

等待队列:

Binder是一个IPC工具,因此,客户端和服务端在发送和接受数据的时候肯定会阻塞情况,比如服务

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

和我亲热不到一个月的小黑Thinkpad T420,在实验室不翼而飞,真的心痛如绞。

不过东西丢了就是丢了,真心的没办法,毕竟我不是终南山,调不动全上海的警力帮我找笔

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
(2012-07-23 17:06)
标签:

it

android

分类: Android驱动学习笔记

前面概述了一下binder到底是什么东西,能为我们解决什么问题,本博把讨论的焦点集中在binder的数据封装上。

数据在用户空间和内核空间的传递



Binder driver是字符设备驱动程序,通过调用open()和ioctl()函数访问。如上图,反应的是系统调用和文件运算函数之间的连接关系。例如open()系统调用顺序是:open()->__open()->binder_open()。

在应用程序通过binder尝试RPC操作时,会进行open()系统调用,获取bender driver的文件描述符。而后,通过mmap()在内核中开辟一块与用户空间相映射的内存空间,以便存放IPC数据。最后通过调用ioctl()函数,将IPC数据作为参数,传递binder driver。然后binder driver的ioctl()的格式如下:

ioctl(文件描述符,ioctl命令,数据)

ioctl()

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
(2012-07-23 14:24)
标签:

it

分类: Android驱动学习笔记

牢骚先行:

最近在看android的binder,因为android源代码大量使用设计模式,看的云里雾里,不知所云,于是翻了很多相关的介绍binder的书籍和文章,最主要是三本书:参考文献1:邓凡平的《深入理解android》,参考文献2:杨丰盛的《android技术内幕:系统卷》,参考文献3:金泰延的《android框架揭秘》(没错,看名字就猜到是棒子的书)。

邓凡平的书告诉我:看源代码要敢猜敢蒙,要有想象力,看个变量名就要猜它的意思,而且,读代码,真心是要有点毅力的。杨丰盛的书告诉我:系统用多了,自然就通了,从开发者和用户哲学来讨论,才能真正猜出开发系统者的设计思路和代码框架。最后,棒子的书告诉我:任你再牛,光靠代码和文字想讲清楚问题,太难太难,配几个图,什么艰深问题都迎刃而解。

牢骚发完

 

正文开始:

什么是binder

Binder是android

阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

分类: Android驱动学习笔记
若要在android上做系统开发,比如做驱动,改内核等等的工作,会在emulator上运行自己编译的内核是十分必要的。

准备交叉工具链

首先,最终目的是在仿真器上跑自己编译的内核,第一步肯定是编译生成kernel镜像。
因为仿真器模拟的是goldfish结构的核,那么交叉编译环境就要采用goldfish的交叉编译工具链(toolchain)。

那么,第一步就是要获得交叉编译工具链。
交叉编译工具链可以在官网上下载获得。
$ cd ANDROID_KERNEL_DIR       ----------(ANDROID_KERNEL_DIR假设是准备存放内核的目录路径。)
$ git clone https://android.googlesource.com/platform/prebuilt
这样就会在自己的这个目录下下载好交叉编译的toolchain,这个toolchain的具体的可执行文件被存在了ANDROID_KERNEL_DIR/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin路径下。
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
标签:

杂谈

分类: Android驱动学习笔记
编译linux kernel :
首先,要编译手机平台上的内核镜像,需要交叉编译工具,而一般主流的手机上的交叉编译环境都很完备了,只要把它纳入PATH目录,基本都可以make成功。
假设交叉编译环境工具路径:~/ANDROID_CROSS_TOOL/

把交叉编译环境的bin目录加入/etc/profile
PATH=~/ANDROID_CROSS_TOOL/bin:PATH
使得开机时自动运行。

把交叉编译环境加入PATH环境变量以后,就可以make。

make成功以后,在kernel/kernel/arch/arm/boot/目录下会生成一个zImage的镜像文件,这个就是编译内核生成的内核镜像。
然后,通过./out/host/linux-x86/bin/目录下的mkbootimg命令制作boot镜像:
$./out/host/linux-x86/bin/mkbootimg --kernel kernel/arch/arm/boot/zImage --ramdisk out/target/product/kt501/ramdisk.img --output out/target/product/kt501/boot.img
可见在这里,通过mkbooting命令把kernel和ramdisk打包成了一个boot镜像。
有了boot.img镜像,就可以在手机中烧录编译好的内核了。
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
(2012-07-09 15:41)
标签:

杂谈

分类: Android驱动学习笔记
今天在一台实际到HTC手机上烧录了自己编译的系统。怕以后遗忘,做了笔记备份。

首先,下载代码svn工具:
svn是早期的代码管理工具,可以说比git的历史还要早,所以完成的功能和github上到git是一样的。
sudo apt-get install subversion
sudo apt-get install subversion-tools db4.7-util patch

然后,类似于git,下载代码,同步代码(co-同步命令):
svn co svn://svnserver/Android2.3

搭建环境:
sudo apt-get install sun-java6-jdk
 
sudo apt-get install flex
sudo apt-get install bison
sudo apt-get install gperf
sudo apt-get install libsdl-dev
sudo apt-get install libesd0-dev
sudo apt-get install libwxgtk2.6-dev
sudo apt-get install build-essential
sudo apt-get install zip
sudo apt-get install curl
sudo apt-get install libncurses5-dev
阅读  ┆ 评论  ┆ 转载 ┆ 收藏 
  

新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

新浪公司 版权所有