博文

目前显示的是 五月, 2011的博文

怎样向Android社区提交代码

注:[2014-3-13] 向android提交patch的方式已经更新,本文所叙述的方式不再完全匹配,请参考  http://source.android.com/source/submit-patches.html 向开源社区贡献代码的方式很多,Android采用repo的方式。 由于在提交patch的时候,必须使用repo upload命令,所以,首先要安装 repo 在自己的项目中。安装repo在自己项目的步骤分两步: 1-1. $ curl  http://android.git.kernel.org/repo > ~/bin/repo $ chmod a+x ~/bin/repo 1-2.然后把~/bin加入到PATH环境变量中,如果不加的话,用repo就需要全路径,比较麻烦,不管怎样,下面这一步是可选的: $ export PATH=~/bin:$PATH 2.安装repo到自己的项目中,只有安装到自己项目中后,才可以使用repo,即使是repo help也不例外。 $ repo init -u git:// android.git.kernel.org/platform/manifest.git 题外话:使用repo比使用git更麻烦,在教育网中,repo platform几乎是不能完成的任务,当然,可以使用git proxy,不过这种方法并不好使,一个简单且方便的方法是搞一个VPS 。 如果自己要提交的project没有在manifest管辖的范围内,那就需要自己去修改.repo/manifest.xml文件了。 比如,我要修改的Project项目名称是kernel/common,路径是kernel/common,而这个Project并没有在manifest.xml,所以在.repo/mainfest.xml文件中添加这么一行: <project path="kernel/common" name="kernel/common/" /> 然后运行repo sync去下载整个platform,整个platform的容量基本上2GB左右,如果没有必要下载那么多的项目,修改.repo/manifest.xml,只保留自己的

Android 与Linux Kernel

在kernel子目录下存放的就是Android的Linux Kernel了, 通过和标准的Linux 2.6.25 Kernel的对比,我们可以发现,其主要增加了以下的内容: 1. 基于ARM架构增加Gold-Fish平台,相应增加的目录如下: kernel/arch/arm/mach-goldfish kernel/include/asm-arm/arch-goldfish Gold-Fish平台采用的是ARM926T CPU作为BaseBand处理器, 该CPU主频至少为200M HZ. 采用MSM7201A CPU(ARM 11)作为主CPU, 其主频为528M HZ. 2. 增加了yaffs2 FLASH文件系统,相应增加的目录为: kernel/fs/yaffs2 实际上,Android包经过编译后生成的system.img和ramdisk.img文件就是yaffs2格式的包. 3. 增加了Android的相关Driver,相应目录为: kernel/drivers/android 主要分为: Android IPC系统: Binder Android 日志系统: Logger Android 电源管理: Power Android 闹钟管理: Alarm Android 内存控制台: Ram_console Android 时钟控制的gpio: Timed_gpio 4. 增加了switch处理, 相应的目录为: kernel/drivers/switch/ 5. 增加了一种新的共享内存处理方式, 相应增加的文件为: kernel/mm/ashmem.c 6. 其他为Linux-2.6.25内核所做的补丁等等,例如BlueTooth, 在此不做详细分析 另外GoldFish平台相关的驱动文件如下: 1. 字符输出设备: kernel/drivers/char/goldfish_tty.c 2. 图象显示设备: (Frame Buffer) kernel/drivers/video/goldfishfb.c 3. 键盘输入设备: kernel/drivers/input/keyboard/goldfish_events.c 4. RTC设备: (Real Time Clock) kernel/drivers/rtc/rtc-goldfish.c . US

Linux进程调度中队列的使用

Linux 进程调度中队列的使用 作者:西邮 王聪 Linux 内核中大量使用了队列,这里仅列举它在进程调度中的几处应用。 Linux 内核中的队列是以双链表的形式连接起来的, include/linux/list.h 中定义了队列并提供了一些接口,详细的介绍可以参考 [1] 中的附录。 Linux 中的进程有如下几个主要状态: 进程状态 说明 TASK_RUNNING 进程正在运行或将要被运行。 TASK_INTERRUPTIBLE 进程正在睡眠,等待某个条件的完成。 TASK_UNINTERRUPTIBLE 深度睡眠,不会被信号打扰。 TASK_STOPPED 进程运行被停止。 TASK_TRACED 进程被调试程序停止,被另一个进程跟踪。 两个额外的状态是 EXIT_ZOMBIE 和 EXIT_DEAD ,表示进程处于僵死状态还是真正死亡。处于僵死状态的进程会等待其父进程的收养(否则就会被 init 进程收养),而真正死亡的进程会被直接删除。 状态为 TASK_RUNNING 的进程都会被放入运行队列( runqueue )中,这是通过 task_struct (定义在 include/linux/sched.h )中的 run_list 成员来链接的。不过,为了让内核每次都能选取优先级最合适的进程, Linux 为每个优先级构建了一个 queue 。这是通过 struct prio_array 来实现的, struct prio_array 的定义在 kernel/sched.c ,大致如下: struct prio_array { int nr_active; unsigned long bitmap[BITMAP_SIZE]; struct list_head queue[MAX_PRIO]; }; queue 成员就是队列数组。每个 CPU 有各自的 runqueue ,每一个 runqueue 又有包含两个 prio_array ,一个是活动队列,一个是时间片耗尽的队列。当运行队列空时,内核便会交换两个队列的指针,原来的耗尽队列就成了新的活动队列!这和 prio_array 中的 bitmap 是决定调度算法为 O(1) 的关键。 状态为 TASK_STOPPED , EXIT_ZOMBIE 或

