2010年2月26日 星期五

Linux Driver : /proc file system (Part1)



Ref:

http://www.wangcong.org/articles/lkmpg_cn/index.htm#AEN602





1. chardev.c

/*

* chardev.c: Creates a read-only char device that says how many times

* you've read from the dev file

*/



#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <asm/uaccess.h> /* for put_user */



/*

* Prototypes - this would normally go in a .h file

*/

int init_module(void);

void cleanup_module(void);

static int device_open(struct inode *, struct file *);

static int device_release(struct inode *, struct file *);

static ssize_t device_read(struct file *, char *, size_t, loff_t *);

static ssize_t device_write(struct file *, const char *, size_t, loff_t *);



#define SUCCESS 0

#define DEVICE_NAME "gw-chardev" /* Dev name as it appears in /proc/devices */

#define BUF_LEN 80 /* Max length of the message from the device */



/*

* Global variables are declared as static, so are global within the file.

*/



static int Major; /* Major number assigned to our device driver */

static int Device_Open = 0; /* Is device open?

* Used to prevent multiple access to device */

static char msg[BUF_LEN]; /* The msg the device will give when asked */

static char *msg_Ptr;



static struct file_operations fops = {

.read = device_read,

.write = device_write,

.open = device_open,

.release = device_release

};



/*

* This function is called when the module is loaded

*/

int init_module(void)

{

Major = register_chrdev(0, DEVICE_NAME, &fops);



if (Major < 0) {

printk(KERN_ALERT "Registering char device failed with %d\n", Major);

return Major;

}



printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);

printk(KERN_INFO "the driver, create a dev file with\n");

printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);

printk(KERN_INFO "Try various minor numbers. Try to cat and echo to\n");

printk(KERN_INFO "the device file.\n");

printk(KERN_INFO "Remove the device file and module when done.\n");



return SUCCESS;

}



/*

* This function is called when the module is unloaded

*/

void cleanup_module(void)

{

unregister_chrdev(Major, DEVICE_NAME);

printk(KERN_ALERT "cleanup_module - GW\n");

}



/*

* Methods

*/



/*

* Called when a process tries to open the device file, like

* "cat /dev/mycharfile"

*/

static int device_open(struct inode *inode, struct file *file)

{

static int counter = 0;



if (Device_Open)

return -EBUSY;



Device_Open++;

sprintf(msg, "I already told you %d times Hello world!\n", counter++);

msg_Ptr = msg;

try_module_get(THIS_MODULE);

return SUCCESS;

}



/*

* Called when a process closes the device file.

*/

static int device_release(struct inode *inode, struct file *file)

{

Device_Open--; /* We're now ready for our next caller */



/*

* Decrement the usage count, or else once you opened the file, you'll

* never get get rid of the module.

*/

module_put(THIS_MODULE);



return 0;

}



/*

* Called when a process, which already opened the dev file, attempts to

* read from it.

*/

static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */

char *buffer, /* buffer to fill with data */

size_t length, /* length of the buffer */

loff_t * offset)

{

/*

* Number of bytes actually written to the buffer

*/

int bytes_read = 0;



/*

* If we're at the end of the message,

* return 0 signifying end of file

*/

if (*msg_Ptr == 0)

return 0;



/*

* Actually put the data into the buffer

*/

while (length && *msg_Ptr) {



/*

* The buffer is in the user data segment, not the kernel

* segment so "*" assignment won't work. We have to use

* put_user which copies data from the kernel data segment to

* the user data segment.

*/

put_user(*(msg_Ptr++), buffer++);

length--;

bytes_read++;

}



/*

* Most read functions return the number of bytes put into the buffer

*/

return bytes_read;

}



/*

* Called when a process writes to dev file: echo "hi" > /dev/hello

*/

static ssize_t

device_write(struct file *filp, const char *buff, size_t len, loff_t * off)

{

static int w_count = 0;

printk(KERN_INFO "You write message %d times.\n", w_count++);

return -EINVAL;

}



2. Makefile



obj-m += chardev.o

KERNELDIR := /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)



default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:

$(RM) *.o *.mod.c *.ko *.symvers



3. Fixed try



$make



#掛載driver module

$insmod chardev.ko



#建立裝置檔案節點

# mknod 裝置檔名 [bcp] [Major] [Minor]

#選項與參數:

#裝置種類:

# b :設定裝置名稱成為一個周邊儲存設備檔案,例如硬碟等;

# c :設定裝置名稱成為一個周邊輸入設備檔案,例如滑鼠/鍵盤等;

# p :設定裝置名稱成為一個 FIFO 檔案;



# Major :主要裝置代碼;

# Minor :次要裝置代碼;

$mknod /dev/gw-chardev c 250 0



#Testing1 - write message

$echo "Hello World" > /dev/gw-chardev



