2013年5月2日 星期四

Andorid HAL & system service testing / example code for TI AM335xevm JB BSP.




A. APP . "AndroInt_ext8_native"
  We start from the demo apk. This apk is very simple , create two text input , and one button. Input the number at text_1 & text_2 , the button click will adding two numbers from each text, and show result on text of Button.


The IAndroIntServie is java interface , create by .aidl file in frameworks direct.
In this interface only have one function "AndroInt_add()".

So this using ServiceManage.getServie() to get system service.
This Service will implemnet in frameworks .

Now we go through to next step " modify frameworks ".

diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java TI-Android-JB-4.1.2_AM335x_4.0.1/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/packages/apps/AndroInt_ext8_native/src/com/example/androInt_ext8_native/MainActivity.java    2013-05-02 16:58:39.860415713 +0800
@@ -0,0 +1,87 @@
+package com.example.androInt_ext8_native;
+
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IAndroIntService;
+import android.os.ServiceManager;
+import android.os.RemoteException;
+
+//import android.os.Parcel;
+
+import android.util.Log;
+import android.view.Menu;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.app.Activity;
+
+//import android.content.Context;
+
+
+public class MainActivity extends Activity implements OnClickListener
+{
+
+    private static final String TAG = "MainActivity";
+    private EditText mEditText2;
+    private EditText mEditText1;
+    private Button mButton;
+//    private AndroIntService mAndroIntService = null ;
+
+    IAndroIntService om = IAndroIntService.Stub.asInterface(ServiceManager.getService("androint"));
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        mEditText1 =(EditText) this.findViewById(R.id.editText1);
+        mEditText2 = (EditText) this.findViewById(R.id.editText2);
+        mButton = (Button) this.findViewById(R.id.button1);
+
+        mButton.setOnClickListener((android.view.View.OnClickListener) this);
+//        mAndroIntService = new AndroIntService(this);
+
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu)
+    {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+
+    @Override
+    public void onClick(View v)
+    {
+        // TODO Auto-generated method stub
+        int result = 0 ;
+        int a = Integer.parseInt(mEditText1.getText().toString());
+        int b = Integer.parseInt(mEditText2.getText().toString());
+
+        Log.i(TAG, "a:" + a + " ,b:" + b );
+        Log.i(TAG, "om:" + om);
+
+        try
+        {
+//            result = a + b ;
+            result = om.AndroInt_add(a, b);
+            Log.i(TAG, "result:" + result);
+        }
+        catch (RemoteException e)
+        {
+            // TODO Auto-generated catch block
+            Log.i(TAG, "Fail.... ");
+        }
+
+        mButton.setText(String.valueOf("A+B="+result ));
+
+    }
+
+}
+
+
+
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/packages/apps/AndroInt_ext8_native/Android.mk    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/packages/apps/AndroInt_ext8_native/Android.mk    2013-05-02 11:22:09.705661044 +0800
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := AndroInt_ext8_native
+
+include $(BUILD_PACKAGE)



B. Modify Frameworks .

    1. Add new "IAndroIngService.aidl " into Android.mk file.

diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/Android.mk    2012-12-17 15:18:22.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/Android.mk    2013-04-30 16:25:22.118205204 +0800
@@ -126,6 +126,7 @@
     core/java/android/nfc/INfcTag.aidl \
     core/java/android/os/ICancellationSignal.aidl \
     core/java/android/os/IHardwareService.aidl \
+    core/java/android/os/IAndroIntService.aidl \
     core/java/android/os/IMessenger.aidl \
     core/java/android/os/INetworkManagementService.aidl \
     core/java/android/os/IPermissionController.aidl \






   2.Caeate  "IAndroIntService.aidl " file. This interface only have one function.
      "AndroInt_add()"


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/core/java/android/os/IAndroIntService.aidl TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/core/java/android/os/IAndroIntService.aidl
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/core/java/android/os/IAndroIntService.aidl    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/core/java/android/os/IAndroIntService.aidl    2013-04-30 16:25:15.269146567 +0800
@@ -0,0 +1,32 @@
+/*
+ * IAndroIntService.aidl
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+package android.os;
+
+/** {@hide} */
+interface IAndroIntService
+{
+    // obsolete flashlight support
+    int AndroInt_add(int a, int b);
+}
+
 


3.Implement AndroIntService.java file.
   In this class , implement AndroInt_add(); function and
   addService "androint" into system service.
   In AndroInt_add() function , we call JNI function add_native().
   The add_native() will access kernel driver.



diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/AndroIntService.java TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/AndroIntService.java
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/AndroIntService.java    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/AndroIntService.java    2013-05-02 13:58:21.110380956 +0800
@@ -0,0 +1,75 @@
+/*
+ * AndroIntService.java
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+package com.android.server;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.IAndroIntService;
+import android.os.ServiceManager;
+import android.os.Message;
+import android.util.Slog;
+import android.util.Log;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class AndroIntService
+{
+
+    private static final String LOG_TAG = "AndroIntService";
+
+    private static native int init_native();
+    private static native int add_native(int a,int b);
+
+    private final Context mContext;
+
+    AndroIntService(Context context)
+    {
+        Log.i(LOG_TAG, "AndroIntService.");
+        init_native();
+        mContext = context;
+
+        Log.i(LOG_TAG, "addService.");
+        ServiceManager.addService("androint", mAndroInt_Bind);
+    }
+
+    private final IAndroIntService.Stub mAndroInt_Bind = new IAndroIntService.Stub()
+    {
+        public int AndroInt_add(int a , int b)
+        {
+            int result;
+            Log.i(LOG_TAG, "mAndroInt_Bind.AndroInt_add.");
+            result = add_native(a,b);
+            return result;
+        }
+
+    };
+
+
+
+
+
+}




4.Modif SystemService.java file .
   When system service started, lunch AndroIntService Class and then
   add service "androint" into system service.
 


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/SystemServer.java TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/SystemServer.java
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/java/com/android/server/SystemServer.java    2012-12-17 15:18:57.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/java/com/android/server/SystemServer.java    2013-05-02 12:41:16.244678767 +0800
@@ -117,6 +117,7 @@
         AccountManagerService accountManager = null;
         ContentService contentService = null;
         LightsService lights = null;
+        AndroIntService mAndroIntService = null;
         PowerManagerService power = null;
         BatteryService battery = null;
         VibratorService vibrator = null;
@@ -208,6 +209,9 @@
             Slog.i(TAG, "Lights Service");
             lights = new LightsService(context);

+            Slog.i(TAG, "Testing Service");
+            mAndroIntService = new AndroIntService(context);
+
             Slog.i(TAG, "Battery Service");
             battery = new BatteryService(context, lights);
             ServiceManager.addService("battery", battery);
@@ -657,7 +661,7 @@
             } catch (Throwable e) {
                 reportWtf("starting CertBlacklister", e);
             }
-           
+
             if (context.getResources().getBoolean(
                     com.android.internal.R.bool.config_enableDreams)) {
                 try {


5.Add jni cpp file into Android.mk file.



diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/Android.mk    2012-12-17 15:18:57.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/Android.mk    2013-04-30 16:25:20.077187730 +0800
@@ -8,6 +8,7 @@
     com_android_server_input_InputManagerService.cpp \
     com_android_server_input_InputWindowHandle.cpp \
     com_android_server_LightsService.cpp \
+    com_android_server_AndroIntService.cpp \
     com_android_server_PowerManagerService.cpp \
     com_android_server_SerialService.cpp \
     com_android_server_SystemServer.cpp \



 6.Implement com_android_server_AndroIntService.cpp file.
   There have two JNI function.

   add_native(): write data into kernle char driver. And do add in kernel driver,
   then read result from kernel char driver.

   init_native(): get HAL module device data , and open kernel char device.



diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/com_android_server_AndroIntService.cpp TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/com_android_server_AndroIntService.cpp
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/com_android_server_AndroIntService.cpp    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/com_android_server_AndroIntService.cpp    2013-05-02 15:14:32.380259488 +0800
@@ -0,0 +1,98 @@
+/*
+ * com_android_server_AndroIntService.cpp
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#define LOG_TAG "AndroIntService_JNI"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <utils/misc.h>
+#include <utils/Log.h>
+#include <hardware/hardware.h>
+#include <hardware/androint.h>
+
+#include <stdio.h>
+
+namespace android
+{
+static    hw_module_t        *module;
+static     hw_device_t        *device ;
+
+    static jint add_native(JNIEnv *env, jobject clazz,int a , int b)
+    {
+    int result;
+    struct androint_device_t *int_dev;
+
+        ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+        if ( device == NULL )
+        {
+            ALOGI("[%s]:%d:Device is null \n",__FUNCTION__,__LINE__);
+            return (jint)-1;
+        }
+        else
+        {
+            int_dev = (struct androint_device_t *)device;
+            int_dev->write_add(int_dev,a,b);
+            result = int_dev->read_add(int_dev);
+            ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+
+        }
+        return (jint)result;
+    }
+
+    static jint init_native(JNIEnv *env, jobject clazz)
+    {
+    int err;
+
+        ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+        err = hw_get_module(ANDROINT_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+        if (err == 0)
+        {
+            err = module->methods->open(module, ANDROINT_HARDWARE_MODULE_ID, &device);
+            ALOGI("get module success! \n" );
+        }
+        else
+        {
+            device = NULL;
+            ALOGI("get module fail:%d! \n",err );
+        }
+
+        return (jint)err;
+    }
+
+    static JNINativeMethod method_table[] =
+    {
+        { "add_native", "(II)I", (void*)add_native },
+        { "init_native", "()I", (void*)init_native },
+    };
+
+    int register_android_server_AndroIntService(JNIEnv *env)
+    {
+        ALOGI("[%s]:%d \n",__FUNCTION__,__LINE__);
+        return jniRegisterNativeMethods(env, "com/android/server/AndroIntService",
+                method_table, NELEM(method_table));
+    }
+
+};



  7.Modify onload.cpp file .
    when system load .so module file. the "JNI_OnLoad"  is first doing function.
    In this function , we so register Natiye Metheods .



diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/onload.cpp TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/onload.cpp
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/frameworks/base/services/jni/onload.cpp    2012-12-17 15:18:57.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/frameworks/base/services/jni/onload.cpp    2013-04-30 19:31:08.255261707 +0800
@@ -19,6 +19,8 @@
 #include "utils/Log.h"
 #include "utils/misc.h"

+#define LOG_TAG "onload"
+
 namespace android {
 int register_android_server_AlarmManagerService(JNIEnv* env);
 int register_android_server_BatteryService(JNIEnv* env);
@@ -34,6 +36,9 @@
 int register_android_server_SystemServer(JNIEnv* env);
 int register_android_server_location_GpsLocationProvider(JNIEnv* env);
 int register_android_server_connectivity_Vpn(JNIEnv* env);
+
+int register_android_server_AndroIntService(JNIEnv* env);
+
 };

 using namespace android;
@@ -64,5 +69,8 @@
     register_android_server_location_GpsLocationProvider(env);
     register_android_server_connectivity_Vpn(env);

+    ALOGI("register_android_server_AndroIntService...... ");
+    register_android_server_AndroIntService(env);
+
     return JNI_VERSION_1_4;
 }




C. Hard device side (HAL)


1. Create androint.h file.
    In this file , define driver using stauct , called "androint_device_t"
    And define HARDWARE_MODULE_ID "androint"


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/hardware/libhardware/include/hardware/androint.h TI-Android-JB-4.1.2_AM335x_4.0.1/hardware/libhardware/include/hardware/androint.h
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/hardware/libhardware/include/hardware/androint.h    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/hardware/libhardware/include/hardware/androint.h    2013-05-02 14:36:20.091463495 +0800
@@ -0,0 +1,54 @@
+/*
+ * androint.h
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef ANDROIDINT_INTERFACE_H
+#define ANDROIDINT_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <hardware/hardware.h>
+
+__BEGIN_DECLS
+
+/**
+ * The id of this module
+ */
+#define ANDROINT_HARDWARE_MODULE_ID        "androint"
+
+struct androint_device_t
+{
+    struct hw_device_t hw_dev;
+
+    int fd;
+    int (*write_add)(struct androint_device_t* dev,int a , int b );
+    int (*read_add)(struct androint_device_t* dev);
+};
+
+
+
+__END_DECLS
+
+#endif  // ANDROID_LIGHTS_INTERFACE_H
+




