add system call to linux

添加系统系统到内核,测试环境huawei u9508手机,基于内核代码huawei u9508 kernel

  1. 修改 arch/arm/kernel/calls.S

    diff —git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
    index 80f7896..100320f 100644
    —- a/arch/arm/kernel/calls.S
    +++ b/arch/arm/kernel/calls.S
    @@ -385,6 +385,7 @@

    CALL(sys_syncfs)
    CALL(sys_sendmmsg)
    

    / 375 / CALL(sys_setns)

    • CALL(sys_hello)

      ifndef syscalls_counted

      .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls

      define syscalls_counted

  2. 修改 include/linux/syscalls.h

    diff —git a/include/linux/syscalls.h b/include/linux/syscalls.h
    index 8c03b98..ca05033 100644
    —- a/include/linux/syscalls.h
    +++ b/include/linux/syscalls.h
    @@ -847,4 +847,5 @@ asmlinkage long sys_open_by_handle_at(int mountdirfd,

    struct file_handle __user *handle,
    int flags);
    

    asmlinkage long sys_setns(int fd, int nstype);
    +asmlinkage long sys_hello(void);

    endif

  3. 修改 arch/arm/include/asm/unistd.h

    diff —git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
    index 2c04ed5..fa6cc69 100644
    —- a/arch/arm/include/asm/unistd.h
    +++ b/arch/arm/include/asm/unistd.h
    @@ -402,6 +402,7 @@

    define NR_syncfs (NR_SYSCALL_BASE+373)

    define NR_sendmmsg (NR_SYSCALL_BASE+374)

    define NR_setns (NR_SYSCALL_BASE+375)

    +#define NR_sys_hello (NR_SYSCALL_BASE+376)

    /*

    • The following SWIs are ARM private.
  4. 在kernel下添加hello目录,并添加hello.c, Makefile

    hello/
    ├── hello.c
    └── Makefile

vim hello.c

#include <linux/kernel.h>
asmlinkage long sys_hello(void) 
{
    printk("hello world\n");
    return 0;
}

vim Makefile

obj-y := hello.o
  1. 修改kernel下Makefile

    diff —git a/Makefile b/Makefile
    index 9651e1c..3e54a62 100755
    —- a/Makefile
    +++ b/Makefile
    @@ -719,7 +719,7 @@ export mod_strip_cmd

 ifeq ($(KBUILD_EXTMOD),)
-core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ hello/

 vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
                     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
  1. 编译内核

    export CROSS_COMPILE=arm-linux-androideabi-
    export ARCH=arm
    make distclean
    make hisi_k3v2oem1_defconfig
    make zImage

  2. modify boot.img with our build zImage
    mkboot boot.img boot
    ….
    mkboot boot boot_new.img
    adb reboot bootloader
    fastboot flash boot boot_new.img
    fastboot reboot

  3. 测试添加的系统调用

    jni/
    ├── Android.mk
    └── sys_hello.cpp

vim sys_hello.cpp

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>

#define __NR_hello 376

long hello_syscall(void)
{
    return syscall(__NR_hello);
}

int main(int argc, char **argv)
{
    long int a = hello_syscall();
    printf("System call returned %ld\n", a);
    return 0;
}

vim Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES += sys_hello.cpp

LOCAL_MODULE := hello
include $(BUILD_EXECUTABLE)

ndk-build

StaticLibrary  : libstdc++.a
Executable     : hello
Install        : hello => libs/armeabi/hello

adb push libs/armeabi/hello /data/local/tmp/
adb shell

root@android:/data/local/tmp # ./hello                                         
System call returned 0
root@android:/data/local/tmp # dmesg                                           
<4>[5494.1, hello] [ 1911.446306] hello world

以上针对arm平台添加的系统调用,若为x86平台,则需要将1,2,3步修改为x86目录下相应的文件即可;
参考: How To Add A System Call and Recompile the Linux Kernel

compile binary fow windows on linux with mingw

with mingw we can compile 3rd party project for windows on linux.

compile openssl for example:
参考: OpenSSL for Windows

  1. setup cross compile environment.
    sudo apt-get install mingw-w64 binutils-mingw-w64

  2. download openssl source code
    git clone https://github.com/openssl/openssl.git

  3. cross compile with mingw
    cd openssl
    ./Configure —cross-compile-prefix=i686-w64-mingw32- mingw64 no-asm shared —prefix=xxx
    make
    make install

    ├── bin
    │ ├── c_rehash
    │ ├── libeay32.dll
    │ ├── openssl.exe
    │ └── ssleay32.dll
    ├── include
    │ └── openssl
    ├── lib
    │ ├── engines
    │ ├── libcrypto.a
    │ ├── libcrypto.dll.a
    │ ├── libssl.a
    │ ├── libssl.dll.a
    │ └── pkgconfig
    └── ssl

    ├── certs
    ├── man
    ├── misc
    ├── openssl.cnf
    └── private
    

add libusb-win32 to vc project

windows下面使用libusb开源库

下载已经编译好的libusb libusb-win32-bin-1.2.6.0

目录结构:

libusb-win32-bin-1.2.6.0
├── AUTHORS.txt
├── bin
│   ├── amd64
│   ├── ia64
│   ├── inf-wizard.exe
│   ├── libusb-win32-bin-README.txt
│   └── x86
├── COPYING_GPL.txt
├── COPYING_LGPL.txt
├── examples
│   ├── benchmark.c
│   ├── BenchmarkHelp.txt
│   ├── benchmark_rc.rc
│   ├── bulk.c
│   ├── driver_installer_template.iss
│   └── testbulk_rc.rc
├── include
│   └── lusb0_usb.h
├── installer_license.txt
├── lib
│   ├── bcc
│   ├── dynamic
│   ├── gcc
│   ├── msvc
│   ├── msvc_i64
│   └── msvc_x64
├── libusb-win32-changelog-1.2.6.0.txt
└── README.txt

根据下面的步骤将库添加到vc工程中
参考: stackoverflow

Typically you need to do 5 things to include a library in your project:

1) Add #include statements necessary files with declarations/interfaces, e.g.:

#include "library.h"
2) Add an include directory for the compiler to look into

-> Configuration Properties/VC++ Directories/Include Directories (click and edit, add a new entry)

3) Add a library directory for *.lib files:

-> Configuration Properties/VC++ Directories/Library Directories (click and edit, add a new entry)

4) Link the lib's *.lib files

-> Configuration Properties/Linker/Input/Additional Dependencies (e.g.: library.lib;

5) Place *.dll files either:

-> in the directory you'll be opening your final executable from or into Windows/system32

编写测试代码:
参考 examples/bulk.c

#include "stdafx.h"
#include "lusb0_usb.h"

#define MY_VID 0x0421
#define MY_PID 0x03C5

////////////////////////////////////////////////////
usb_dev_handle *open_dev(void)
{
    struct usb_bus *bus;
    struct usb_device *dev;

    for (bus = usb_get_busses(); bus; bus = bus->next)
    {
        for (dev = bus->devices; dev; dev = dev->next)
        {
            if (dev->descriptor.idVendor == MY_VID
                && dev->descriptor.idProduct == MY_PID)
            {
                return usb_open(dev);
            }
        }
    }
    return NULL;
}

int _tmain(int argc, _TCHAR* argv[])
{
        usb_dev_handle *dev = NULL; 
        usb_init(); 
        usb_find_busses(); 
        usb_find_devices(); 

        if (!(dev = open_dev()))
        {
            printf("error opening device: \n%s\n", usb_strerror());
            return 0;
        }
        else
        {
            printf("success: device %04X:%04X opened\n", MY_VID, MY_PID);
        }
    return 0;
}

huawei k3v2oem1 kernel compile

compile huawei k3v2oem1 kernel

get source code :

android_kernel_huawei_k3v2oem1

pre-compile

which device can use it ?
README_Version.txt

Kernel release package version instruction

USE zImage NOTE:

1¡¢This package make out zImage only, you have to get ramdisk and add kernel cmdline to generate a total boot.img before replace your phone's bootimage.
2¡¢If your phone already enable secboot feature, please decrypt or unlock the secboot feature first.
3¡¢Please make sure your phone software version is same with this release package, if not, please download the match version first.

This kernel package is released for the phone software version U9508 V100R001CHNC00B550

how to compile it?
README_Kernel.txt

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

1. How to Build
    - get Toolchain
        From android git server , codesourcery and etc ..
         - arm-linux-androideabi-4.6

    - edit Makefile
        edit "CROSS_COMPILE" to right toolchain path(You downloaded).
          EX)   CROSS_COMPILE= $(android platform directory you download)/android/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-
          Ex)   CROSS_COMPILE=/usr/local/toolchain/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-          // check the location of toolchain
          or
          Ex)Exexport CROSS_COMPILE=arm-linux-androideabi-
          Ex)Exexport PATH=$PATH:<toolchain_parent_dir>/arm-linux-androideabi-4.6/bin

        $ make ARCH=arm hisi_k3v2oem1_defconfig
        $ make ARCH=arm zImage

2. Output files
    - Kernel : arch/arm/boot/zImage
    - module : drivers/*/*.ko