#Testing2 - read message

$cat /dev/gw-chardev



#卸載 driver module

$rmmod chardev



kdesvn 下關於kernel ignore問題

kdesvn 下關於kernel ignore問題

2009/2/26(四) 陰
關於kernel 有許多 *.cmd , *.mod 不會自動ignore 的問題,此為Make 型態問題,*.cmd.c *.cmd *.mod ...etc 此一類型檔案為runtime 產生,故每一使用者build時都會產生不同path問題,造成build過後會跟svn上不match.
問題:
  • 若要人工去ignore 將花費大量時間。
  • kdesvn無提供rule 套用所有子目錄。
解決方式:
  • ~/.subversion/config,將這個檔裡面下面的注解拿掉,重啟kdesvn即可解決。
    原始:#global-ignores = *.mod.c *.ko *.cmd *.o *.lo *.la
    修改為:global-ignores = *.mod.c *.ko *.cmd *.o *.lo *.la *.mod arm-merlin arm-merlin.build

2010年2月25日 星期四

Special bash variables

Special bash variables

Android源码编译反思 收藏

原创 Android源码编译反思 收藏

【初步构想】

如果是在一台PC上先完整的编译一次Android源码,然后将整个编译好的源码移到另一台PC,然后再在移到的PC上编译,这样估计是可以减少时间的吧?

【初步测试】

初步测试结果,很令我感动意外,似乎所花费的时间跟make clean后,再make所花的时间差不多,这是为啥呢?看来得好好研究一下make的规则。

【今天测试进展-20091024】

在看了有关Makefile的介绍后,才了解到Makefile跟时间戳关联很紧密,于是,我采用了如下方法编译Android源码:

1、拷贝一份已经编译好的源码到另一个路劲下,这样整个源码的时间都会被修改;

2、修改out目录下所有文件的时间戳为当前时间(请参考linux时间戳一文),这样保证目标文件总比依赖文件新;

3、开始编译源码,编译时终于发现一些令人惊喜的log,即源码好像不再是从C/C++源码开始编译,而是做一些拷贝或者格式转换的工作,对于动态链接库主要有三步,分别是:target SharedLib, target Prelink, target Strip,值得特别说明的是libwebcore.so档是唯一重新编译的一个动态链接库,原因尚未找出来。

1)、target SharedLib

target SharedLib: libwebcore (out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/LINKED/libwebcore.so)

prrebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi g++ -nostdlib -wl,-soname,libwebcore.so -wl .......

2)、target Prelink

target Prelink: libwebcore (out/target/product/generic/symbols/system/lib/libwebcore.so)
out/host/linux-x86/bin/apriori --prelinkmap build/core/prelink-linux-arm.map --locals-only --quiet out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/LINKED/libwebcore.so --output out/target/product/generic/symbols/system/lib/libwebcore.so

3)、 target Strip

target Strip: libwebcore (out/target/product/generic/obj/lib/libwebcore.so)
out/host/linux-x86/bin/soslim --strip --shady --quiet out/target/product/generic/symbols/system/lib/libwebcore.so --outfile out/target/product/generic/obj/lib/libwebcore.so

libwebcore.so在三个文件夹中出现

obj/SHARED_LIBRARIES/libwebcore_intermediates/LINKED/libwebcore.so(258MB)-> symbols/system/lib/libwebcore.so(257MB)-> obj/lib/libwebcore.so(3.9MB)

4)、其他举例

对于JAR

target Java: am (out/target/common/obj/JAVA_LIBRARIES/am_intermediates/classes)
Copying out/target/common/obj/JAVA_LIBRARIES/am_intermediates/classes-full-debug.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/am_intermediates/classes.jar
target Dex: am
target Jar: am (out/target/common/obj/JAVA_LIBRARIES/am_intermediates/javalib.jar)

对于APK:

target Java : Camera (out/target/common/obj/APPS/Camera_intermediates/classes)
Copying out/target/common/obj/APPS/Camera_intermediates/classes-full-debug.jar
Copying: out/target/common/obj/APPS/Camera_intermediates/classes.jar
target Dex : Camera
target Package : Camera (out/target/product/generic/obj/APPS/Camera_intermediates/package.apk)

对于可执行文件:

target Executable : ssh (out/target/product/generic/obj/EXECUTABLES/ssh_intermediates/LINKED/ssh)
target Non-prelinked : ssh (out/target/product/generic/symbols/system/bin/ssh)
target Strip : ssh (out/target/product/generic/obj/EXECUTABLES/ssh_intermediates/ssh)


4、img文件的生成过程描述

1)、system.img

Target system fs image : out/target/product/generic/obj/PACKAGING/systemimage_unopt_intermediates/system.img
out/host/linux-x86/bin/mkyaffs2image -f out/target/product/generic/system out/target/product/generic/obj/PACKAGING/systemimage_unopt_intermediates/system.img