2. Modify am335xevm_sd.mk file .
    Add androin.$(TARGET_PRODUCE) .
    ### importent ###
         androin.$(TARGET_PRODUCE) .
         must same as HARDWARE_MODULE_ID
  
   the HAL hw_get_module() will searce /system/lib/hw/ <id.product.board>
   the id is HARDWARE_MODULE_ID.


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/am335xevm_sk.mk TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/am335xevm_sk.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/am335xevm_sk.mk    2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/am335xevm_sk.mk    2013-05-02 16:42:49.562787996 +0800
@@ -28,7 +28,8 @@
         MagicSmokeWallpapers \
         VisualizationWallpapers \
         librs_jni \
-        lights.$(TARGET_PRODUCT)
+        lights.$(TARGET_PRODUCT) \
+        androint.$(TARGET_PRODUCT)

 PRODUCT_PROPERTY_OVERRIDES := \
         net.dns1=8.8.8.8 \


3.Modify device.mk file .




diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/device.mk TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/device.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/device.mk    2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/device.mk    2013-05-02 16:42:51.695805279 +0800
@@ -112,6 +112,9 @@
     hcitool

 PRODUCT_PACKAGES += \
+    androint.am335xevm_sk
+
+PRODUCT_PACKAGES += \
     lights.am335xevm_sk

 PRODUCT_PACKAGES += \



 4.Implement add.c file.
    This file is driver access function.

    open_add(): open device file of /dev/xxxxx . and setting read_add / write_add
                        function point into androint_device_t  struct.

     write_add()/read_add() : Direct access kernel device .


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/add.c TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/add.c
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/add.c    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/add.c    2013-05-02 16:46:04.784374408 +0800
@@ -0,0 +1,161 @@
+/*
+ * add.c
+ *
+ * Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#define LOG_TAG "HAL_add"
+
+#include <cutils/log.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <hardware/androint.h>
+
+
+#define DEVFILE "/dev/androint-1"
+
+
+static pthread_once_t g_init = PTHREAD_ONCE_INIT;
+static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static void init_globals(void)
+{
+    /* init the mutex */
+    pthread_mutex_init(&g_lock, NULL);
+}
+
+static int write_add(struct androint_device_t *dev, int a , int b )
+{
+int        err;
+int     buf[2];
+
+    ALOGI("Device:%s not open !!\n", DEVFILE);
+    err = -1;
+    if (dev->fd < 0  )
+    {
+        ALOGI("Device:%s not open !!\n", DEVFILE);
+        return err ;
+    }
+    pthread_mutex_lock(&g_lock);
+
+    buf[0] = a;
+    buf[1] = b;
+
+    err = write(dev->fd,buf,sizeof(int)*2);
+
+    pthread_mutex_unlock(&g_lock);
+
+    return err ;
+
+}
+
+static int read_add(struct androint_device_t* dev)
+{
+int        err;
+int     result;
+
+    err = -1;
+    if (dev->fd < 0  )
+    {
+        ALOGI("Device:%s not open !!\n", DEVFILE);
+        return err ;
+    }
+
+    pthread_mutex_lock(&g_lock);
+
+    read(dev->fd, &result,sizeof(int));
+
+    pthread_mutex_unlock(&g_lock);
+
+    return result;
+}
+
+static int close_add(struct androint_device_t *dev)
+{
+int    err;
+    err = -1;
+    if (dev->fd > 0 )
+    {
+        ALOGI("Close %s\n", DEVFILE);
+        close(dev->fd);
+        dev->fd = -1 ;
+        err = 0;
+    }
+
+    return err;
+}
+
+static int open_add(const struct hw_module_t *module, char const *name, struct hw_device_t **device)
+{
+struct androint_device_t *dev;
+
+    pthread_once(&g_init, init_globals);
+
+    dev = malloc(sizeof(struct androint_device_t));
+    memset(dev, 0, sizeof(*dev));
+
+    dev->hw_dev.tag = HARDWARE_DEVICE_TAG;
+    dev->hw_dev.version = 0;
+    dev->hw_dev.module = (struct hw_module_t *)module;
+    dev->hw_dev.close =  (int (*)(struct hw_device_t *))close_add;
+
+    dev->fd = open(DEVFILE,O_RDWR);
+    dev->write_add = write_add;
+    dev->read_add = read_add;
+
+
+    ALOGI("Open %s\n", DEVFILE);
+
+    *device = (struct hw_device_t *)dev;
+
+    return 0;
+}
+
+static struct hw_module_methods_t add_module_methods =
+{
+    .open =  open_add,
+};
+
+struct hw_module_t HAL_MODULE_INFO_SYM =
+{
+    .tag = HARDWARE_MODULE_TAG,
+    .version_major = 1,
+    .version_minor = 0,
+    .id = ANDROINT_HARDWARE_MODULE_ID,
+    .name = "Instant testing Module",
+    .author = "Instant, Inc.",
+    .methods = &add_module_methods,
+};
+
+
+
+
+
 


  5.Create Andorid.mk file for build add.c .


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/Android.mk TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/Android.mk
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/libintadd/Android.mk    1970-01-01 08:00:00.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/libintadd/Android.mk    2013-05-02 16:58:00.966105273 +0800
@@ -0,0 +1,40 @@
+#  Android.mk
+#
+#  Copyright 2013 Jeff Hsieh <jeff@localhost.localdomain>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+#  MA 02110-1301, USA.
+#
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(TARGET_PRODUCT),am335xevm_sk)
+# HAL module implemenation, not prelinked and stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := add.c
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := androint.$(TARGET_PRODUCT)
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif
 



 6.Modify init.am335xevm.rc file . to insmod kernel driver .ko file.



diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/init.am335xevm.rc TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/init.am335xevm.rc
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/init.am335xevm.rc    2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/init.am335xevm.rc    2013-05-02 15:02:15.438483092 +0800
@@ -43,6 +43,8 @@
     insmod /system/lib/modules/cfg80211.ko
     insmod /system/lib/modules/mac80211.ko
     insmod /system/lib/modules/wl12xx.ko
+    insmod /system/lib/modules/androint_module.ko
+

 on fs
     # Backlight



 7.Modify uevnetd.am335xevm.rc file.
    Change /dev/xxxxx group and owner.