3. How to Clean
        $ make ARCH=arm distclean
################################################################################

compile

error fix:

<1> perl parse excel fail.
arch/arm/mach-k3v2/ipps_para_gen.pl line 3 error

make sure your have perl installed with perl -v
install perl excel parse library
sudo cpan
    install OLE::Storage_Lite
    install Spreadsheet::ParseExcel

<2> lzop not found.
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
LZO arch/arm/boot/compressed/piggy.lzo
/bin/sh: 1: lzop: not found
make[2]: [arch/arm/boot/compressed/piggy.lzo] Error 1
make1:
[arch/arm/boot/compressed/vmlinux] Error 2
make: * [zImage] Error 2

sudo apt-get install lzop

Test

repack boot.img , then flash it with fastboot, please make sure you had unlocked your phone.
huawei u9508 with this to unlock

fastboot oem unlock UUUUUUUUUUUUUUUU

repack boot.img

mkboot boot.img out
... replace out/zImage
mkboot out new_boot.img

flash

adb reboot bootloader
fastboot flash boot new_boot.img
or 
fastboot flash:raw boot zImage ramdisk.gz
fastboot reboot

android reverse tools

tools are in my github
git@github.com:Wonfee/android-reverse-tools.git

apk modify

a. apktool
apktool官网
usage:
apktool d xx.apk
apktool b xx
b. baksmali/smali
baksmali github