Install system fs image : out/target/product/generic/system.img
out/host/linux-x86/bin/acp -fpt out/target/product/generic/obj/PACKAGING/systemimage_unopt_intermediates/system.img out/target/product/generic/system.img

2)、ramdisk.img
Target ram disk : out/target/product/generic/ramdisk.img

out/host/linux-x86/bin/mkbootfs out/target/product/generic/root | gzip > out/target/product/generic/ramdisk.img

3)、userdata.img(此种方法userdata.img并未重新生成,怪事啊)

out/host/linux-x86/bin/mkyaffs2image -f out/target/product/generic/data out/target/product/generic/userdata.img

5、对于整个编译过程的描述

1)、更新动态链接库

2)、生成javalib.jar

3)、生成APK

4)、生成可执行文件

5)、编译生成libwebcore.so(很费时间)

6)、生成img

6、附件说明

1)、整个编译过程log摘要:

host Executable: acp (out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp)
true
Install: out/host/linux-x86/bin/acp
host Java: droiddoc (out/host/common/obj/JAVA_LIBRARIES/droiddoc_intermediates/classes)
Install: out/host/linux-x86/framework/droiddoc.jar
Install: out/host/linux-x86/lib/libneo_util.so
Install: out/host/linux-x86/lib/libneo_cs.so
Install: out/host/linux-x86/lib/libneo_cgi.so
Install: out/host/linux-x86/lib/libclearsilver-jni.so
Install: out/host/linux-x86/bin/dx
host Executable: aapt (out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/aapt)

host SharedLib: libSR_Core (out/host/linux-x86/obj/lib/libSR_Core.so)
host SharedLib: libSR_AcousticModels (out/host/linux-x86/obj/lib/libSR_AcousticModels.so)
host SharedLib: libSR_AcousticState (out/host/linux-x86/obj/lib/libSR_AcousticState.so)
host SharedLib: libSR_Semproc (out/host/linux-x86/obj/lib/libSR_Semproc.so)
host SharedLib: libSR_Vocabulary (out/host/linux-x86/obj/lib/libSR_Vocabulary.so)
host SharedLib: libSR_Grammar (out/host/linux-x86/obj/lib/libSR_Grammar.so)
host SharedLib: libSR_Nametag (out/host/linux-x86/obj/lib/libSR_Nametag.so)
host SharedLib: libSR_Session (out/host/linux-x86/obj/lib/libSR_Session.so)
host Executable: grxmlcompile (out/host/linux-x86/obj/EXECUTABLES/grxmlcompile_intermediates/grxmlcompile)
true
Install: out/host/linux-x86/lib/libESR_Portable.so
Install: out/host/linux-x86/lib/libESR_Shared.so
Install: out/host/linux-x86/lib/libSR_EventLog.so
Install: out/host/linux-x86/lib/libSR_Core.so
Install: out/host/linux-x86/lib/libSR_AcousticModels.so
Install: out/host/linux-x86/lib/libSR_AcousticState.so
Install: out/host/linux-x86/lib/libSR_G2P.so
Install: out/host/linux-x86/lib/libSR_Semproc.so
Install: out/host/linux-x86/lib/libSR_Vocabulary.so
Install: out/host/linux-x86/lib/libSR_Grammar.so
Install: out/host/linux-x86/lib/libSR_Nametag.so
Install: out/host/linux-x86/lib/libSR_Session.so
Install: out/host/linux-x86/lib/libfst.so
Install: out/host/linux-x86/bin/grxmlcompile

2)、libwebcore.so编译过程摘要:

target thumb C++: libwebcore <= external/webkit/ JavaScriptCore/bytecode/CodeBlock.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/bytecode/JumpTable.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/bytecode/Opcode.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/bytecode/SamplingTool.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/bytecode/StructureStubInfo.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/debugger/Debugger.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/debugger/DebuggerActivation.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/debugger/DebuggerCallFrame.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/interpreter/CallFrame.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/interpreter/Interpreter.cpp
target thumb C++: libwebcore <= external/webkit/JavaScriptCore/interpreter/RegisterFile.cpp

.........................................

target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/ANPSoundInterface.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/ANPTypefaceInterface.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/ANPWindowInterface.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/PluginTimer.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/PluginViewBridgeAndroid.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/PluginWidgetAndroid.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/plugins/SkANP.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/wds/Command.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/wds/Connection.cpp
target thumb C++: libwebcore <= external/webkit/WebKit/android/wds/DebugServer.cpp

