一:Android简介

1.什么是Android

Android是一种基于linux的自由及开放源代码的操作系统,主要适用于移动设备,如智能手机和平板电脑,是由google公司和开放手机联盟领导和开发;

Android的系统架构和其操作系统一样,采用了分层的架构从架构图看,Android分为四个层:从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。如下图所示:

(1)应用程序层:所有安装在手机上的应用程序都是属于这一层的,就是一些应用程序(apk)

(2)应用程序框架层:这一层主要提供了构建应用时可能用到的API,Android自带的一些核心应用程序就是使用这些API完成的,开发者可以通过使用这些API构建自己的应用程序。比如有活动管理器、View系统。内容提供器、通知管理器等。

(3)系统运行库层:这这一层主要包含的是C/C++库来为Android系统提供了主要的特性支持,比如SQLite库提供了数据库的支持,同时还它提供了一些核心库,能允许开发者使用Java来编写Android应用,关键是Dalvik虚拟机,它使得我们每一个Android应用都能运行在独立的进程当中,并且拥有一个自己的Dalvik虚拟机实例,相比Java虚拟机(JVM),Dalvik是专门为移动设备定制的,它对手机内存、CPU性能有限等情况做了优化处理;

(4)Linux内核层:s3c6410板子上面跑的是Android2.2+linux-2.6.35;

Tiny4412:Android4.2.2 + linux-3.5; 这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、WiFi驱动、电源管理;

二、Android手机的移植

1、编译Android源码

  1. 在编译android原代码之前要卸载系统原有的openjdk,安装sun公司的jdk 1.5 (为了支持以后的Android上层的应用开发;)

yum remove openjdk*

yum remove gcc-java

安装jdk-1.5

rpm -ivh jdk-1.x-xxx.rpm

在此之前还需要配置yum 源(一般为163源,更新比较快)

  2、设置环境变量

vim /etc/profile
  加入:
  PATH=$PATH:/usr/local/arm/4.5.1/bin

  export JAVA_HOME=/usr/java/jdk1.5.0_22

  export
JRE_HOME=${JAVA_HOME}/jre


  exportCLASS_PATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASS_PATH


  export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin

  export
PATH=${JAVA_PATH}:$PATH

现在就可以进入android2.2源码宝包进行编译了

  cd .../android2.2

  make

在编译android的过程中可能会遇到 :

  gperf : command not found

gperf命令没有,于是乎就要安装,需要下载gperf包:

tar xf gperf *. tar.gz

./configure

make

make install

至此就静等android编译完毕(这个过程大概要4个小时左右)

  3.编译Android内核(Linux-2.6.35)

  在编译整个android结束后,就可以开始内核的编译了

  vim  Makefile

  配置相应的编译平台及编译器

ARCH        ?= arm
  CROSS_COMPILE  
?=/home/android/android1/android-2.2_froyo/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-

make

4.烧写bootloader

  1. 设置sd卡启动,烧写bootloader到sd卡

  2. 在板子上选择sd卡启动

  3. 安装minicom软件(配置Minicom -s)

  4. pc机上运行命令 minicom -s 选择第三个(配置如下图)

  5. 安装设置好tftp

yum install xinetd

yum install tftp

yum install-sever

配置tftp服务:

vim vi /etc/xinetd.d/tftp
    disable = no

重启服务:

service xinetd restart

   6.烧写bootloader到nandflash

将u-boot-nand.bin拷贝到 /var/lib/tftp目录下:

进入minicom

板子上面:tftp 52000000 u-boot-nand.bin
     nand erase clean
  
 nand write 52000000 0 3000

重启板子设置为nand falsh启动

  5.搭建Android nfs 网络文件系统到开发板

    安装nfs服务:

yum install nfs

在pc 机创建根文件系统目录

mkdir /work/android/nfsroot

配置nfs
   vim /etc/export
     
/work/android/nfsroot *(rw,no_root_squash)

重启 nfs 服务

service nfs restart

将编译生成的Android源码的一下文件拷贝到nfsroot下面