apk resign

signapk xx.apk

boot.img recovery.img unpack repack

a. use android source code tools otatools

b. abootimg
$ apt-cache search abootimg
abootimg - Tool to read/write/update android boot images
$ sudo apt-get install abootimg
$ abootimg -i boot.img

c. mkboot
mkbootimg_tools github地址
which fix dtb missing when use abootimg tool to unpack boot.img or recovery.img

how to use

just set environment then enjoy it …

porting cyanogenmod

由于Cyanogenmod的源码编译已经没有问题,手头手机又都不在Cyanogenmod的支持列表里,所以打算将cyanogenmod亲自移植到我自己的手机上。
参考:How To Port CyanogenMod Android To Your Own Device

必备知识

成功移植过cyanogenmod到已知已支持的设备上;
对cyanogenmod的代码目录结构要熟悉;
移植一般会涉及到如下三个目录:
/device/[vendor]/[codename]
/vendor/[vendor]/[codename]
/kernel/[vendor]/[codename]

搜集我们手机的相关信息

搜集手机的必要信息,如:product name, code name, architecture, memory size, internal storage size, and platform architecture.可以从手机中读取(手机最好已经root),或者在网上下载.zip升级包,从.zip包里解出获取相关信息;

mkdir lenovo_s2 && cd lenovo_s2
adb pull /system/build.prop

