zoukankan      html  css  js  c++  java
  • S3C6410板子移植 Android2.2

    一:Android简介

    1.什么是Android

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

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

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

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

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

    4Linux内核层: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卡启动,烧写bootloadersd

    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.烧写bootloadernandflash

    将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上面移植tslibTslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能,通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口;

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

    4. 重新启动Android ts_calibrate

    在android内核中运行ts_calibrate

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

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

     

    至此触摸屏就可以工作了

    1. LED内核驱动的编写

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

    1. 编写apkjarjnikernel_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文件

     

     1 #-------------- 1. APK ---------------
     2 LOCAL_PATH      := $(call my-dir)
     3 LOCAL_SRC_FILES := $(call all-subdir-java-files)
     4 LOCAL_PACKAGE_NAME  := TestEvent
     5 
     6 LOCAL_JAVA_LIBRARIES    :=  cat 
     7     #   in AndroidManifest.xml
     8         #   <application android:label="@string/app_name" android:icon="@drawable/icon">
     9         # <uses-library android:name="cat" />
    10         # <activity android:name="TestEvent"
    11 
    12 LOCAL_STATIC_JAVA_LIBRARIES     :=
    13 
    14 include $(BUILD_PACKAGE)
    15 
    16 #-------------- 2. static JAR --------
    17 LOCAL_PATH      := $(call my-dir)
    18 LOCAL_SRC_FILES := $(call all-java-files-under, src)
    19 LOCAL_MODULE    := dog 
    20 
    21 LOCAL_JAVA_LIBRARIES     := 
    22 LOCAL_STATIC_JAVA_LIBRARIES :=
    23 
    24 include $(BUILD_STATIC_JAVA_LIBRARY)
    25 
    26 
    27 #-------------- 3. shared JAR ----------
    28 LOCAL_PATH      := $(call my-dir)
    29 LOCAL_SRC_FILES := $(call all-java-files-under, src)
    30 LOCAL_MODULE    := dog 
    31 
    32 LOCAL_JAVA_LIBRARIES     := 
    33 LOCAL_STATIC_JAVA_LIBRARIES :=
    34     # in system/etc/permissions/platform.xml
    35     # <library name="cat"
    36         #     file="/system/framework/cat.jar"/>
    37 
    38 include $(BUILD_JAVA_LIBRARY)
    39 
    40 #-------------- 4. static c library -------
    41 LOCAL_PATH      := $(call my-dir)
    42 
    43 LOCAL_SRC_FILES := test-jni.c
    44 LOCAL_MODULE    := libtest-jni
    45 
    46 LOCAL_SHARED_LIBRARIES  :=  libc
    47 LOCAL_STATIC_LIBRARIES  := 
    48 
    49 include $(BUILD_STATIC_LIBRARY)
    50 
    51 #-------------- 5. shared c library -------
    52 LOCAL_PATH      := $(call my-dir)
    53 
    54 LOCAL_SRC_FILES := test-jni.c
    55 LOCAL_MODULE    := libtest-jni
    56 LOCAL_PRELINK_MODULE    := false
    57 
    58 LOCAL_SHARED_LIBRARIES  :=  libc
    59 LOCAL_STATIC_LIBRARIES  := 
    60 
    61 include $(BUILD_SHARED_LIBRARY)
    62 
    63 #-------------- 6. exectutable ---------------
    64 LOCAL_PATH      := $(call my-dir)
    65 
    66 LOCAL_SRC_FILES := test.c
    67 LOCAL_MODULE    := test
    68 LOCAL_SHARED_LIBRARIES  := libc
    69 LOCAL_STATIC_LIBRARIES  := 
    70 
    71 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  

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:orientation="vertical"
     4     android:layout_width="fill_parent"
     5     android:layout_height="fill_parent"
     6     >
     7 <TextView  
     8     android:layout_width="fill_parent" 
     9     android:layout_height="80dp"
    10     android:id="@+id/txt"
    11     android:textSize="30dp"
    12     />
    13     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    14         android:orientation="horizontal"
    15         android:layout_width="fill_parent"
    16         android:layout_height="fill_parent"
    17         >
    18         <Button
    19             android:layout_width="60px"
    20             android:layout_height="40px"
    21             android:layout_weight="1"
    22             android:id="@+id/but_on"
    23         />
    24         <Button
    25             android:layout_width="60px"
    26             android:layout_height="40px"
    27             android:layout_weight="1"
    28             android:id="@+id/but_off"
    29         />
    30     </LinearLayout>
    31 </LinearLayout>

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

     1 package bunfly.pratice;
     2 
     3 import android.app.Activity;
     4 import android.os.Bundle;
     5 import android.widget.TextView;
     6 import android.widget.Button;
     7 import android.view.View.OnClickListener;
     8 import android.view.View;
     9 import com.device.led;
    10 
    11 public class Bunfly extends Activity
    12 {
    13     TextView txt;
    14     Button but_on, but_off;
    15     OnClickListener listener; //监听
    16 
    17     /** Called when the activity is first created. */
    18     @Override
    19     public void onCreate(Bundle savedInstanceState)
    20     {
    21         super.onCreate(savedInstanceState);
    22         setContentView(R.layout.main);
    23         txt = (TextView)findViewById(R.id.txt);
    24         but_on =(Button)findViewById(R.id.but_on);
    25         but_off = (Button)findViewById(R.id.but_off);
    26         txt.setText("Please Click Button");
    27         but_on.setText("ON");
    28         but_off.setText("OFF");
    29 
    30         listener = new OnClickListener() {
    31             public void onClick(View v) {
    32                 led l;
    33                 String str;
    34                 l = new led();
    35                 if(v == but_on) {
    36                     str = l.jar_led_on(); //调用jar中的jar_led_on()
    37                     txt.setText(str);
    38                     //txt.setText(String.valueOf(ret));
    39                 }else if (v == but_off) {
    40                     str = l.jar_led_off();////调用jar中的jar_led_off()
    41                     txt.setText(str);
    42                     //txt.setText(String.valueOf(ret));
    43                 }
    44             }
    45         };
    46         but_on.setOnClickListener(listener);//设置监听
    47         but_off.setOnClickListener(listener);
    48         
    49     }
    50 }

      JAR程序编写:

      

     1 package com.device;
     2 
     3 public class led {
     4     native String on();
     5     native String off(); 
     6     
     7     static {
     8         System.loadLibrary("s3c6410_led");
     9     }
    10     
    11     public String jar_led_on() {
    12         return on();
    13     }
    14 
    15     public String jar_led_off() {
    16         return off();
    17     }
    18 };

     JNI程序编写

     1 #include <jni.h>
     2 #include <fcntl.h>
     3 #include <stdio.h>
     4 #include <sys/ioctl.h>
     5 #include <string.h>
     6 
     7 #define LED_ON (('Z' << 24) | 1)
     8 #define LED_OFF (('Z' << 24) | 2)
     9 
    10 jstring Java_com_device_led_on(JNIEnv *env, 
    11                                 jobject thiz) 
    12 {
    13     int fd = open("/dev/s3c6410_led", O_RDWR); //打开led设备文件
    14     if(fd  < 0) {
    15         return (*env)->NewStringUTF(env, "open failed");
    16     }
    17     ioctl(fd, LED_ON); //控制led
    18     close(fd);    
    19     return (*env)->NewStringUTF(env, "led on"); //返回给jar 
    20 }
    21 
    22 jstring Java_com_device_led_off(JNIEnv *env, 
    23                                 jobject thiz) 
    24 {
    25     int fd = open("/dev/s3c6410_led", O_RDWR);
    26     if(fd  < 0) {
    27         return (*env)->NewStringUTF(env, "open failed");
    28     }
    29     ioctl(fd, LED_OFF);
    30     close(fd);    
    31     return (*env)->NewStringUTF(env, "led off");
    32 }


     内核模块驱动编写

      1 #include <linux/init.h>
      2 #include <linux/module.h>
      3 #include <linux/io.h>
      4 #include <linux/platform_device.h>
      5 #include <linux/device.h>
      6 #include <linux/miscdevice.h>
      7 #include <linux/fs.h>
      8 #include <linux/cdev.h>
      9 
     10 MODULE_LICENSE("GPL");
     11 MODULE_AUTHOR("bunfly");
     12 
     13 struct led_class {
     14     char *name;
     15     unsigned long phys;
     16     unsigned long gpio_virt;
     17     unsigned *gpmcon, *gpmdat;
     18     void (*led_on)(struct led_class *);
     19     void (*led_off)(struct led_class *);
     20 };
     21 
     22 int led_probe(struct platform_device *led_dev);
     23 int led_remove(struct platform_device *led_dev);
     24 int led_ioctl(struct inode *no, struct file *fp, unsigned int cmd, unsigned long arg);
     25 int led_open(struct inode *no, struct file *fp);
     26 int led_release(struct inode *no, struct file *fp);
     27 void led_dev_release(struct device *dev);
     28 
     29 //led_on
     30 void s3c6410_led_on(struct led_class *l)
     31 {
     32      *(l->gpmcon) &= ~0xffff;
     33       *(l->gpmcon) |= 0x1;
     34       *(l->gpmdat) = 0x0;    
     35 }
     36 
     37 //led_off
     38 void s3c6410_led_off(struct led_class *l)
     39 {
     40      *(l->gpmcon) &= ~0xffff;
     41       *(l->gpmcon) |= 0x1;
     42       *(l->gpmdat) = 0x1;    
     43     
     44 }
     45 
     46 
     47 void init_led_class(struct led_class *l) 
     48 {
     49     l->name = "s3c6410_led"; //设备文件名
     50     l->phys = 0x7f008000;
     51     l->gpio_virt = ioremap(l->phys, SZ_4K); //将物理地址映射为虚拟地址,以4k对齐
     52     l->gpmcon = l->gpio_virt + 0x820;
     53     l->gpmdat = l->gpio_virt + 0x824;
     54     l->led_on = s3c6410_led_on;
     55     l->led_off = s3c6410_led_off;
     56 }
     57 
     58 struct led_class s3c6410_led;
     59 int led_open(struct inode *no, struct file *fp)
     60 {
     61     return 0;
     62 }
     63 
     64 int led_release(struct inode *no, struct file *fp)
     65 {
     66     return 0;
     67 }
     68 
     69 int led_ioctl(struct inode *no, struct file *fp, unsigned int cmd, unsigned long arg)
     70 {
     71     int ret = 0;
     72 #define LED_ON (('Z' << 24) | 1)
     73 #define LED_OFF (('Z' << 24) | 2)
     74 
     75     switch(cmd) {
     76         case LED_ON:
     77         s3c6410_led.led_on(&s3c6410_led);
     78         break;
     79         case LED_OFF:
     80         s3c6410_led.led_off(&s3c6410_led);
     81         break;
     82     }
     83 
     84     return ret;
     85 }
     86 
     87 void destroy_led_class(struct led_class *l)
     88 {
     89     iounmap(l->gpio_virt); //取消映射
     90 }
     91 
     92 /*初始化file_operations*/
     93 struct file_operations led_ops = {
     94     .open = led_open,
     95     .ioctl = led_ioctl,
     96     .release = led_release,
     97 };
     98 
     99 /*将s3c6410_led注册到misc类下*/
    100 struct miscdevice led_misc = {
    101     .minor = 99,
    102     .name = "s3c6410_led",
    103     .fops = &led_ops, //关联fangfa
    104 };
    105 
    106 
    107 int led_probe(struct platform_device *led_dev)
    108 {
    109     int ret = 0;
    110     init_led_class(&s3c6410_led);
    111     ret = misc_register(&led_misc);//注销led
    112     if(ret < 0) {
    113         printk("misc_register device failed");
    114     }
    115 
    116     return ret;    
    117 }
    118 
    119 int led_remove(struct platform_device *led_dev)
    120 {
    121     misc_deregister(&led_misc);
    122     destroy_led_class(&s3c6410_led);
    123 
    124     return 0;
    125 }
    126 
    127 void led_dev_release(struct device *dev)
    128 {
    129     printk("device release
    ");
    130 }
    131 
    132 struct platform_device led_dev = { //在platform总线上注册名为led的设备
    133     .name = "led",
    134     .id = 0,
    135     .dev = {
    136         .release = led_dev_release,
    137     },
    138 };
    139 
    140 struct platform_driver led_drv = {//在platform总线上注册名为led的设备驱动
    141     .driver = {
    142         .name = "led",
    143     },
    144     .probe = led_probe,
    145     .remove = led_remove,
    146 };
    147 
    148 int bunfly_init()
    149 {    
    150     int ret = 0;
    151     printk("bunfly_init");
    152     platform_device_register(&led_dev);//注册设备
    153     platform_driver_register(&led_drv);//注册设备驱动
    154     
    155     return ret;
    156 }
    157 
    158 void bunfly_exit()
    159 {
    160     s3c6410_led.led_off(&s3c6410_led);
    161     platform_device_unregister(&led_dev);//注销设备
    162      platform_driver_unregister(&led_drv);//注销设备驱动
    163 }
    164 
    165 module_init(bunfly_init);
    166 module_exit(bunfly_exit);

      本地可执行程序测试led:

     1 #include <stdio.h>
     2 #include <fcntl.h>
     3 #include <sys/ioctl.h>
     4 #include <sys/types.h>
     5 
     6 int main(int argc, char **argv)
     7 {
     8 #define LED_ON  (('Z' << 24) | 1)
     9 #define LED_OFF (('Z' << 24) | 2) 
    10     int fd;
    11     fd = open("/dev/s3c6410_led", O_RDWR); //打开设备文件
    12     ioctl(fd, LED_ON); //用ioctl控制灯
    13     close(fd); //关闭文件
    14     
    15     return 0;
    16 }
    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系统移植完毕:

  • 相关阅读:
    Hadoop1.2.0开发笔记(四)
    Datalist、GridView、Repeater 的区别
    oAuth
    浏览器沙箱技术
    28个HTML5特征、窍门和技术
    在Windows 8 JavaScript Metro Application 开发
    CSS浮动属性Float详解
    Windows 8为什么会是开发人员的2012
    CSS实现截取隐藏文字
    国外可绑定域名的免费空间(精选)
  • 原文地址:https://www.cnblogs.com/wenqiang/p/4908599.html
Copyright © 2011-2022 走看看