cp
root/* /work/android/nfsroot  -rf
   cp system/
/work/android/nfsroot/system -rf
   cp data/
/work/android/nfsroot/data -rf

至此android nfs文件系统构建完毕

  1. 设置arm板的启动参数

setenv
bootargs console=ttySAC0 init=/init root=/dev/nfs
nfsroot=192.168.1.10:/work/android/nfsroot ip=192.168.1.20

Saveenv

    将编译生成的内核镜像copy到/var/lib/tftp

    启动板子
        tftp 50008000 zImage
        bootm 50008000

  至此整个Android系统就可以在板子上面跑起来了

 三、Android系统简单的应用程序及驱动的编写

  1. Android触摸屏矫正(内核、Android源码)

  1. 首先我们需要在Android上面移植tslib:Tslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能,通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口;

  2. 下载 tslib, ./configure mmm 编
  3. 配置编译tslib 拷贝到nfsroot目录下 ts.conf

  4. 重新启动Android (ts_calibrate)

在android内核中运行ts_calibrate

利用ts_calibrate得到7个数值,填充到内核中的数组中,作为计算x,y的坐标的系数

矫正数据在.. nfsroot/system/etc/pointercal

至此触摸屏就可以工作了

  1. LED内核驱动的编写

接下来的工作就是在应用写一个apk程序,调用Java的动态库jar,jar在通过jni调用内核中的C库,实现led的亮、灭

  1. 编写apk,jar,jni,kernel_module

  2. 编译的一个顺序

.so
--> jni --> jar -->apk

  Android.mk

  include
$(BUILD_PACKAGE) -->
编译生成apk文件

  include
$(BUILD_JAVA_LIBRARY) -->
编译生成动态jar

  include
$(BUILD_STATIC_JAVA_LIBRARY) -->
编译生成静态jar

  include
$(BUILD_SHARED_LIBRARY) -->
编译生成动态C

 开发板

 insmod
led.ko

   chmod
777 /dev/
s3c6410_led

  代码如下:

首先了解下如何编译生成apk,jar,jni文件

 #-------------- . APK ---------------
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := TestEvent LOCAL_JAVA_LIBRARIES := cat
# in AndroidManifest.xml
# <application android:label="@string/app_name" android:icon="@drawable/icon">
# <uses-library android:name="cat" />
# <activity android:name="TestEvent" LOCAL_STATIC_JAVA_LIBRARIES := include $(BUILD_PACKAGE) #-------------- . static JAR --------
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := dog LOCAL_JAVA_LIBRARIES :=
LOCAL_STATIC_JAVA_LIBRARIES := include $(BUILD_STATIC_JAVA_LIBRARY) #-------------- . shared JAR ----------
LOCAL_PATH := $(call my-dir)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := dog LOCAL_JAVA_LIBRARIES :=
LOCAL_STATIC_JAVA_LIBRARIES :=
# in system/etc/permissions/platform.xml
# <library name="cat"
# file="/system/framework/cat.jar"/> include $(BUILD_JAVA_LIBRARY) #-------------- . static c library -------
LOCAL_PATH := $(call my-dir) LOCAL_SRC_FILES := test-jni.c
LOCAL_MODULE := libtest-jni LOCAL_SHARED_LIBRARIES := libc
LOCAL_STATIC_LIBRARIES := include $(BUILD_STATIC_LIBRARY) #-------------- . shared c library -------
LOCAL_PATH := $(call my-dir) LOCAL_SRC_FILES := test-jni.c
LOCAL_MODULE := libtest-jni
LOCAL_PRELINK_MODULE := false LOCAL_SHARED_LIBRARIES := libc
LOCAL_STATIC_LIBRARIES := include $(BUILD_SHARED_LIBRARY) #-------------- . exectutable ---------------
LOCAL_PATH := $(call my-dir) LOCAL_SRC_FILES := test.c
LOCAL_MODULE := test
LOCAL_SHARED_LIBRARIES := libc
LOCAL_STATIC_LIBRARIES := include $(BUILD_EXECUTABLE)

led的文件内容:


 apk中的内容:

  如下打开main.xml 我们可以制作apk的界面,我这个apk是实现的是两个按钮,btn_off, btn_on, 用来控制灯亮/灭 一个textview显示栏

  vim /home/DREAM/src/8nd_led/apk/res/layout/main.xml  

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="80dp"
android:id="@+id/txt"
android:textSize="30dp"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="60px"
android:layout_height="40px"
android:layout_weight=""
android:id="@+id/but_on"
/>
<Button
android:layout_width="60px"
android:layout_height="40px"
android:layout_weight=""
android:id="@+id/but_off"
/>
</LinearLayout>
</LinearLayout>

  vim /home/DREAM/src/8nd_led/apk/src/bunfly/pratice/Bunfly.java

 package bunfly.pratice;

 import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;
import android.view.View.OnClickListener;
import android.view.View;
import com.device.led; public class Bunfly extends Activity
{
TextView txt;
Button but_on, but_off;
OnClickListener listener; //监听 /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt = (TextView)findViewById(R.id.txt);
but_on =(Button)findViewById(R.id.but_on);
but_off = (Button)findViewById(R.id.but_off);
txt.setText("Please Click Button");
but_on.setText("ON");
but_off.setText("OFF"); listener = new OnClickListener() {
public void onClick(View v) {
led l;
String str;
l = new led();
if(v == but_on) {
str = l.jar_led_on(); //调用jar中的jar_led_on()
txt.setText(str);
//txt.setText(String.valueOf(ret));
}else if (v == but_off) {
str = l.jar_led_off();////调用jar中的jar_led_off()
txt.setText(str);
//txt.setText(String.valueOf(ret));
}
}
};
but_on.setOnClickListener(listener);//设置监听
but_off.setOnClickListener(listener); }
}

  JAR程序编写:

  

 package com.device;

 public class led {
native String on();
native String off(); static {
System.loadLibrary("s3c6410_led");
} public String jar_led_on() {
return on();
} public String jar_led_off() {
return off();
}
};

 JNI程序编写

 #include <jni.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <string.h> #define LED_ON (('Z' << 24) | 1)
#define LED_OFF (('Z' << 24) | 2) jstring Java_com_device_led_on(JNIEnv *env,
jobject thiz)
{
int fd = open("/dev/s3c6410_led", O_RDWR); //打开led设备文件
if(fd < ) {
return (*env)->NewStringUTF(env, "open failed");
}
ioctl(fd, LED_ON); //控制led
close(fd);
return (*env)->NewStringUTF(env, "led on"); //返回给jar
} jstring Java_com_device_led_off(JNIEnv *env,
jobject thiz)
{
int fd = open("/dev/s3c6410_led", O_RDWR);
if(fd < ) {
return (*env)->NewStringUTF(env, "open failed");
}
ioctl(fd, LED_OFF);
close(fd);
return (*env)->NewStringUTF(env, "led off");
}

 内核模块驱动编写

 #include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/cdev.h> MODULE_LICENSE("GPL");
MODULE_AUTHOR("bunfly"); struct led_class {
char *name;
unsigned long phys;
unsigned long gpio_virt;
unsigned *gpmcon, *gpmdat;
void (*led_on)(struct led_class *);
void (*led_off)(struct led_class *);
}; int led_probe(struct platform_device *led_dev);
int led_remove(struct platform_device *led_dev);
int led_ioctl(struct inode *no, struct file *fp, unsigned int cmd, unsigned long arg);
int led_open(struct inode *no, struct file *fp);
int led_release(struct inode *no, struct file *fp);
void led_dev_release(struct device *dev); //led_on
void s3c6410_led_on(struct led_class *l)
{
*(l->gpmcon) &= ~0xffff;
*(l->gpmcon) |= 0x1;
*(l->gpmdat) = 0x0;
} //led_off
void s3c6410_led_off(struct led_class *l)
{
*(l->gpmcon) &= ~0xffff;
*(l->gpmcon) |= 0x1;
*(l->gpmdat) = 0x1; } void init_led_class(struct led_class *l)
{
l->name = "s3c6410_led"; //设备文件名
l->phys = 0x7f008000;
l->gpio_virt = ioremap(l->phys, SZ_4K); //将物理地址映射为虚拟地址,以4k对齐
l->gpmcon = l->gpio_virt + 0x820;
l->gpmdat = l->gpio_virt + 0x824;
l->led_on = s3c6410_led_on;
l->led_off = s3c6410_led_off;
} struct led_class s3c6410_led;
int led_open(struct inode *no, struct file *fp)
{
return ;
} int led_release(struct inode *no, struct file *fp)
{
return ;
} int led_ioctl(struct inode *no, struct file *fp, unsigned int cmd, unsigned long arg)
{
int ret = ;
#define LED_ON (('Z' << 24) | 1)
#define LED_OFF (('Z' << 24) | 2) switch(cmd) {
case LED_ON:
s3c6410_led.led_on(&s3c6410_led);
break;
case LED_OFF:
s3c6410_led.led_off(&s3c6410_led);
break;
} return ret;
} void destroy_led_class(struct led_class *l)
{
iounmap(l->gpio_virt); //取消映射
} /*初始化file_operations*/
struct file_operations led_ops = {
.open = led_open,
.ioctl = led_ioctl,
.release = led_release,
}; /*将s3c6410_led注册到misc类下*/
struct miscdevice led_misc = {
.minor = ,
.name = "s3c6410_led",
.fops = &led_ops, //关联fangfa
}; int led_probe(struct platform_device *led_dev)
{
int ret = ;
init_led_class(&s3c6410_led);
ret = misc_register(&led_misc);//注销led
if(ret < ) {
printk("misc_register device failed");
} return ret;
} int led_remove(struct platform_device *led_dev)
{
misc_deregister(&led_misc);
destroy_led_class(&s3c6410_led); return ;
} void led_dev_release(struct device *dev)
{
printk("device release\n");
} struct platform_device led_dev = { //在platform总线上注册名为led的设备
.name = "led",
.id = ,
.dev = {
.release = led_dev_release,
},
}; struct platform_driver led_drv = {//在platform总线上注册名为led的设备驱动
.driver = {
.name = "led",
},
.probe = led_probe,
.remove = led_remove,
}; int bunfly_init()
{
int ret = ;
printk("bunfly_init");
platform_device_register(&led_dev);//注册设备
platform_driver_register(&led_drv);//注册设备驱动 return ret;
} void bunfly_exit()
{
s3c6410_led.led_off(&s3c6410_led);
platform_device_unregister(&led_dev);//注销设备
platform_driver_unregister(&led_drv);//注销设备驱动
} module_init(bunfly_init);
module_exit(bunfly_exit);

  本地可执行程序测试led:

 #include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h> int main(int argc, char **argv)
{
#define LED_ON (('Z' << 24) | 1)
#define LED_OFF (('Z' << 24) | 2)
int fd;
fd = open("/dev/s3c6410_led", O_RDWR); //打开设备文件
ioctl(fd, LED_ON); //用ioctl控制灯
close(fd); //关闭文件 return ;
}
  1. Android ALSA声卡驱动的移植

    1. 下载ALSA源码包

    2. git clone git://android.git.kernel.org/platform/external/alsa-lib.git

    3. git clone git://android.git.kernel.org/platform/external/alsa-utils.git

    4. git clone git://android.git.kernel.org/platform/hardware/alsa_sound.git

  1. 用mmm单独编译

  2. alsa-libalsa-utils alsa_sound 分别拷贝到Android下的external hardware 目录下

    播放声乐没有声音

