这篇文章通过开发完成一个Node.js的web应用,介绍了很多技术点:服务端JavaScript、函数式编程、阻塞与非阻塞、回调、事件、内部和外部模块等等,可作为node学习的入门材料。
add system call to linux
添加系统系统到内核,测试环境huawei u9508手机,基于内核代码huawei u9508 kernel
修改 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_syscallsdefine syscalls_counted
- CALL(sys_hello)
修改 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
修改 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.
在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
修改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) \
编译内核
export CROSS_COMPILE=arm-linux-androideabi-
export ARCH=arm
make distclean
make hisi_k3v2oem1_defconfig
make zImagemodify 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测试添加的系统调用
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
setup cross compile environment.
sudo apt-get install mingw-w64 binutils-mingw-w64download openssl source code
git clone https://github.com/openssl/openssl.gitcross 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 error1>
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 22>
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 …
Log on as Administrator in win8
一、我的电脑->管理->本地用户和组->Administrator
二、cmd prompt
net user administrator /active:yes
net user administrator /active:no
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下创建手机相关的目录
- 通过mkvendor.sh脚本自动创建
- 从github仓库里找是否有手机型号比较接近的然后克隆下来
- 手动创建这三个目录结构
我们使用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
注意事项:
- 若编译环境有配置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了。