vendor name:
adb shell getprop ro.product.manufacturer 或者从build.prop中读取
codename:
adb shell getprop ro.product.device 或者从build.prop中读取

解包boot.img 或者 recovery.img得到内核文件kernel,在得不到内核源码的情况下,可以通过这种方式得到编译好的内核文件;

boot.img,recovery.img可以在root过的手机上找到其对应分区,然后取出来;或者从.zip中得到;

在device、vendor、kernel下创建手机相关的目录

  1. 通过mkvendor.sh脚本自动创建
  2. 从github仓库里找是否有手机型号比较接近的然后克隆下来
  3. 手动创建这三个目录结构

我们使用1.的方式,此种方式比较快速,先得到boot.img或者recovery.img

./build/tools/device/mkvendor.sh [vendorname] [codename] [boot.img|recovery.img]

If it returns the message “unpackbootimg not found. Is your android build environment set up and have the host tools been built?” please be sure that you run the following command during setting up the developer environment:

$ make -j4 otatools

$ export PATH=$PATH:[source path]/out/host/linux-x86/bin

$ ./build/tools/device/mkvendor.sh lenovo s2 ../lenove_s2/mmcblk0p8_boot.img 
Arguments: lenovo s2 ../lenove_s2/mmcblk0p8_boot.img
Output will be in /data/Android/Cyanogenmod/device/lenovo/s2
737 blocks
Creating initial git repository.
/data/Android/Cyanogenmod/device/lenovo/s2 /data/Android/Cyanogenmod
Initialized empty Git repository in /data/Android/Cyanogenmod/device/lenovo/s2/.git/
[master (root-commit) 89d920e] mkvendor.sh: Initial commit of s2
 8 files changed, 96 insertions(+)
 create mode 100644 AndroidBoard.mk
 create mode 100644 AndroidProducts.mk
 create mode 100644 BoardConfig.mk
 create mode 100644 cm.mk
 create mode 100644 device_s2.mk
 create mode 100644 kernel
 create mode 100644 recovery.fstab
 create mode 100644 system.prop
/data/Android/Cyanogenmod
Done!
Use the following command to set up your build environment:
  lunch cm_s2-eng
And use the follwowing command to build a recovery:
  . build/tools/device/makerecoveries.sh cm_s2-eng

此时在device/[vendorname]/[codename]/目录下会生成 AndroidBoard.mk, AndroidProducts.mk, BoardConfig.mk, cm.mk, device_[codename].mk, kernel , recovery.fstab等文件

ls device/lenovo/s2/
AndroidBoard.mk  AndroidProducts.mk  BoardConfig.mk  cm.mk  device_s2.mk  kernel  recovery.fstab  system.prop

客制化生成的文件

为了能使用生成的recovery.img正常工作,我们需要到device/[vendorname]/[codename]/下对生生的文件根据手机做相应的修改;

Setup build environment:

lunch cm_[codename]-eng
lunch cm_s2-eng

build recovery image:

. build/tools/device/makerecoveries.sh cm_[codename]-eng
. build/tools/device/makerecoveries.sh cm_s2-eng

这样就完成了recovery.img的编译,但是发现用了两部手机通过此步骤做出的recovery.img刷进去后手机无法启动该recovery。

build cm-11 source code

编译环境准备

编译环境

uname -a
Linux wonfee-ThinkPad-T540p 3.16.7-ckt5my-very-own-kernel #1 SMP Fri Feb 27 23:04:29 CST 2015 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/issue
Ubuntu 14.04.2 LTS \n \l

java -version
java version “1.6.0_30”
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode)

安装其他必要的库

该部分可参考android源码官方编译文档,若已成功编译过android源码,则该部分的库应该都已经安装。
sudo apt-get install bison build-essential curl flex \
g++-multilib gcc-multilib git-core gnupg gperf \
lib32ncurses5-dev lib32readline-gplv2-dev lib32z1-dev \
libesd0-dev libncurses5-dev libsdl1.2-dev \
libwxgtk2.8-dev libxml2 libxml2-utils lzop \
openjdk-6-jdk openjdk-6-jre pngcrush schedtool \
squashfs-tools xsltproc zip zlib1g-dev