4)编辑build/target/gerneric/Board/Config.mk

  注释原来的两行,添加新的,如下:

      #HAVE_HTC_AUDIO_DRIVER := true

      #BOARD_USES_GENERIC_AUDIO := true

      BOARD_USES_ALSA_AUDIO := true

        BUILD_WITH_ALSA_UTILS := true

编译 make clean

make

重新编译Android源码:再次启动Android就可以播放音乐了;

四、Android系统烧录到nandflash

  1. 需要用静态链接编译busybox

  2. 将整个nfsroot目录拷贝到nandfalsh的第三个分区中

  busybox mount -t yasff2 /dev/mtdblock3 /mnt

  更改权限:chmod 777 /mnt * - R

  nand erase nand writenand read

  设置板子启动参数:

  Setenv bootargs console=ttySAC0 root=/dev/block/mtdblock3 init=/init

31:3

  Setenv bootcmd nand read 50008000 10000 400000\; bootm 50008000

  Setenv bootdelay 3

  Saveenv

  至此整个Android系统移植完毕:

S3C6410板子移植 Android2.2的更多相关文章

  1. s3c6410下移植sqlite3.7.8

    http://blog.chinaunix.NET/uid-30441-id-2133838.html 1.下载源代码http://www.sqlite.org/download.html 2.tar ...

  2. thttpd 在S3C6410的移植-web服务程序的应用

    1.    在VMWare 虚拟机上将arm-linux-gcc 4.3.1配置好:2.    下载thttpd软件包并解压:3.    在thttpd根目录下运行:  ./configure:4.  ...

  3. 【嵌入式开发】写入开发板Linux系统-模型S3C6410

    笔者 : 万境绝尘 转载请著名出处 最终拿到板子了, 嵌入式开发正式开启. 板子型号 : 三星 S3C6410 基于ARM11, 指令集基于arm6指令集; 为毛不是 Cortext A9的板子; 烧 ...

  4. Python的交叉编译移植至arm板

    虽然网上有那么多python的交叉编译移植教程,但是方法差异蛮大,需要根据实际开发板的型号做调整,以下是适用于海思的板子移植过程. step 1. python版本从网上下就可以: step 2. 解 ...

  5. 【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410

    作者 : 万境绝尘 转载请著名出处 终于拿到板子了, 嵌入式开发正式开启. 板子型号 : 三星 S3C6410 基于ARM11, 指令集基于arm6指令集; 为毛不是 Cortext A9的板子; 烧 ...

  6. Android 编译参数 LOCAL_MODULE_TAGS

    此参数会影响到库生成后的存放位置,影响生成位置的应该是相关平台下的变量PRODUCT_PACKAGES http://blog.csdn.net/evilcode/article/details/64 ...

  7. linux 设备树及节点引用【转】

    本文转载自:http://blog.csdn.net/KjfureOne/article/details/51972854 1.ARM Linux社区为什么要引入设备树 Linux之父Linus To ...

  8. S3C6410嵌入式应用平台构建(四)——linux-3.14.4移植到OK6410-(初步启动)

    这次,还是把基本的基于我目前最新的Linux源码进行移植到OK6410吧,同时也写下我移植过程中遇到的问题及解决方法,不过有些方法是借鉴网上的,有些是自己加的,会有一些小bug. 一.基本工作 1. ...

  9. S3C6410嵌入式应用平台构建(六)——linux-3.14.4移植到OK6410-(Yaffs2文件制作)

    本文主要讲怎用利用yaffs2工具和busybox制作yaffs2文件系统镜像.大多数都是参照网上的,目的在于记录学习,不做任何用途. 一.制作mkyaffs2image工具 进入yaffs2源码目录 ...