关于内核抢占

内核抢占 ---------------------------------------------------     与其他大部分Unix变体和其他大部分的操作系统不同, Linux完整地支持内核抢占。     在不支持内核抢占的内核中,内核代码可以一直执行,到它完成为止。也就是说,调度程序没有办法在一个内核级的任务正在执行的时候重新调度 -- 内核中的各任务是协作方式调度的,不具备抢占性。     在2.6版的内核中,内核引人了抢占能力;现在,只要重新调度是安全的,那么内核就可以在任何时间抢占正在执行的任务。     那么,什么时候重新调度才是安全的呢?只要没有持有锁,内核就可以进行抢占。锁是非抢占区域的标志。由于内核是支持SMP的,所以,如果没有持有锁,那么正在执行的代码就是可重新导入的,也就是可以抢占的。     为了支持内核抢占所作的第一处变动就是每个进程的thread_info引入了preempt_count(thread_info.preempt_count)计数器。该计数器初始值为0,每当使用锁的时候数值加1,释放锁的时候数值减1。当数值为0的时候,内核就可执行抢占。从中断返回内核空间的时候,内核会检查need_resched和preempt_count的值。如果need_resched被设置,并且preempt_count为0的话,这说明有一个更为重要的任务需要执行并且可以安全地抢占,此时,调度程序就会调度(抢占当前进程)。如果preempt_count不为0,说明当前任务持有锁,所以抢占是不安全的。这时,就会像通常那样直接从中断返回当前执行进程。如果当前进程所持有的所有的锁都被释放了。那么preempt_count就会重新为0。此时,释放锁的代码会检查need_resched是否被设置。如果是的话,就会调用调度程序。有些内核代码需要允许或禁止内核抢占。     如果内核中的进程被阻塞了,或它显式地调用了schedule(),内核抢占也会显式地发生。这种形式的内核代码从来都是受支持的,因为根本无需额外的逻辑来保证内核可以安全地发生被抢占。如果代码显式的调用了schedule(),那么它应该清楚自己是可以安全地被抢占的。     内核抢占发生在:     (1) 当"从中断处理程序"正在执行,且返回内核空间之前     (2

关于Makefile

几乎所有的Linux项目都是使用make来进行项目管理的.make是依据Makefile来进行工作的.因此书写和阅读Makefile就是Linux程序员必备的一项基本功. 对于像我这样的newbie,写一个稍微复杂的Makefile必定会错误百出,原因是Makefile的命令语法与bash有相似之处,但是还有许多细节上的差别,比如 赋值bash要求"="两边是不能有空格的,但是Makefile就允许. 在bash中用if条件判断,就像VB一样,但是如果要在Makefile中使用的话,需要写到一行中,如果写不下,需要用"\"来告诉make,下面的一行和上面的这一行属于一个逻辑行. Makefile还对TAB,空格有严格的要求,这个仿佛就像是Python.如果你不TAB就写一个命令,make不认为是一个命令,而如果写个ifdef而用了TAB的话,make会把ifdef当作一个命令来执行,而不是一个条件判断. exit在Makefile中貌似起不到Bash中的效果,你要在Makefile中控制其执行情况必须用error才可以. 读Makefile就是执果索因(这是别人总结的),根据结果顺瓜摸藤,就比较容易了.而对于Makefile的语法如果单单能够要求读懂的话,也是比较简单。 一般情况,在一个项目中,用Makefile就完全能够进行项目管理了。但一些项目会由像Rules.mk,Post.mk之类的东西让我们感到望而生畏,仿佛Make是一项深不可测的东西。其实 Rules.mk和Post.mk 同 1.mk 2.mk 没有什么区别。在一个论坛里面有下面一句话: IIRC, traditionally, when people set up Makefiles and used files named rules.mk and make.mk , they put all the platform-independent stuff in make.mk , and all the platform-specific stuff in rules.mk . And then their Makefiles just included those, and each Makefile contained the things