diff -Nura TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/ueventd.am335xevm.rc TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/ueventd.am335xevm.rc
--- TI-Android-JB-4.1.2_AM335x_4.0.1-orignal/device/ti/am335xevm_sk/ueventd.am335xevm.rc    2012-12-17 15:17:46.000000000 +0800
+++ TI-Android-JB-4.1.2_AM335x_4.0.1/device/ti/am335xevm_sk/ueventd.am335xevm.rc    2013-05-02 15:04:22.641516874 +0800
@@ -1 +1,2 @@
 /dev/video0         0666  root       root
+/dev/androint-1        0660  system     system


D. Kernel Dirver

I am lazy to explain it, if have some question please contact me.


1.Makefile

# ./kernel/hardware/driver_test/Makefile
#
# vi: set ts=4 :


##=======================================
## Setting Compiler FLAGS.
##=======================================

export CFLAGS           :=

export CPPFLAGS         :=

export LDFLAGS          :=

##==========================================
## Specital Make Rules.
##==========================================
KERNELDIR                 ?= $(PRJ_KERNEL_DIR)/_version
PWD                       := $(shell pwd)

ifeq ($(KERNELRELEASE),)

all:
    @if [ -L '$(KERNELDIR)' ] ;then \
        INSTALL_MOD_PATH=$(PRJ_IMG_DIR) $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD) modules modules_install ;\
    else \
        $(MKMATE) color -fred "## Unknow kernel dir '$(KERNELDIR)', Please build kernel first...." ; \
        exit 1 ; \
    fi

distclean clean:
    @rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions [mM]odule*

else

obj-m   := androint_module.o

endif






2.Driver code.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>

#include <asm/uaccess.h>
#include <asm/system.h>

#define DEV_MAJOR 48
#define DEV_NAME "androint"

struct androint_dev
{
    int             data[2];
    struct cdev     cdev;
    struct class     *sysfs_class;
    dev_t             dev_num;
};
struct androint_dev androint_device;


ssize_t androint_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
ssize_t retval;
int sum ;

    retval = 0;
    sum = androint_device.data[0] + androint_device.data[1];
    if (count != sizeof (int))
    {
        printk(KERN_INFO "Read error: buffer size not same !\n");
        goto out;
    }

    retval = copy_to_user(buf,&sum , sizeof(int));

    if ( retval)
        retval = -EFAULT;

out:
    return retval;
}

ssize_t androint_write(struct file *filp, const char *buf, size_t count,
            loff_t *f_pos)
{
ssize_t retval;

    retval = 0;

    if (count != sizeof(int) * 2 )
    {
        printk(KERN_INFO "Write error: buffer size not same !\n");
        goto out;
    }

    retval = copy_from_user(androint_device.data , buf, count);

    if ( retval)
        retval = -EFAULT;
out:
    return retval;
}

int androint_open(struct inode *inode, struct file *filp)
{
    int num = MINOR(inode->i_rdev);

    printk("androint_open -> minor : %d\n", num);

    return 0;
}

int androint_release(struct inode *inode, struct file *filp)
{
    printk("androint_release \n");
    return 0;
}

struct file_operations androint_fops =
{
    .owner  = THIS_MODULE,
    .read       = androint_read,
    .write      = androint_write,
    .open       = androint_open,
    .release    = androint_release,
};


static int __init androint_init(void)
{
int        result;

    printk(KERN_INFO "Module inti starts !\n");

    androint_device.dev_num = MKDEV(DEV_MAJOR,0);
    result = register_chrdev_region(androint_device.dev_num,1, DEV_NAME);
    if (result < 0)
    {
        printk( KERN_ALERT "androint: cannot register device region of %s\n",DEV_NAME);
        return result;
    }

    cdev_init(&androint_device.cdev, &androint_fops);
    androint_device.cdev.owner = THIS_MODULE;

    result = cdev_add(&androint_device.cdev,androint_device.dev_num,1);
    if (result)
    {
        printk(KERN_INFO "Can not add device %s \n ", DEV_NAME);
        goto fail_addcdev;
    }

//    populate sysfs entry
    androint_device.sysfs_class = class_create(THIS_MODULE, DEV_NAME);
    device_create(androint_device.sysfs_class, NULL,
                        androint_device.dev_num, NULL, DEV_NAME"-%d", 1);

    printk(KERN_INFO "Module inti done !\n");


fail_addcdev:
    unregister_chrdev_region(androint_device.dev_num,1);

    return result;


}

void androint_exit(void)
{

// remove the cdev
    cdev_del(&androint_device.cdev);

// Freeing the major number
    unregister_chrdev_region(androint_device.dev_num, 1);

    device_destroy(androint_device.sysfs_class, androint_device.dev_num);

    class_destroy(androint_device.sysfs_class);

    printk(KERN_INFO "Module release done !\n");
}