随机推荐

  1. RB-tree (红黑树)相关问题

    今天被问到了红黑树的规则,简述总结一下: 1.每个节点不是红色就是黑色. 2.根节点为黑色. 3.如果节点为红,其子节点必须为黑. 4.任一节点至NULL(树尾端)的任何路径,所含之黑节点数必须相同. ...

  2. STL - set和multiset

    set/multiset的简介 set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列.元素插入过程是按排序规则插入,所以不能指定插入位置. set采用红黑树变体的数据结构实现, ...

  3. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

  4. Java中如何封装自己的类,建立并使用自己的类库?

    from:http://blog.csdn.net/luoweifu/article/details/7281494 随着自己的编程经历的积累会发现往往自己在一些项目中写的类在别的项目中也会有多次用到 ...

  5. Linux文件系统及常用命令

    Linux文件系统介绍: 一 .Linux文件结构 文件结构是文件存放在磁盘等存贮设备上的组织方法.主要体现在对文件和目录的组织上.目录提供了管理文件的一个方便而有效的途径. Linux使用树状目录结 ...

  6. SharePoint 部件通过EditorPart自定义属性面板

    需求:编写一个新闻展示的WebPart,要求可以分类,类别是从WebService中获取的字符串,要求可以在属性中勾选分类,显示该分类的信息,分类可能会增加.我要做的就是动态生成属性中的新闻类别,至于 ...

  7. coco2dx添加类报错

    最近刚开始学习2dx,用的vs编辑器,现在说说我使用时碰到的一点小问题: 我使用的类添加向导,但是添加的类在win32目录下,而且编译的时候总是提示找不到 .h 文件 其实,这样添加类不是很好,可以在 ...

  8. sxoi爆炸祭

    好吧,纯粹是去玩玩的,我这么一个弱省的蒟蒻,进队纯粹是开玩笑.... Day0 去五中试机,感觉电脑手感不错,打了半个线段树的板子才发现试机要在自己的电脑上试,然后我无奈的搬东西(从26号搬到2号), ...

  9. 重定向和servlet生命周期

    重定向(1)什么是重定向服务器通知浏览器向一个新的地址发送请求.注:可以发送一个302状态码和一个Location消息头.(该消息头包含了一个地址,称之为重定向地址),浏览器收到之后,会立即向重定向地 ...

  10. javaScript(8)---对象和数组

    javaScript(8)---对象和数组 学习要点: 1.Object类型 2.Array类型 3.对象中的方法 什么是对象,其实就是一种类型,即引用类型.而对象的值就是引用类型的实例.在ECMAS ...