target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/ JavaScriptCore/parser/Grammar.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/CSSGrammar.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/XPathGrammar.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/UserAgentStyleSheets.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSCharsetRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSFontFaceRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSImportRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSMediaRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSPageRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSPrimitiveValue.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSRuleList.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSStyleDeclaration.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSStyleRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSStyleSheet.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSUnknownRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSValue.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSValueList.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSVariablesDeclaration.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCSSVariablesRule.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSCounter.cpp
target thumb C++: libwebcore <= out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/WebCore/css/JSMediaList.cpp

target SharedLib: libwebcore (out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates/LINKED/libwebcore.so)
target Prelink: libwebcore (out/target/product/generic/symbols/system/lib/libwebcore.so)
target Strip: libwebcore (out/target/product/generic/obj/lib/libwebcore.so)

【今天测试进展-20091025】

1、昨天提到“值得特别说明的是libwebcore.so档是唯一重新编译的一个动态链接库,原因尚未找出来。”这个问题,已经得到解决了,原来在out目录下( out/target/product/generic/obj/SHARED_LIBRARIES/libwebcore_intermediates ),也有.java及其.cpp文件,所以会重新编译了。 我昨天在out目录下使用指令find ./* -exec touch {} \;,结果把out下的文件的时间戳都改为当前时间,其中也包括.java及其.cpp文件,如果是要解决这个问题,必须把.java及其.cpp文件排除在外啊。

如果是要排除某一类型文件,可以执行类似命令:

find . -type f ! -name "*.cpp" -exec touch {} \;

find . -type f ! -name "*.java" -exec touch {} \;

但是要同时排除这两种类型的文件,该怎么执行指令呢?

find . -type f \( ! -name "*.java" -and ! -name "*.cpp" \) -exec touch {} \;

如果不用这个办法,还有一种方法是理清整个编译过程所产生的文件,比如链接库的产生过程是:*.c/cpp---->*.o--->*.a/*.so,只要保证目标文件是最新的就行。除了静态、动态连接库外,还有jar文件的产生过程也要清楚。

找出out目录下的所有*.cpp, *.o, *.a, *.so文件,并保存在txt文件中。

today=`date +%y-%m-%d`

find ./out -type f \( -name "*.cpp" -or -name "*.o" -or -name "*.a" -or -name "*.so" \) -exec echo {} >> cpp_o_a_so_$today.txt \;

找出out目录下的所有*.java, *.class, *.jar, *.dex,*.apk文件,并保存在txt文件中。

find ./out -type f \( -name "*.java" -or -name "*.class" -or -name "*.jar" -or -name "*.dex" -name "*.apk" \) -exec echo {} >> java_class_jar_dex_$today.txt \;

2、今天无意中发现了几个包含"timestamp"字样的文件,其中的文件作用可能与时间戳有紧密关联,也和make紧密关联,得研究一下才行。

-rw-rw-r-- 1 san san 0 2009-10-27 03:20 ./out/target/common/docs/offline-sdk-timestamp
-rw-rw-r-- 1 san san 0 2009-10-27 03:20 ./out/target/common/obj/PACKAGING/checkapi-current-timestamp
-rw-rw-r-- 1 san san 0 2009-10-27 03:20 ./out/target/common/obj/PACKAGING/checkapi-last-timestamp
-rw-rw-r-- 1 san san 0 2009-10-27 03:20 ./out/target/product/generic/obj/NOTICE_FILES/hash-timestamp

【今天测试进展-20091027】

1、今天的做法仍然是保证目标文件是最新的,测试结果是编译时间大概需要50分钟,比当初的重新编译所需的两个小时缩短了很多。

find ./out -type f \( ! -name "*.java" -and ! -name "*.cpp" \) -exec touch {} \;

或者

find ./out -type f \( -name "*.o" -or -name "*.a" -or -name "*.so" \) -exec touch {} \;
find ./out -type f \( -name "*.class" -or -name "*.jar" -or -name "*.dex" -or -name "*.apk" \) -exec touch {} \;

2、编译的过程中有几个地方比较花时间,至今尚未找到解决办法。

(1)、产生libwebcore.so(258MB)

(2)、从jar产生dex

(3)、soslim链接可执行文件

3、关于timestamp

今天测试修改了"timestamp"字样的文件的时间戳,但好像没什么效果。

find ./out -type f -name "*timestamp" -exec touch {} \;

4、待测试,修改*intermediates下所有文件的时间戳

find ./out -type d -name "*intermediates" -exec touch {} \;

【今天测试进展-20091101】

查找并显示所有Makefile的文件内容

find . -type f -name "*.mk" -print -exec cat {} \; > all_android_mk_file.txt

find . -type f -name "*.mk" -printf "\n# ===========================================\n" -print -printf "# ===========================================\n\n" -exec cat {} \; > ~/Desktop/android_mk.txt

研究过了Android编译过程的一些Log,现在该好好看一下MK是怎么写的了,其实,MK只是Log的浓缩而已了。