module_init(androint_init);
module_exit(androint_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Instnat");






2013年3月22日 星期五

Build TI-Android-JB-4.1.2_AM335x_4.0.1 BSP in x64 Fedora 18

經過之前的測試  , 發現非64 位元 不行 , 好吧  , Fedora 16 i686 更新成為 Fedora 18 x64 吧 !!

按照 TI 網頁的說明將  TI-Android-JB-4.1.2_AM335x_4.0.1.bin 下載  , 並且解開 .

先按照 TI 說明build 一次  , 將缺少的 package 和 有錯誤的修正 , 就可以在 AM335x_EVM_SK board 上凍做了 .

下列說明修改的部份:

A.建立一個環境設定 shell file. ( env.sh )

#!/bin/sh
#
# vi: set ts=4 :


## ======== setting PATH ========
    TOOLCHAIN_BIN="${PWD}/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin"

    PATH1=`echo ${PATH} | sed "s|[:]${TOOLCHAIN_BIN}||g" | sed "s|${TOOLCHAIN_BIN}[:]||g"`
    PATH2=`echo ${PATH1} | sed "s|[:]${PWD}/build||g" | sed "s|${PWD}/build[:]||g"`

    PATHE=${PATH2}

    export PATH=${TOOLCHAIN_BIN}:${PWD}/build:${PATHE}

## ========

export USE_CCACHE=1

export CROSS_COMPILE=arm-eabi-
export ARCH=arm
export TARGET_PRODUCT=am335xevm_sk
export OMAPES=4.x

## ===================================


B. 和之前一樣會遇到 perl 版本不合, 修改 "make-hash-tools.pl" 檔案.
    詳細請參考之前文章.

Index: make-hash-tools.pl
===================================================================
--- make-hash-tools.pl  (revision 1)
+++ make-hash-tools.pl  (working copy)

@@ -20,7 +20,8 @@
 #   Boston, MA 02110-1301, USA.

 use strict;
-use Switch;
+# use Switch;
+use feature qw(switch);
 use File::Basename;

 my $outdir = $ARGV[0];
@@ -28,9 +29,9 @@
 my $option = basename($ARGV[0],".gperf");


-switch ($option) {
+given ($option) {

-case "DocTypeStrings" {
+when ("DocTypeStrings") {

     my $docTypeStringsGenerated    = "$outdir/DocTypeStrings.cpp";
     my $docTypeStringsGperf        = $ARGV[0];
@@ -40,7 +41,7 @@

 } # case "DocTypeStrings"

-case "ColorData" {
+when ("ColorData") {

     my $colorDataGenerated         = "$outdir/ColorData.cpp";
     my $colorDataGperf             = $ARGV[0];
@@ -51,3 +52,4 @@
 } # case "ColorData"

 } # switch ($option)
+


B.在 buil sqx driver 的時候會發現有 bug , 這是 Makefile的錯誤.
   修正  ./hardware/ti/sgx/Makefile.KM.Android file.

Index: hardware/ti/sgx/Makefile.KM.Android
===================================================================
--- hardware/ti/sgx/Makefile.KM.Android (revision 1)
+++ hardware/ti/sgx/Makefile.KM.Android (working copy)
@@ -1,6 +1,6 @@
 include Rules.make

-OMAPES:=INVALIDVAL
+#OMAPES:=INVALIDVAL

 .PHONY: all_km buildkernel
 .PHONY: clean_km cleankernelmodule
@@ -11,21 +11,21 @@
 buildkernel:

 ifeq ($(OMAPES),4.x)
-       @echo "building the sgx kernel modules..."
-      
-       @export KERNELDIR=$(KERNEL_INSTALL_DIR) && \
-               export PATH=$(CSTOOL_PATH):$(PATH) && \
-               export CROSS_COMPILE=$(CSTOOL_PREFIX) && \
-               export EURASIAROOT=$(EURASIAROOT) && \
-               export ANDROID_ROOT=$(ANDROID_ROOT) && \
-               export ARCH=arm && \
-               make -C $(GFX_KERNMOD_SRCPATH)/eurasiacon/build/linux2/omap4430_android KERNELDIR=$(KERNEL_INSTALL_DIR) TARGET_PRODUCT=$(TARGET_PRODUCT) SGXCORE=530 SGXCOREREV=125 BUILD=release
-       @echo "copying the sgx kernel modules to $(GFX_REL_ES4_LIB_SRCPATH_ANDROID)"
+       @echo "######## building the sgx kernel modules.... ########"
+       export KERNELDIR=$(KERNEL_INSTALL_DIR) \
+               PATH=$(CSTOOL_PATH):$(PATH)  \
+               CROSS_COMPILE=$(CSTOOL_PREFIX) \
+               EURASIAROOT=$(EURASIAROOT)  \
+               ANDROID_ROOT=$(ANDROID_ROOT) \
+               ARCH=arm && \
+       make -C $(GFX_KERNMOD_SRCPATH)/eurasiacon/build/linux2/omap4430_android \
+                               KERNELDIR=$(KERNEL_INSTALL_DIR) TARGET_PRODUCT=$(TARGET_PRODUCT) SGXCORE=530 SGXCOREREV=125 BUILD=release
+       @echo "######## copying the sgx kernel modules to $(GFX_REL_ES4_LIB_SRCPATH_ANDROID) ########"
        @cp -rf $(GFX_KERNMOD_SRCPATH)/eurasiacon/binary2_omap4430_android_release/target/pvrsrvkm.ko $(GFX_REL_ES4_LIB_SRCPATH_ANDROID)/.
        @cp -rf $(GFX_KERNMOD_SRCPATH)/eurasiacon/binary2_omap4430_android_release/target/omaplfb.ko $(GFX_REL_ES4_LIB_SRCPATH_ANDROID)/.
+
 else ifeq ($(OMAPES),5.x)
        @echo "building the sgx kernel modules..."
-      
        @export KERNELDIR=$(KERNEL_INSTALL_DIR) && \
                export PATH=$(CSTOOL_PATH):$(PATH) && \
                export CROSS_COMPILE=$(CSTOOL_PREFIX) && \
@@ -45,8 +45,8 @@
 clean_km: cleankernelmodule cleandevmem2

 builddevmem2:
-       @echo "building devmem2..."
-       make -C $(GFX_DEVMEM2_SRCPATH) && make -C $(GFX_DEVMEM2_SRCPATH) install
+       @echo "######## building devmem2.... ########"
+       @make -C $(GFX_DEVMEM2_SRCPATH) && make -C $(GFX_DEVMEM2_SRCPATH) install

 cleandevmem2:
         make -C $(GFX_DEVMEM2_SRCPATH) clean



C. 因為這個版本沒有 git  , 不過在 Make 過程卻用 .git/HEAD 來產生版本編號.
    修正 "./hardware/ti/wlan/mac80211/compat_wl12xx/drivers/net/wireless/wl12xx/Makefile" File.


 Index: hardware/ti/wlan/mac80211/compat_wl12xx/drivers/net/wireless/wl12xx/Makefile
===================================================================
--- hardware/ti/wlan/mac80211/compat_wl12xx/drivers/net/wireless/wl12xx/Makefile        (revision 1)
+++ hardware/ti/wlan/mac80211/compat_wl12xx/drivers/net/wireless/wl12xx/Makefile        (working copy)
@@ -4,10 +4,10 @@
 define filechk_version.h
        (echo 'static const char *wl12xx_timestamp = __TIMESTAMP__;'; \
        echo 'static const char *wl12xx_git_head = \
-                       "$(shell git describe --dirty)";')
+                       "$(shell hostname)";')
 endef

-$(obj)/version.h: .git/HEAD .git/index .git/refs/tags
+$(obj)/version.h: Makefile
        @$(call filechk,version.h)

 $(obj)/main.c: $(src)/version.h



 E. Build kernel 過程中會發現少了mkimag file .
    這個 utility 是由 u-boot 產生 , 所以修改一下 ./Makefile , 讓 u-boot 在 build kernel 之前會先 build 出來, 並且會將 mkimage 複製到下 ./build/ .

 Index: Makefile
===================================================================
--- Makefile    (revision 2)
+++ Makefile    (working copy)
@@ -38,7 +38,7 @@
 endif
 endif

-kernel_build: droid
+kernel_build: u-boot_build droid
 ifeq ($(strip $(kernel_not_configured)),)
 ifeq ($(TARGET_PRODUCT), am335xevm_sk)
        $(MAKE) -C kernel ARCH=arm am335x_evm_android_defconfig
@@ -94,7 +94,7 @@
        $(MAKE) -C u-boot ARCH=arm am335x_evm_config
 endif
 ifeq ($(TARGET_PRODUCT), am335xevm_sk)
-       $(MAKE) -C u-boot ARCH=arm am335x_evm_config
+       @$(MAKE) -C u-boot ARCH=arm am335x_evm_config
 endif
 ifeq ($(TARGET_PRODUCT), am335xevm)
        $(MAKE) -C u-boot ARCH=arm am335x_evm_config
@@ -108,11 +108,21 @@
 ifeq ($(TARGET_PRODUCT), flashboard)
        $(MAKE) -C u-boot ARCH=arm flashboard_config
 endif
-       $(MAKE) -C u-boot ARCH=arm CROSS_COMPILE=arm-eabi-
+       @$(MAKE) -C u-boot ARCH=arm CROSS_COMPILE=arm-eabi-
+       @cp u-boot/tools/mkimage build/

 u-boot_clean:
-       $(MAKE) -C u-boot ARCH=arm CROSS_COMPILE=arm-eabi- distclean
+       @$(MAKE) -C u-boot ARCH=arm CROSS_COMPILE=arm-eabi- distclean
+       @cd u-boot ;\
+       rm MLO* > /dev/null 2>&1 ; \
+       rm -rf  spl/arch spl/board spl/common spl/disk spl/drivers spl/fs \
+               spl/lib spl/net spl/spl ; \
+       cd - > /dev/null
+       @if [ -e "build/mkimage" ];then \
+               rm build/mkimage ; \
+       fi

+
 # x-loader is required only for AM37x-based devices
 # TODO: Handle non-supported devices gracefully
 x-loader_build:
@@ -150,4 +160,7 @@
        (cd $(ANDROID_INSTALL_DIR)/out/target/product/$(TARGET_PRODUCT); \
        tar cvjf nfs-rootfs.tar.bz2 android_rootfs)

-rowboat_clean: $(CLEAN_RULE)
+rowboat_clean: $(CLEAN_RULE) u-boot_clean
+       @if [ -e "./.ccache"    ];then \
+               rm -rf ./.ccache ; \
+       fi



 F.在執行 make rowboat_clean 的時候會發現 sgx 又有錯誤.
    主要是認不得 Android SDK 版本 , 修正 "./hardware/ti/sgx/eurasiacon/build/linux2/common/android/platform_version.mk" Files

Index: hardware/ti/sgx/eurasiacon/build/linux2/common/android/platform_version.mk
===================================================================
--- hardware/ti/sgx/eurasiacon/build/linux2/common/android/platform_version.mk    (revision 1)
+++ hardware/ti/sgx/eurasiacon/build/linux2/common/android/platform_version.mk    (working copy)
@@ -46,7 +46,7 @@
         cat $(TARGET_ROOT)/product/$(TARGET_PRODUCT)/system/build.prop | \
             grep ^ro.build.version.release | cut -f2 -d'=' | cut -f1 -d'-'; \
     else \
-        echo 1.6; \
+        echo 4.9.9; \
     fi)



 G.在 clean 過程 wlan driver 會有 error .
    主要是某個 config file 已經被刪除  , makefile 卻要 include 這個 file .
    修正 ./hardware/ti/wlan/mac80211/compat_wl12xx/Makefile.

Index: hardware/ti/wlan/mac80211/compat_wl12xx/Makefile
===================================================================
--- hardware/ti/wlan/mac80211/compat_wl12xx/Makefile    (revision 2)
+++ hardware/ti/wlan/mac80211/compat_wl12xx/Makefile    (working copy)
@@ -43,7 +43,7 @@
 export CREL_PRE:=.compat_autoconf_
 export CREL_CHECK:=$(CREL_PRE)$(CREL)

-include $(PWD)/$(COMPAT_CONFIG)
+-include $(PWD)/$(COMPAT_CONFIG)

 all: modules




這樣就可以正確 在 Fedora 18 x64 下 build出所有東西 , 並可以在 am335xevm_sk 上執行!!








2013年2月18日 星期一

Start Build TI AM335X Android JB DevKit BSP in Fedora 16.

最近比較有空 (等PCB 回來驗證修改部份 ) , 所以在看看 TI 的 Android 吧 !!
發現 , TI release 的 Android JB for AM335x  的 BSP 了 .

一樣 在 FC16 上 build 看看吧 !! 我的 PC 還是 FC16 , 所以應該缺少的 東西不多 !
想說可以順利build 完畢 , 沒想到 .... 第一步就有問題 !!


Cross Compile 給我用 64 bit 的 ..... 我的 FC16 是 32bit 啦 !!!!
不想使用 VM machine (build 太慢) , 並且有舊的 project toolchain (32Bit ) .
好吧 , 試試看是否能 在 32 bit build .

PS. 這篇文章會陸續增加 修正的項目 .


A.先改 ./prebuilts/tools/gcc-sdk/gcc 吧.
  原始檔案使用 file -L "$SHELL" 的方式再次檢查是否 64 bit. 感覺有點多餘.
  每次都用同樣方式檢查不就可以了 ?? 修改後的 diff 如下:

--------------------------------- gcc-sdk/gcc ---------------------------------
index eac1c47..38f6317 100755
@@ -1,4 +1,5 @@
 #!/bin/bash
+# vi:set ts=4 :

 HOST_OS=`uname -s | tr '[:upper:]' '[:lower:]'`
 if [ "$HOST_OS" != "linux" ] ; then
@@ -14,27 +15,13 @@ PREFIX64=../../gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/bin/x86_64-linux

 options=" ${@} "   # sentinel prefix/suffix space to simplify pattern match below

-suffix_m32=${options##* -m32 }    # suffix after the last -m32
-suffix_m64=${options##* -m64 }    # suffix after the last -m64
-
-len_m32=${#suffix_m32}            # length of suffix after the last -m32
-len_m64=${#suffix_m64}            # length of suffix after the last -m64
-
-if [ $len_m32 -ge $len_m64 ] ; then
-  # Choose 64-bit if -m64 only, -m64 appears after -m32, or neither exist (-eq)
-  MY_TOOL=`dirname $0`/${PREFIX64}-${PROGNAME}
-  # Make sure host is running 64-bit OS.
-  # Note that "uname -m" only show host CPU is capable of.  Use the following technique
-  # from ndk/build/core/ndk-common.sh instead
-  file -L "$SHELL" | grep -q "x86[_-]64"
-  if [ $? != 0 ]; then
-    # $SHELL is not a 64-bit executable, so assume our userland is too.
-    echo "ERROR: $MY_TOOL only run on 64-bit linux"
-    exit 1
-  fi
+
+file -L "$SHELL" | grep -q "x86[_-]64"
+
+if [ $? != 0 ]; then
+    MY_TOOL=`dirname $0`/${PREFIX32}-${PROGNAME}
 else
-  # Otherwise, choose 32-bit
-  MY_TOOL=`dirname $0`/${PREFIX32}-${PROGNAME}
+    MY_TOOL=`dirname $0`/${PREFIX64}-${PROGNAME}
 fi

 $MY_TOOL "$@"


這一版本沒有 32bit 的 target toolchain , 所以由 ICS 的 版本內將的 toolchain
arm-linux-androideabi-4.4.x 複製到
./prebuild/linux-x86/toolchain/ 目錄下!!
原本應該在 ./prebuilds 下 , 不過擔心 ICS 的 toolchain 會有內部指定位置 , 所以放在和
ICS 一樣的 ./prebuild/ 目錄下.
本篇最後會有一個 env.sh 的 file , 內容會說明如何將 toolchain 指定到這邊 !!



B.Java VM 沒有辦法開啟 .
只細看一下 error message , 好像 jave 的 heap memory 太大 , 修正 下面這個檔案
./build/core/definitions.mk , diff 內容如下:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
make: *** [out/host/common/obj/JAVA_LIBRARIES/core-hostdex_intermediates/classes.dex] Error 1
make: *** Waiting for unfinished jobs....



index 9fe0a11..2750bed 100644
@@ -1547,7 +1547,7 @@ define transform-classes.jar-to-dex
 @echo "target Dex: $(PRIVATE_MODULE)"
 @mkdir -p $(dir $@)
 $(hide) $(DX) \
-    $(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx2048M) \
+    $(if $(findstring windows,$(HOST_OS)),,-JXms16M -JXmx1024M) \
     --dex --output=$@ \
     $(incremental_dex) \
     $(if $(NO_OPTIMIZE_DX), \



C.修正 TOOLCHAIN 的位置.
   這版本內部使用 64bit 的 complier , 雖然可以由環境參數設定 TARGET_TOOLS_PREFIX 的方式來解決 , 不過我的系統都是 32bit , 所以就用固定的方式吧 !
修改後的 diff 內容如下:

------------------------ core/combo/TARGET_linux-arm.mk ------------------------
index 4a461f8..569001a 100644
@@ -43,8 +43,10 @@ include $(TARGET_ARCH_SPECIFIC_MAKEFILE)

 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6
-TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/arm-linux-androideabi-
+## TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6
+## TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/arm-linux-androideabi-
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-eabi-4.6
+TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/arm-eabi-
 endif

 # Only define these if there's actually a gcc in there.



D.因為我的 uname -m 是 i686 , Compile 的時候會尋找 system/core/include/arch/linux-i686 和 system/core/include/arch/target_linux-i686 的內容 , 所以
就將 linux-x86 和 target_linux-x86 個別複製一份為 linux-i686 & target_linux-i686

C.修正 ./external/webkit/Source/WebCore/make-hash-tools.pl file.
    請參考前一版 ICS 的修正方式.主要是 Fedora 16  的版本比較新 , 沒有 switch 功能.


E.Make 過程如果發現 libbfd 的問題 , 就需要更改./external/oprofile/common.mk ,
   因為我們使用 i686 的 toolchain , 所以沒有 libbfd , HAVE_LIBBFD需要為 false.
   更改後的 diff 如下:


---------------------------------- common.mk ----------------------------------
index f5578b1..cc79eef 100644
@@ -45,9 +45,13 @@ HAVE_LIBBFD := true
 common_host_cflags += -DMISSING_MREMAP
 common_host_ldlibs_libiconv := -liconv
 else
+ifeq ($(shell uname -m),i686)
+HAVE_LIBBFD := false
+else
 ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
 HAVE_LIBBFD := true
 endif
 endif
+endif

 endif


D.build 到 qemu 的時候會出錯
  主要是 非 standalone 的時候會去 build 64bit 的 library , 這時候就出錯 !!
  參考一下 Makefile.common 發現設定BUILD_STANDALONE_EMULATOR 會排除
  64 bit 的 library 部份 , 先設定吧 , 到時候 qemu 要用的時候再來修正.
  diff 後的 內容如下:

---------------------------------- Android.mk ----------------------------------
index 0b02fdb..abbab01 100644
@@ -2,8 +2,11 @@
 # through the 'm' or 'mm' build commands. if not, we use the
 # standard QEMU Makefile
 #
+# vi: set ts =4 :
+
 ifeq ($(DEFAULT_GOAL),droid)
     LOCAL_PATH:= $(call my-dir)
+    BUILD_STANDALONE_EMULATOR=true
     include $(LOCAL_PATH)/Makefile.android
 else
     include Makefile.qemu



E.編譯到一半 會發現沒有 LIBBFD 
 LIBBFD 我不知道是啥東西 , 不過確定32bit 的 toolchain 沒有 , 所以修改./external/oprofile/common.mk , 這個 mk file中有指定toolchain 目錄 , 所以順便一起更改 . 只要 uname -m 是i686 就關閉 LIBBFD 和設定 32 bit 的 toolchain 位置 , diff 內容如下:

---------------------------------- common.mk ----------------------------------
index f5578b1..4b1ff6c 100644
@@ -35,7 +35,12 @@ common_target_cflags := $(common_cflags)
 HAVE_LIBBFD := false

 ifeq ($(TARGET_ARCH),arm)
+ifneq ($(shell uname -m),i686)
 toolchain := prebuilts/gcc/$(HOST_PREBUILT_TAG)/arm/arm-linux-androideabi-4.6
+else
+toolchain := prebuilts/gcc/$(HOST_PREBUILT_TAG)/toolchain/arm-linux-androideabi-4.4.x
+endif
+
 common_host_c_includes := $(common_c_includes) $(toolchain)/include
 common_host_cflags := $(common_cflags) -fexceptions -DANDROID_HOST -DHAVE_XCALLOC
 common_host_ldlibs_libiconv :=
@@ -46,8 +51,10 @@ common_host_cflags += -DMISSING_MREMAP
 common_host_ldlibs_libiconv := -liconv
 else
 ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
+ifneq ($(shell uname -m),i686)
 HAVE_LIBBFD := true
 endif
 endif
+endif

 endif


F. 編譯到 frameworks/native/libs/utils  目錄的時後會出錯
   原因是會去編譯 64 bit 的 static library.
   檢查一下 Android.mk file 發現 , default 會編譯 64 bit static library ,
   修改成不要編譯 (使用 uname -m 區別).
    Diff 的內容如下:

---------------------------- libs/utils/Android.mk ----------------------------
index ddfb83e..503126a 100644
@@ -81,6 +81,7 @@ include $(BUILD_HOST_STATIC_LIBRARY)

 # For the host, 64-bit
 # =====================================================
+ifneq ($(shell uname -m),i686)
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES:= $(commonSources)
 ifeq ($(HOST_OS), linux)
@@ -93,7 +94,7 @@ LOCAL_C_INCLUDES := \
 LOCAL_CFLAGS += $(host_commonCflags) -m64
 LOCAL_LDLIBS += $(host_commonLdlibs)
 include $(BUILD_HOST_STATIC_LIBRARY)
-
+endif

 # For the device
 # =====================================================


G.編譯到 system/core/libcutils 和 system/core/liblog 的時候會有相同錯誤
   一樣發現要 編譯 64 bit 的 static lib , 分別修正 Android.mk (使用 uname -m) .
   diff  內容分別如下:

----------------------------- libcutils/Android.mk -----------------------------
index 5c227b6..22b86bf 100644
@@ -97,6 +97,7 @@ include $(BUILD_HOST_STATIC_LIBRARY)

 # Static library for host, 64-bit
 # ========================================================
+ifneq ($(shell uname -m),i686)
 include $(CLEAR_VARS)
 LOCAL_MODULE := lib64cutils
 LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
@@ -104,7 +105,7 @@ LOCAL_LDLIBS := -lpthread
 LOCAL_STATIC_LIBRARIES := lib64log
 LOCAL_CFLAGS += $(hostSmpFlag) -m64
 include $(BUILD_HOST_STATIC_LIBRARY)
-
+endif

 # Shared and static library for target
 # ========================================================

------------------------------ liblog/Android.mk ------------------------------
index be5cec2..7fcc6bf 100644
@@ -57,6 +57,7 @@ include $(BUILD_HOST_SHARED_LIBRARY)

 # Static library for host, 64-bit
 # ========================================================
+ifneq ($(shell uname -m),i686)
 include $(CLEAR_VARS)
 LOCAL_MODULE := lib64log
 LOCAL_SRC_FILES := $(liblog_host_sources)
@@ -64,6 +65,7 @@ LOCAL_LDLIBS := -lpthread
 LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -m64
 include $(BUILD_HOST_STATIC_LIBRARY)

+endif

 # Shared and static library for target
 # ========================================================



H.增加環境參數設定
為了容易設定環境參數 ,增加了一個 ./env.sh file 來協助整個環境的設定.
內容如下:

#!/bin/sh
# vi: set ts=4 :

## ==== Setting PATH.
JDK_BIN_DIR=${HOME}/bin/jdk1.6.0_34/bin

TOOLCHAIN_BIN_DIR=${PWD}/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin

PATH1=`echo ${PATH} | sed "s|[:]${JDK_BIN_DIR}||g"`
PATH2=`echo ${PATH1} | sed "s|${JDK_BIN_DIR}[:]||g"`

PATH3=`echo ${PATH2} | sed "s|[:]${TOOLCHAIN_BIN_DIR}||g"`
PATH4=`echo ${PATH3} | sed "s|${TOOLCHAIN_BIN_DIR}[:]||g"`

PATH_E=${PATH4}

export PATH=${TOOLCHAIN_BIN_DIR}:${JDK_BIN_DIR}:${PATH_E}

export TARGET_TOOLS_PREFIX=${PWD}/prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin/arm-linux-androideabi-
## ====

export TARGET_PRODUCT=am335xevm_sk
export OMAPES=4.x
export USE_CCACHE=1

## ==== for u-boot or kernel used.

export ARCH=arm
export CROSS_COMPILE=arm-eabi-

source ${PWD}/build/envsetup.sh

## ==================================



Some Reference Web Address:
    https://groups.google.com/forum/?fromgroups=#!topic/android-building/Rq6bS2C47S8 

    http://forum.xda-developers.com/showthread.php?p=37568464&postcount=54


目前已經可以build 完畢 , 接著要試試看有沒有問題.......

沒有想像的那樣容易  , 不能 working .
後來發現 64 bit 的系統可以跑32bit 的程式,只要安裝 所需要的 32bit library即可 !!
舊的 Project 因為 code 的關係(int 大小不, 整個 struct 也會不對 ) 不能編譯成為 64 bit !!
不過可以在 CFLAGS & LDFLAGS 額外加上 -m32 就可以編譯成為
32 bit 的程式 , 當然對應的 32bit library 也要安裝 (ex zlib-devel.i686.....等)

乖乖的轉換 64 bit system , 並且不需要修改很多東西就可以了!!

2012年9月18日 星期二

加入自己的 執行程式...

開發階段可能需要一些簡單的測試程式(執行檔) , 來進行一些小功能測試 , 所以下一個階段 , 移植一個小執行檔進入 TI BSP 吧 !!

之前我們有一個 lcd-test 的程式 , 由 console press "Enter" key , 會使用 mmap 方式填寫固定 pattern 到 fb0 內. 就先移植這個吧 !!

同樣的使用自己的 makefile 方式 .

首先開一的資料夾 ( android 的 main.mk 會自己尋找 ) , 可以有兩層 , 我的方式如下:
rowboat-android/test_apps/test/lcd-test & rowboat-android/test_apps/test/lcd-test/lcd-test-0.0.1

在 lcd-test 資料夾下放入 Android.mk file , 內容如下:
#  Android.mk
#
#  Copyright 2012 Jeff Hsieh <jeff@instant-jeff.instant>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#


LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

CROSS_TC_PREFIX        := $(shell basename $(TARGET_TOOLS_PREFIX))
CROSS_TC_DIR        := $(realpath $(shell dirname $(TARGET_TOOLS_PREFIX)))
export TARGET_CC    := $(CROSS_TC_DIR)/$(CROSS_TC_PREFIX)gcc


export PRODUCT_OUT    := $(PRODUCT_OUT)
PACKAGE_PATH        := $(LOCAL_PATH)

LOCAL_GLOBAL_CFLAGS        := $(subst -I ,-I $(shell pwd)/,$(subst -include ,-include $(shell pwd)/,$(TARGET_GLOBAL_CFLAGS))) \
                        $(foreach f,$(TARGET_C_INCLUDES), $(addprefix -I$(shell pwd)/,$f)) \
                        $(foreach f,$(TARGET_PROJECT_INCLUDES), $(addprefix -I$(shell pwd)/,$f)) \
                        $(foreach f,$(JNI_H_INCLUDE), $(addprefix -I$(shell pwd)/,$f))


LOCAL_GLOBAL_LDFLAGS    := -L$(shell pwd)/$(TARGET_OUT_STATIC_LIBRARIES)


##=======================================
## Setting source file.
##=======================================

#~ ifeq ($(CONFIG_),y)
export VERNUM        = 0.0.1
export TARGET_EXE    = lcd-test

#~ endif

VERSION     = lcd-test-$(VERNUM)
PACKAGE     = $(PACKAGE_PATH)/$(VERSION)

##=======================================
## Setting Compiler FLAGS.
##=======================================

export EXE_CFLAGS    = $(LOCAL_GLOBAL_CFLAGS)

export EXE_LDFLAGS    = $(LOCAL_GLOBAL_LDFLAGS)

export EXE_EXT_FILE =  $(shell pwd)/$(TARGET_CRTBEGIN_DYNAMIC_O) \
                        $(shell pwd)/$(TARGET_CRTEND_O)


##=======================================

.PHONY: distclean install_lcd_test distclean_lcd_test

droid: install_lcd_test


install_lcd_test: $(TARGET_CRTBEGIN_DYNAMIC_O) $(TARGET_CRTEND_O) $(TARGET_OUT_STATIC_LIBRARIES)/libm.so \
                $(TARGET_OUT_STATIC_LIBRARIES)/libc.so $(TARGET_OUT_STATIC_LIBRARIES)/libdl.so \
                $(TARGET_OUT_STATIC_LIBRARIES)/liblog.so
    $(MAKE) -C $(PACKAGE) -f Makefile all


distclean: distclean_lcd_test

distclean_lcd_test:
    @$(MAKE) -C $(PACKAGE) -f Makefile distclean



##################################################


主要將一些 ldflags , cflags export 到 下一層 Makefile 使用 , 其中 EXE_EXT_FILES 是因為執行檔 , 會需要這兩個 .o file , 並且很奇怪需要放在 同一個目錄下 , 我試過使用 --sysroot=<path> 的方式 , 也是不行 , 所以只好 copy 過去 make 完畢後 delete 掉.

接著在 ./lcd-test-0.0.1/ 下建立 Makefile , 這個 makefile 就是自己的方式.內容如下:

# ./test_apps/test/lcd-test/lcd-test-0.0.1/Makefile
#
# vi: set ts=4 :

##==========================================


TARGET_OUT        := $(PWD)/$(PRODUCT_OUT)/system/bin/$(TARGET_EXE)

TARGET            = $(TARGET_EXE)
CFLAGS            = $(EXE_CFLAGS)
LDFLAGS            = $(EXE_LDFLAGS)

##==========================================
## Setting target & source file.
##==========================================

CPP_SRCS        = $(wildcard *.cpp)
C_SRCS          = $(wildcard *.c)

CPP_OBJS        = $(CPP_SRCS:.cpp=.opp)
C_OBJS          = $(C_SRCS:.c=.o)

DEPEND_FILE        = .depend


##==========================================
## Make Rules.
##==========================================


.PHONY: all distclean


all: $(DEPEND_FILE) $(TARGET_OUT)

$(TARGET_OUT): $(TARGET) Makefile
    @echo "  Install $(TARGET) ==> $(PRODUCT_OUT)/system/bin/"
    @cp $(TARGET) $(PWD)/$(PRODUCT_OUT)/system/bin/


$(TARGET): $(C_OBJS) $(CPP_OBJS)
    @echo "  Building '$@' ... "
    @cp $(foreach f,$(EXE_EXT_FILE), $(shell echo $f)) ./
    @$(TARGET_CC) -o $@ $(C_OBJS) $(CPP_OBJS) $(LDFLAGS)
    @rm $(foreach f,$(EXE_EXT_FILE), $(shell echo $f | sed 's/.*\///g'))


%.opp: %.cpp
    @echo "  Compiling '$<' ..."
    @$(TARGET_CC) $(CFLAGS) -o $@ -c $<

%.o: %.c
    @echo "  Compiling '$<' ..."
    @$(TARGET_CC) $(CFLAGS) -o $@ -c $<


distclean:
    @echo " Distcleaning '$(TARGET)'  ..."
    @rm -f $(TARGET) $(C_OBJS) $(CPP_OBJS) $(DEPEND_FILE)


$(DEPEND_FILE):
    @if [ -n "$(C_SRCS)" ] || [ -n "$(CPP_SRCS)" ] ; then \
        echo "  Generating '$@' ..." ;\
        for i in  $(C_SRCS) $(CPP_SRCS) ; do  \
            j=`echo $$i | sed 's/\.c/.o/g' ` ;\
            $(TARGET_CC) $(CFLAGS) -M $$i -MT"$$j" >> $@ ;\
        done ; \
    fi


ifeq ($(DEPEND_FILE),$(wildcard $(DEPEND_FILE)))
    include $(DEPEND_FILE)
endif

##==========================================

build 完畢後 ,利用 lrz 傳到 EVB 上的 /system/bin/ 下 . 執行看看 !!
成功....... ^^ , 不過會被原本 的畫面 re-flash 掉 , 所以建議找畫面更新率最低的頁面測試 , 或是使用 stop command 讓 java machine 暫停 , 在利用 console 執行測試程式.

Android 的 fb0 位置和一般linux 不同 , 移動到 /dev/graphics/fb0 位置.








2012年9月17日 星期一

Add Busybox into TI Android BSP

開發階段 , 很多東西都在 console 下進行一些 debug 的動作 , 有些小修改  , 卻沒有 vim 可以用 , 加上有些常用的 busybox command 都沒有 , 真的有點不方便 !!

之前有  lrz/lsz 的經驗 , 這次一樣如法泡製 , 將 busybox 移植到 TI 的 BSP 中 !!
一樣借用 linaro 這個組織的東西 網址 :

http://www.linaro.org/linux-on-arm

一樣修改一下 Android.mk file (格式和 debug message 修改 ) .

include $(CLEAR_VARS)

BUSYBOX_TOOLS := \
    ar \
    arp \
    ash \
    awk \
    base64 \
    basename \
    beep \
    blkid \
    blockdev \
    bunzip2 \
    bzcat \
    cal \
    catv \
    chat \
    chattr \
    chgrp \
    chpst \
    chroot \
    chrt \
    chvt \
    cksum \
    clear \
    comm \
    cp \
    cpio \
    cttyhack \
    cut \
    dc \
    deallocvt \
    depmod \
    devmem \
    diff \
    dirname \
    dnsd \
    dos2unix \
    dpkg \
    dpkg-deb \
    du \
    dumpkmap \
    echo \
    ed \
    egrep \
    envdir \
    envuidgid \
    expand \
    fakeidentd \
    false \
    fbset \
    fbsplash \
    fdflush \
    fdformat \
    fdisk \
    fgconsole \
    fgrep \
    find \
    findfs \
    flash_lock \
    flash_unlock \
    flashcp \
    flock \
    fold \
    freeramdisk \
    ftpd \
    ftpget \
    ftpput \
    fuser \
    getopt \
    grep \
    gunzip \
    halt \
    hdparm \
    head \
    hexdump \
    httpd \
    ifdown \
    ifup \
    inotifyd \
    install \
    iostat \
    ipaddr \
    ipcalc \
    iplink \
    iproute \
    iprule \
    iptunnel \
    klogd \
    linuxrc \
    loadkmap \
    losetup \
    lpd \
    lpq \
    lpr \
    lsattr \
    lspci \
    lsusb \
    lzcat \
    lzma \
    lzop \
    lzopcat \
    makedevs \
    makemime \
    man \
    md5sum \
    mesg \
    mkfifo \
    mknod \
    mkswap \
    mktemp \
    modinfo \
    modprobe \
    more \
    mpstat \
    nbd-client \
    nc \
    nice \
    nmeter \
    nohup \
    od \
    openvt \
    patch \
    pidof \
    pipe_progress \
    pmap \
    popmaildir \
    poweroff \
    printf \
    pscan \
    pstree \
    pwd \
    pwdx \
    raidautorun \
    rdev \
    readlink \
    readprofile \
    realpath \
    reformime \
    reset \
    resize \
    rev \
    rpm \
    rpm2cpio \
    rtcwake \
    run-parts \
    runsv \
    runsvdir \
    rx \
    script \
    scriptreplay \
    sed \
    sendmail \
    seq \
    setkeycodes \
    setlogcons \
    setserial \
    setsid \
    setuidgid \
    sha1sum \
    sha256sum \
    sha512sum \
    showkey \
    smemcap \
    softlimit \
    sort \
    split \
    start-stop-daemon \
    strings \
    stty \
    sum \
    sv \
    svlogd \
    sysctl \
    tac \
    tail \
    tar \
    tcpsvd \
    tee \
    telnet \
    telnetd \
    test \
    time \
    timeout \
    tr \
    traceroute \
    true \
    ttysize \
    tunctl \
    tune2fs \
    udhcpc \
    uname \
    uncompress \
    unexpand \
    uniq \
    unix2dos \
    unlzma \
    unlzop \
    unxz \
    unzip \
    uudecode \
    uuencode \
    vi \
    volname \
    watch \
    wc \
    wget \
    which \
    whoami \
    whois \
    xargs \
    xz \
    xzcat \
    yes \
    zcat

BB_TC_DIR := $(realpath $(shell dirname $(TARGET_TOOLS_PREFIX)))
BB_TC_PREFIX := $(shell basename $(TARGET_TOOLS_PREFIX))
BB_LDFLAGS := -nostdlib -Bdynamic -Wl,-z,muldefs$(shell if test $(PLATFORM_SDK_VERSION) -lt 16; then echo -ne ',-T../../$(BUILD_SYSTEM)/armelf.x'; fi),-dynamic-linker,/system/bin/linker,-z,nocopyreloc,--no-undefined ../../$(TARGET_CRTBEGIN_DYNAMIC_O) ../../$(TARGET_CRTEND_O) -L../../$(TARGET_OUT_STATIC_LIBRARIES)
# FIXME remove -fno-strict-aliasing once all aliasing violations are fixed
BB_COMPILER_FLAGS := $(subst -I ,-I../../,$(subst -include ,-include ../../,$(TARGET_GLOBAL_CFLAGS))) -I../../bionic/libc/include -I../../bionic/libc/kernel/common -I../../bionic/libc/arch-arm/include -I../../bionic/libc/kernel/arch-arm -I../../bionic/libm/include -fno-stack-protector -Wno-error=format-security -fno-strict-aliasing
BB_LDLIBS := dl m c gcc
ifneq ($(strip $(SHOW_COMMANDS)),)
BB_VERBOSE="V=1"
endif


.PHONY: build_busybox


FILE_BUSYBOX = $(PRODUCT_OUT)/system/bin/busybox

droid: build_busybox

systemtarball: symlinks
    @echo "==================== systemtarball done ...... "

build_busybox: $(TARGET_CRTBEGIN_DYNAMIC_O) $(TARGET_CRTEND_O) $(TARGET_OUT_STATIC_LIBRARIES)/libm.so $(TARGET_OUT_STATIC_LIBRARIES)/libc.so $(TARGET_OUT_STATIC_LIBRARIES)/libdl.so
    @if [ ! -e $(FILE_BUSYBOX) ];then  \
    echo "==================== Building Busybox ...... " ; \
        cd external/busybox && \
        sed -e "s|^CONFIG_CROSS_COMPILER_PREFIX=.*|CONFIG_CROSS_COMPILER_PREFIX=\"$(BB_TC_PREFIX)\"|;s|^CONFIG_EXTRA_CFLAGS=.*|CONFIG_EXTRA_CFLAGS=\"$(BB_COMPILER_FLAGS)\"|" configs/android_defconfig >.config && \
        export PATH=$(BB_TC_DIR):$(PATH) && \
        $(MAKE) -j1 oldconfig && \
        $(MAKE) -j1 $(BB_VERBOSE) EXTRA_LDFLAGS="$(BB_LDFLAGS)" LDLIBS="$(BB_LDLIBS)" && \
        mkdir -p ../../$(PRODUCT_OUT)/system/bin && \
        cp busybox ../../$(PRODUCT_OUT)/system/bin/ ; \
        cd - ; \
        for link in $(BUSYBOX_TOOLS); do\
        ln -sf busybox $(PRODUCT_OUT)/system/bin/$$link; done ; \
    fi

symlinks: build_busybox
    @echo "==================== Create busybox tools linking ...... " ;\
    for link in $(BUSYBOX_TOOLS); do\
        ln -sf busybox $(PRODUCT_OUT)/system/bin/$$link; done
  


最後可以在 out/target/product/am335xevm/system/bin/ 下看到 busybox 和一些 command 的 link .... 大功告成 ..
 

2012年9月13日 星期四

Add JNI demo code ( java + C )

Pure Java 完成了 , 改換 JNI 方式吧 !! 將 a + b 的動作 用 C library 來完成 .
一樣使用之前 pure java 的 code , 如下列修改方式.

    private OnClickListener mAddListener = new OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            int a = Integer.parseInt(mEditText1.getText().toString());
            int b = Integer.parseInt(mEditText2.getText().toString());
-    int result = a+b;
+ int result = addJNI(a, b);

            mButton.setText(String.valueOf("A+B=" + result));
        }
    };

並且在 .java 中加入 :

    public native int addJNI(int a, int b);
    static
    {
        System.loadLibrary("androint-jni");
    }

## 注意 library 的名稱為 libandroint-jni.so , java 會自動將 lib prefix 補上去 , 所以JNI 產生的 so file , 要注意 , 也需要 lib 這個 perfix.

接著先 產生 .class file , 在由 .class file 產生 .h , 然後 .c file include 這個 .h 並且完成 function 的功能.

產生 .class 的方式可以用下列的command :

javac -d ./ -cp /${HOME}/android-sdk-linux/platforms/android-15/android.jar src/com/eps/william/androint/AndroIntActivity.java <source top>/out/target/common/R/com/eps/william/androint/R.java

接著用 javah 來產生 .h file , command 如下: 
javah -jni -classpath ../bin com.eps.william.androint.AndroIntActivity
 



經過測試 ,沒有問題 , 只是..... 一切都不自動 , 需要手動產生, 並且還要先編譯 java 程式 , 然後手動產生 .h file , 然後 修正 .c file ,  最後在 Android.mk 中加入 .so 的 make 部份 . 一點都不優...... 

經過幾天的  study , 修改了一下 Android.mk  內容 , 讓整個 make 過程中自動產生 .h 然後接著 compile .c file 產生 .so ...... , 修改後的 Android.mk 如下: 

#  Android.mk
#
#  Copyright 2012 Jeff Hsieh <jeff@instant-jeff.instant>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#


LOCAL_PATH:= $(call my-dir)

############################################
#### Jave APK
############################################

$(warning DEBUG **** BUILD_APK)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS     := optional
LOCAL_SRC_FILES     := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME     := Sample_4

include $(BUILD_PACKAGE)


############################################
#### Jni Library.
############################################

#~ $(warning DEBUG **** BUILD_JNI)
#~
#~ include $(CLEAR_VARS)
#~
#~ LOCAL_MODULE_TAGS     := optional
#~ LOCAL_SRC_FILES     := $(call all-subdir-c-files)
#~ LOCAL_MODULE        := libandroint-jni
#~
#~ LOCAL_LDLIBS         := -llog
#~
#~ LOCAL_SHARED_LIBRARIES := libcutils
#~
#~ LOCAL_CHECKED_MODULE := build_jni_h
#~ LOCAL_REQUIRED_MODULES := build_jni_h
#~
#~ include $(BUILD_SHARED_LIBRARY)


.PHONY: distclean install_jni_so build_jni_hearder

droid: install_jni_so


############################################
#### create jni h file .
############################################

$(warning DEBUG **** Create JNI heard files.)

include $(CLEAR_VARS)

JNI_LOCAL_PKG_NAME    := $(shell cat $(LOCAL_PATH)/AndroidManifest.xml | grep package | sed 's/.*=//g')
JNI_LOCAL_PKG_DIR     := $(shell echo $(JNI_LOCAL_PKG_NAME) | sed 's/\./\//g' )

JNI_LOCAL_JAVA_SRC     :=
JNI_LOCAL_JAVA_SRC     += $(foreach f,$(call all-subdir-java-files), $(addprefix $(LOCAL_PATH)/,$f))

JNI_LOCAL_PATH         := $(LOCAL_PATH)

JNI_JAVA_LIB        := /home/jeff/Mydroid/android-sdk-linux/platforms/android-15/android.jar
JNI_R_JAVA            := $(TARGET_COMMON_OUT_ROOT)/R/$(JNI_LOCAL_PKG_DIR)/R.java

build_jni_hearder: Sample_4
    @if [ ! -e $(JNI_LOCAL_PATH)/bin ];then \
        mkdir -p $(JNI_LOCAL_PATH)/bin ; \
    fi
    @if [ ! -e $(JNI_LOCAL_PATH)/bin/.jni_header ];then \
        javac -d $(JNI_LOCAL_PATH)/bin  -cp $(JNI_JAVA_LIB) $(JNI_R_JAVA) $(JNI_LOCAL_JAVA_SRC) ; \
        javah -jni -classpath $(JNI_LOCAL_PATH)/bin -d $(JNI_LOCAL_PATH)/jni/jni_include $(JNI_LOCAL_PKG_NAME).AndroIntActivity ;\
    fi


## javac -d ./ -cp /home/jeff/Mydroid/android-sdk-linux/platforms/android-15/android.jar \
##            src/com/eps/william/androint/AndroIntActivity.java \
##            /home/jeff/Mydroid/TI_Android/rowboat-android/out/target/common/R/com/eps/william/androint/R.java

## javah -jni -classpath ../bin com.eps.william.androint.AndroIntActivity


############################################
#### Jni Library.
############################################

include $(CLEAR_VARS)

export JNI_TC_DIR             := $(realpath $(shell dirname $(TARGET_TOOLS_PREFIX)))
export JNI_TC_PREFIX         := $(shell basename $(TARGET_TOOLS_PREFIX))
export TARGET_CC            := $(JNI_TC_DIR)/$(JNI_TC_PREFIX)gcc

export JNI_COMPILER_FLAGS    := $(subst -I ,-I $(shell pwd)/,$(subst -include ,-include $(shell pwd)/,$(TARGET_GLOBAL_CFLAGS))) \
                        $(foreach f,$(TARGET_C_INCLUDES), $(addprefix -I$(shell pwd)/,$f)) \
                        $(foreach f,$(TARGET_PROJECT_INCLUDES), $(addprefix -I$(shell pwd)/,$f)) \
                        $(foreach f,$(JNI_H_INCLUDE), $(addprefix -I$(shell pwd)/,$f)) \

export JNI_LDFLAGS             := -L$(shell pwd)/$(TARGET_OUT_STATIC_LIBRARIES) -llog
export JNI_LOCAL_C_FILES    := $(call all-subdir-c-files)


export PRODUCT_OUT            := $(PRODUCT_OUT)

###################################


install_jni_so: build_jni_hearder \
                $(TARGET_CRTBEGIN_DYNAMIC_O) $(TARGET_CRTEND_O) $(TARGET_OUT_STATIC_LIBRARIES)/libm.so \
                $(TARGET_OUT_STATIC_LIBRARIES)/libc.so $(TARGET_OUT_STATIC_LIBRARIES)/libdl.so \
                $(TARGET_OUT_STATIC_LIBRARIES)/liblog.so
    @$(MAKE) -C $(JNI_LOCAL_PATH) -f Makefile.jni local_jni

############################################
#### Clean rules.
############################################

distclean:
    @if [ -e $(JNI_LOCAL_PATH)/jni/jni_include ];then \
        rm -rf $(JNI_LOCAL_PATH)/jni/jni_include ; \
    fi
    @echo "Remove temp file \"$(JNI_LOCAL_PATH)/bin/ \" .... "
    @if [ -e $(JNI_LOCAL_PATH)/bin ];then \
        rm -rf $(JNI_LOCAL_PATH)/bin ;\
    fi
    @$(MAKE) -C $(JNI_LOCAL_PATH) -f Makefile.jni $@


############################################



因為 Android 的 make rules 太複雜 ,並且支援 make -jN , 所以乾脆獨立出來 build so file . 所以會看到 "@$(MAKE) -C $(JNI_LOCAL_PATH) -f Makefile.jni local_jni " 的字串 , 其中 Makefile.jni 如下:

#  Makefile.jni
#
#  Copyright 2012 Jeff Hsieh <jeff@instant-jeff.instant>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#


DEPEND_FILE                := .jni_depend
JNI_SO_NAME                := libandroint-jni.so
JNI_LOCAL_OBJ_FILES        := $(JNI_LOCAL_C_FILES:.c=.o)
JNI_SO_TARGET           := $(addprefix $(shell pwd)/,$(JNI_SO_NAME))

JNI_TARGET_OUT            := $(PWD)/$(PRODUCT_OUT)/system/lib/$(JNI_SO_NAME)


.PHONY: local_jni distclean


local_jni: $(DEPEND_FILE) $(JNI_TARGET_OUT)

$(JNI_TARGET_OUT): $(JNI_SO_TARGET)
    @echo "  Install $(JNI_SO_NAME) ==> $(PRODUCT_OUT)/system/lib"
    @cp $(JNI_SO_TARGET) $(PWD)/$(PRODUCT_OUT)/system/lib/

$(JNI_SO_TARGET):  $(JNI_LOCAL_OBJ_FILES)
    @echo "  Building '$@' ... "
    @$(TARGET_CC) -shared -Wl,-soname,$(JNI_SO_NAME) -o $@ $(JNI_LOCAL_OBJ_FILES) $(JNI_LDFLAGS)

%.o: %.c
    @echo "  Compiling '$<' ..."
    @$(TARGET_CC) $(JNI_COMPILER_FLAGS) -o $@ -c $<


$(DEPEND_FILE):
    @if [ -n "$(JNI_LOCAL_C_FILES)" ]; then \
        echo "  Generating '$@' ..." ;\
        for i in  $(JNI_LOCAL_C_FILES) ; do  \
            j=`echo $$i | sed 's/\.c/.o/g' ` ;\
            $(TARGET_CC) $(JNI_COMPILER_FLAGS) -M $$i -MT"./$$j" >> $@  ;\
        done ; \
    fi


ifeq ($(DEPEND_FILE),$(wildcard $(DEPEND_FILE)))
    include $(DEPEND_FILE)
endif


distclean:
    @rm -f $(DEPEND_FILE) $(JNI_SO_TARGET) $(JNI_LOCAL_OBJ_FILES)

############################################