下载cm源码

参考: CyanogenMod Source Code Download

下载好cm-11源码后,如果要编译此时还需要下载其所支持机型相关的device、kernel等代码, 这里以官方所支持的nexus7机型作为测试。

从cm官方的github页面[cm-github][2]搜索grouper可以看到还需要下载device和kernel部分,分别为android_device_asus_grouper、android_kernel_asus_grouper,
mkdir -p device/asus/ && cd device/asus
git clone https://github.com/CyanogenMod/android_kernel_asus_grouper.git grouper
cd ../../
mkdir -p kernel/asus && cd kernel/asus/
git clone https://github.com/CyanogenMod/android_device_asus_grouper.git grouper

编译CM-11 源码

source build/envsetup.sh

including device/generic/armv7-a-neon/vendorsetup.sh
including device/generic/goldfish/vendorsetup.sh
including device/generic/mips/vendorsetup.sh
including device/generic/x86/vendorsetup.sh
including vendor/cm/vendorsetup.sh
including sdk/bash_completion/adb.bash
including vendor/cm/bash_completion/git.bash
including vendor/cm/bash_completion/repo.bash

breakfast grouper

Download the necessary prebuilts from cyanogenmod by running

cd verdor/cm/

. get-prebuilts

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   178  100   178    0     0    229      0 --:--:-- --:--:-- --:--:--   229
100  551k  100  551k    0     0   265k      0  0:00:02  0:00:02 --:--:-- 1531k
Archive:  ./proprietary/Term.apk
  inflating: ./proprietary/lib/armeabi/libjackpal-androidterm5.so  
  inflating: ./proprietary/lib/mips/libjackpal-androidterm5.so  
  inflating: ./proprietary/lib/x86/libjackpal-androidterm5.so  
  inflating: ./proprietary/lib/armeabi/libjackpal-termexec2.so  
  inflating: ./proprietary/lib/mips/libjackpal-termexec2.so  
  inflating: ./proprietary/lib/x86/libjackpal-termexec2.so

croot

Building the ROM

brunch grouper

running:  java -Xmx2048m -jar /data/Android/Cyanogenmod/out/host/linux-x86/framework/signapk.jar -w build/target/product/security/testkey.x509.pem build/target/product/security/testkey.pk8 /tmp/tmpFcHrQD /data/Android/Cyanogenmod/out/target/product/grouper/cm_grouper-ota-387c0dd2e4.zip
done.
Package Complete: /data/Android/Cyanogenmod/out/target/product/grouper/cm-11-20150824-UNOFFICIAL-grouper.zip

注意事项:

  1. 若编译环境有配置NDK_ROOT环境变量,则编译前需要取消该环境变量unset NDK_ROOT, 否则编译会直接如下报错;
    build/core/base_rules.mk:134: * external/webrtc/src/system_wrappers/source: MODULE.TARGET.STATIC_LIBRARIES.libwebrtc_system_wrappers already defined by external/webrtc/src/system_wrappers/source. Stop.
    build error!

CyanogenMod Source Code Download

env ubuntu 14.04 64

mkdir CyanogenMod && cd CyanogenMod
下载repo
curl http://php.webtutor.pl/en/wp-content/uploads/2011/09/repo > ./repo
chmod 755 ./repo
初始化:
./repo init -u git://github.com/CyanogenMod/android.git -b cm-11.0
同步源码:
./repo sync -j4

  • [new tag] android-wear-5.1.0_r1 -> android-wear-5.1.0_r1
  • [new tag] android-wear-5.1.1_r1 -> android-wear-5.1.1_r1
    Fetching projects: 100% (477/477), done.
    Checking out files: 100% (44267/44267), done. files: 22% (10167/44267)
    Checking out files: 100% (6686/6686), done.out files: 24% (1636/6686)
    Checking out files: 100% (9389/9389), done.out files: 32% (3007/9389)
    Checking out files: 100% (50822/50822), done.t files: 3% (1619/50822)
    Checking out files: 100% (10083/10083), done.
    Checking out files: 100% (4307/4307), done.out files: 2% (110/4307)
    Checking out files: 100% (4082/4082), done.out files: 24% (987/4082)
    Checking out files: 100% (3494/3494), done.out files: 10% (376/3494)
    Checking out files: 100% (7954/7954), done.
    Checking out files: 100% (4098/4098), done. out files: 20% (826/4098)
    Checking out files: 100% (11685/11685), done.ut files: 19% (2317/11685)
    Checking out files: 100% (4093/4093), done. out files: 29% (1193/4093)
    Checking out files: 100% (1654/1654), done. out files: 30% (510/1654)
    Checking out files: 100% (23588/23588), done.ut files: 0% (149/23588)
    Checking out files: 100% (4629/4629), done. out files: 34% (1592/4629)
    Checking out files: 100% (8597/8597), done.
    Checking out files: 100% (1765/1765), done. out files: 0% (12/1765)
    Checking out files: 100% (575/575), done.ng out files: 21% (123/575)
    Checking out files: 100% (431/431), done.ng out files: 10% (47/431)
    Checking out files: 100% (181/181), done.ng out files: 48% (87/181)
    Checking out files: 100% (2407/2407), done. out files: 33% (795/2407)
    Checking out files: 100% (2482/2482), done.
    Checking out files: 100% (177/177), done.ng out files: 10% (19/177)
    Checking out files: 100% (182/182), done.
    Checking out files: 100% (50299/50299), done.ut files: 16% (8475/50299)
    Checking out files: 100% (4864/4864), done.
    Checking out files: 100% (182/182), done.ng out files: 7% (14/182)
    Checking out files: 100% (1256/1256), done.
    Checking out files: 100% (53361/53361), done.ut files: 2% (1108/53361)
    Checking out files: 100% (126/126), done.
    Syncing work tree: 100% (477/477), done.

看到最后的 “Syncing work tree: 100% (477/477), done.” 代表代码同步完成。 由于同步代码会比较耗时,且网络不好断开时,没有同步完成的代码会以 tmppack_xxx 的形式保存在.repo/projects/仓库名/objects/pack/tmp_pack_XXX 目录下面,再次同步时会从头开始,若多次断开就会在该目录下存在多个tmp_pack_XXX的临时文件并占用大量空间,该文件会在代码同步完成后被删除,也可以手动删除 find ./ -name tmp_pack* -exec rm -rf {} \;

同步代码时为了防止断网导致同步中断可以用一个shell脚本来循环执行repo sync的操作直到成功:

./repo sync -j16
while [ $? != 0 ]
do
    ### maybe disconnect, try again
    sleep 1
    ./repo sync -j16
done

下面是代码同步完成后的目录结构:

.
├── abi
├── android
├── art
├── bionic
├── bootable
├── build
├── cts
├── dalvik
├── developers
├── development
├── device
├── docs
├── external
├── frameworks
├── hardware
├── kernel
├── libcore
├── libnativehelper
├── Makefile
├── ndk
├── packages
├── pdk
├── prebuilt
├── prebuilts
├── repo
├── sdk
├── sync.sh
├── system
├── tools
└── vendor

来看下整个仓库的大小:

45M    ./developers
118M./development
46M    ./libcore
12M    ./system
4.2G./prebuilts
1.2G./frameworks
11M    ./build
8.0K./kernel
33M    ./sdk
13M    ./art
88M    ./hardware
3.2G./external
12M    ./device
424M./cts
42M    ./dalvik
9.1M./docs
12M    ./bootable
19M    ./bionic
971M./tools
18G    ./.repo
120K./abi
72K    ./android
196K./libnativehelper
260M./prebuilt
89M    ./vendor
382M./packages
916K./pdk
77M    ./ndk
29G.

29G,.repo就占了18G,可见仓库的历史记录占用了很大的空间。代码同步完成就可以开始进行编译定制自己的rom了。