android linux内核

2018-11-12 22:59:07 WuLex 阅读数 4240
    Android Version    |API Level  |Linux Kernel in AOSP
    ----------------------------------------------------
    1.5   Cupcake      |3          |2.6.27
    1.6   Donut        |4          |2.6.29
    2.0/1 Eclair       |5-7        |2.6.29
    2.2.x Froyo        |8          |2.6.32
    2.3.x Gingerbread  |9, 10      |2.6.35
    3.x.x Honeycomb    |11-13      |2.6.36
    4.0.x Ice Cream San|14, 15     |3.0.1
    4.1.x Jelly Bean   |16         |3.0.31
    4.2.x Jelly Bean   |17         |3.4.0
    4.3   Jelly Bean   |18         |3.4.39
    4.4   Kit Kat      |19, 20     |3.10
    5.x   Lollipop     |21, 22     |3.16.1
    6.0   Marshmallow  |23         |3.18.10
    7.0   Nougat       |24         |4.4.1
    7.1   Nougat       |25         |4.4.1 (To be updated)

Table compiled from:

Note: other “distributions” of Android might run different kernel versions.

Anyone is welcome to correct and expand this table. Please keep formatting.

887.jpg

在这里插入图片描述

图解Android和Linux发行版的区别

众所周知Google的Android系统跟Linux系统有着千丝万缕的关系,可究竟有什么关系呢?有人说AndroidAndroidLinuxLinux,两个只是kernel一样调度机制一样,其他没一毛钱关系,有人说Android说到底就是个Linux系统,可如果是这样,那么为什么Android系统能这么火,其他的Linux发行版(Ubuntu/Fedora/centos等)为什么在移动端火不起来呢?下面的图或许可以解开这些迷惑。

Android系统跟Linux系统关系
Android系统架构图
在这里插入图片描述
Linux系统架构图
在这里插入图片描述

上面两幅图应该很直观的展示了Android系统和Linux发行版系统(Ubuntu/Fedora/centos)之间的区别和联系。可以这么说Android本质上还是一个Linux系统,只不过Google对它进行了裁剪和定制,这跟我们定制Linux到自己的嵌入式设备上的做法大同小异,只不过Google做的更多。

本质区别:Android系统和Linux发行版的系统根本区别是Android上面只跑了一个Dalvik/ART,而Linux发行版上面跑了很多“Dalvik/ART”而已。如果你把gnome或者LXQT部署到Android上,或者把Dalvik/ART部署到Linux发行版上的话,那么二者的区别可能并没你想象的那么大。

2016-04-03 17:12:06 omnispace 阅读数 824

对于在Windows上写代码写习惯的人,调试是必不可少的手段,但是转到Android以后,发现调试手段异常简陋,Windows简直不是一个级别,特别是Android的内核调试,网上资料也相对较少,不过通过一段时间的倒腾,我终于找到了还算靠谱的调试方法.就是利用Emulator + Eclipse进行Android Linux内核调试.

 

1.系统预装环境

在目前为止,都是使用的最新版本的Android开发环境

 

Ubuntu 14.04 

Android SDK( adt-bundle-linux-x86_64-20140702 )

Android NDK( android-ndk32-r10b-linux-x86_64 )

 

安装好这几个环境以后,设置一下环境变量

 

export PATH=$PATH:ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin

 

ANDROID_NDK_HOME键值为Android NDK安装目录,设置这个环境变量的目的主要是为了使用gcc 4.6版本编译linux内核

 

export PATH=$PATH:ANDROID_SDK_HOME/sdk/tools

 

ANDROID_SDK_HOMEAndroid SDK的安装目录,设置这个环境变量的目的是方便使用emulator命令!

 

万事具备.使用前面安装的Android SDK创建一个虚拟的设备.并且确保 emulator -avd Device_Test这条命令可以启动Android 模拟器.先热身下

 

2.Android Linux内核编译

 

2.1 下载GoldFish 源码

 

mkdir kernel 

cd kernel

git clone http://android.googlesource.com/kernel/goldfish.git

 

GoldFish是适配模拟器的内核源码,如果是要具体适配其他机型,请选择其他源码,这边不展开了,详情参考链接有说明如果失败了,https.我换https是因为使用了代理,现在google被墙,不使用代理搞不动!

 

git clone https://android.googlesource.com/kernel/goldfish.git

 

 

下载过程看你的代理速度了,而且不能中断.中断了就要重新来,特别的麻烦和恶心!所以我上传了一份到百度云和上面goldfish出来的一样.可以考虑去下载

 

http://pan.baidu.com/s/1i3yzhbv

 

下载或者解压完成以后会在kernel目录下会生成一个goldfish文件夹,进入此目录.查看所有分支

 

 

 

可以看到有很多的版本, 2.6.293.4我都测试过编译和运行没有任何问题所以这边我们拉2.6.29的源码

 

git checkout remotes/origin/android-goldfish-2.6.29

 

 

然后目录下就有很多文件了,说明Android Linux的源码下载成功!

 

 

 

3.2 编译GoldFish 源码

 

编译源码之前,请确认已经将NDK的编译工具设置到环境变量中.我们将使用上述这个目录下的交叉编译器arm-linux-androideabi-gcc

 

export PATH=$PATH:ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin

 

然后在glodfish目录下用gedit打开Makefile文件,找到这两行文字:

 

#ARCH ?= $(SUBARCH)

#CROSS_COMPILE ?=

 

修改成

ARCH ?= arm

CROSS_COMPILE ?= arm-linux-androideabi-

 

 

 

保存文件然后

 

make goldfish_armv7_defconfig 

 

 

:$make goldfish_defconfig这样配置也可以编译通过,模拟器也可以启动,但是Android的开机画机就显示不了,$adb shell也死活连不上,原因就是这个goldfish_defconfig这个配置文件问题.

 

Android Linux的基本编译就设置完成了.我们先make 一下

make

 

 

这就表示编译成功了,Linux的源码是Linux上少有的一键make过去的软件,比编译其他Linux应用简单不少.当然到这里编译出来的这个zImage已经可以运行了,但是离我们用来做调试的还是有差距.我们还要开启内核调试和关闭优化

 

3.3 开启调试选项

开启Linux内核的调试选项先安装依赖性

sudo apt-get install ncurses-dev

然后

make menuconfig

 

 

进入内核配置界面,勾选下列选项,同时关闭优化

 

General setup —> 

[ ] Optimize for size,进行开启/关闭

 

[*] Kernel hacking 

     [*] Compile the kernel with debug info 

     [*] KGDB: kernel debugging with remote gdb —>      

[*] Enable dynamic printk() call support 

 

关闭Linux内核优化比较麻烦.我通过和朋友讨论,以及网络搜索还没有找到很好的解决办法,原因是默认的Linux内核编译是开启-O2优化的,这种模式之下会造成gdb和实际的源码对不上,相信使用过windbg调试-O2的朋友都有这个经历,所以我们需要关闭Linux-O2,不过目前还没有很好的解决办法下面这篇文章讨论的解决办法是.针对文件进行关闭优化.下面这两篇文章的讨论都非常有意义:

 

http://www.lenky.info/archives/2013/03/2238

 

http://www.ibm.com/developerworks/cn/linux/l-kdb/

 

这边我们将-Os -O2都调成-O.针对具体文件关闭优化,这边就不搞了.具体到自己的调试任务的时候再看

 

 

 

再进行编译

make -B

选项-B以强制所有内核源文件全部重新编译(因为我前面编译过一次了,为了保险起见,就让目标文件全部重新生成吧)当出现这个画面,就表示编译成功了

 

 

 

4.Android Linux内核调试

使用emulator 启动我们编译的内核试试

 

emulator -verbose -show-kernel -kernel ~/kernel/goldfish/arch/arm/boot/zImage -avd Device_Test

 

 

没错启动的就是我们的内核2.6.29 时间也对的上.说明我们编译的内核是可以运行的.下一步使用这条命令

 

emulator -verbose -show-kernel -kernel -netfast ~/kernel/goldfish/arch/arm/boot/zImage -avd Device_Test -qemu -gdb tcp::1234,ipv4, -S

 

这条命令会在tcp端口的1234监听.加了-S还会暂停下来,等待着gdb链接上来.这时候我们开启NDK目录下面的gdb.链上去然后

 

target remote localhost:1234 

 

 

还可以测试几条命令看看源码是否跟上了

 

 

到这里为止,基本上是用gdb连上emulator 进行内核调试应该没问题了.但是仅仅到这里那离windbg的调试还是差好几条街.所以我们还是需要一个更好的调试方法.是用eclipse来作为调试的前端!

 

5.Eclipse前端

是用Eclipse作为前端的好处是,无论是在windows,linux下面都没有问题.可以在一台windows的机器上,远程调试android内核.所以为了截图方便,我下面的操作都是在windows上弄的,Linux上也是一样!当然要在windows上进行调试,首先要将上面的gold目录复制到windows的机器上,或者是共享给windows.这里就不展开了!

 

运行Eclipse,点击菜单Help->Install New Software… 在弹出的对话框里点击Work with:后面的下拉按钮,选择Kepler – http://download.eclipse.org/releases/kepler

 

不同的Eclipse版本选择不一样,与自己下载的版本一致一即可.然后在下面的选择框中将以下选项安装上

Programming Languages 

C/C++ Autotools support

C/C++ Visual C++ Support

C/C++ Development Tools

C/C++ Development Tools SDK

Linux Tools

GDB Tracepoint Analysis

Mobile and Device Development

C/C++ GDB Hardware Debugging

 

安装好后自动重启Eclipse即可.再配置点击菜单Window -> Preferences在弹出的对话框中,点击左边的General->Workspace将右边的Build automatically复选框不选中.

再点击对话框左边的C/C++->Indexer,将右边的Enable indexerAutomatically update the index两复选框不选中.

 

接下来就简单了.创建一个工程,点击菜单File->New->Project…在弹出的对话框中选择C/C++->C Project再点击Next >按钮

 

 

其中Project name:为工程名,可自定义.Location:则为工程文件所在路径,此处设置为我们下载的源码路径而Project type:则设置为Makefile project/Empty Project, Toolchains:则设置为Linux GCC,如果是windows设置成Android GCC最后点击Finish即可.

 

接下来WindowsLinux都一样,进行DEBUG配置,Project Explorer里右击刚创建的Linux_Kernel项目,在右键菜单中点击Debug As->Debug Configurations…在弹出的对话框中双击GDB Hardware Debugging 然后配置调试选项如下图

 

 

C/C++ Application:栏设置为Linux Kernel源码编译出来的vmlinux文件所在路径(包含文件名),然后将Disable auto build选上,切换到Debugger,修改配置如下截图.

 

 

 

这里是设置gdb的路径还有远程地址和端口. Gdb的路径在ndk安装目录下的如下路径

 

\toolchains\arm-linux-androideabi-4.6\prebuilt\windows-x86_64\bin

 

远程地址,我的ubuntu机器是192.168.1.2这个随机应变即可.端口是我们运行emulator命令定义的端口.搞定这个切换到Startup页面

 

 

 

Reset and Delay(seconds)和 Halt 还有Load image复选框的勾都去掉.然后点击Debug,这时候就停在第一条指令了

 

这时候还不能按F5, F6单步.我们在Execut窗口指定到main.c 然后在 start_kernel上下个断点也可以再Console窗口敲命令break start_kernel. 然后敲入命令C. 

 

 

这时候就停在了Linux内核的入口函数start_kernel.也可以使用F5,F6.寄存器显示各方面都可以了.如果在Windows,有一个毛病,源文件都要自己重新指定路径.不然认不到默认都是编译路径/home/xxx什么的.要重新指定成Windows的盘符形式.不过在Linux上调试就没有这个问题了!

 

 

 

这个调试差不多是搞起走了.如果是分析Android的源码,看一看跟一下还是很不错的.不过还是有一个问题没有解决,关于汇编和符号不对应的问题.大家可以群策群力搞一下!

 

参考链接:

http://wenku.baidu.com/view/95c69448e518964bcf847c2f.html 

http://blog.csdn.net/flydream0/article/details/7070392 

http://www.lenky.info/archives/2013/03/2238 

http://blog.csdn.net/liushuaikobe/article/details/8646555

http://x-slam.com/da_jian_eclipse_qemu_gdb_diao_shi_linux_kernel_huan_jing 

网友评论:

  1. Rover12421  说:

    不建议修改Makefile文件.可以在make命令后面添加参数
    make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- goldfish_armv7_defconfig
    make ARCH=arm CROSS_COMPILE=arm-linux-androideabi-

    make的时候顺便加上-j参数,多线程编译加快速度
    make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- -j8

  2. Rover12421  说:

    emulator -verbose -show-kernel -kernel -netfast ~/kernel/goldfish/arch/arm/boot/zImage -avd Device_Test -qemu -gdb tcp::1234,ipv4, -S

    命令有误,修改如下:

    emulator -verbose -show-kernel -netfast -kernel ~/kernel/goldfish/arch/arm/boot/zImage -avd Device_Test -qemu -gdb tcp::1234,ipv4 -S

  3. Joen  说:

    你说的对, -netfast 和-kernel 要调换下顺序, 可能是我写文章的时候写错了!

  4. joen  说:

    今天为了研究linux的slub分配器.编译了um来调试.但是由于linux内核默认情况下使用-O2,而最低要求需要-O1才能编译成功.在打开优化的情况下,调试起来源代码会乱跳.为了解决这个问题,我折腾了几分钟.发现有三个地方需要修改就可以了

    第一处 include/linux/compiler-gcc.h 在里面inline __inline这些定义之后都有 aways_inline的attribute,要把这个属性删除

    另一处, 在menuconfig里,kernel hack里面不选中”Force gcc to inline functions marked inline”

    当然,最后,Makefile里面那个-O2要删除掉,也就是不用任何优化来编译(貌似这个时候就是-O0)

    之后用make ARCH=um 就可以编译成功了. 我精简过的um编译出来大概15M.(选择了compile the kernel with debug info)

  5. 老蜗牛  说:

    楼主你好,我是新手,按照你的步骤一步步进行内核调试。预装环境与文章一致,linux内核用的3.4,在进行eclipse内核调试时,提示no source available for “0x0”,且 在executables中没有init 的main函数。请问如何破解?


原文地址: http://www.joenchen.com/archives/1093

2014-04-09 08:42:50 loganyang123 阅读数 3881
Android依赖于Linux2.6内核提高的高核心系统服务,例如安全,内存管理,进程管理,网络斎等等方面内容。内核作为一个抽象层,存在与硬件层和软件层之间。android对Linux下面内容做了增强。 

  ①硬件时钟(alarm)

  ②内存分配与共享(Ashem)

  ③低内存管理(low memory killer)  

  ④kernel调试(kernel 调试)

  ⑤日志设备(LogCat)

  ⑥android IPC机制(Binder机制)

  ⑦电源管理(power management)

  这是Linux内核层的简介。相应思维导图如下:

2015-05-28 09:21:27 lxl584685501 阅读数 6410




二、android中bootimage的生成

0.linux VMLINUX 的生成

     vmlinux(vmlinuz)是一个包含linux kernel的静态链接的可执行文件,文件型态可能是linux接受的可执行文件格式之一(ELF、COFF或a.out)。vmlinux是未压缩的内核,vmlinux 是ELF文件,即编译出来的最原始的文件。

      下面以mtk6582分析为例子。

       (1).先看out下的文件:/home/tonylau/tony-workspace/new-v387/my-ap/out/target/product/xxxx(项目名称),

dd该目录下包含所有的手机文件镜像,如bootimage,systemimage等等,还有需要用到的obj(临时文件)

(2).然后进入obj,进一步查看:/home/tonylau/tony-workspace/new-v387/my-ap/out/target/product/xxxx(项目名称)/obj

      可以看出,该目录下包含生成(1)中各种image需要用到的临时文件,如app相关的,bootloader相关的,java相关的,kernel相关的(我们关心的是kernel相关的KERNEL_OBJ)

(3).在进入KERNEL_OBJ:/home/tonylau/tony-workspace/new-v387/my-ap/out/target/product//xxxx(项目名称)/obj/KERNEL_OBJ ====>>>>这是我们需要研究的编译vmlinux相关的地方。


====>>>>生成vmlinux:查看.vmlinux.cmd如下

【编译内核之后相应的文件会产生一个 .*.o.cmd的依赖文件, 据此文件可看出被编译的.o文件依赖的头文件,及被编译参数.

Linux Makefile通过在编译过程中生成的 .文件名.o.cmd(比如对于main.c文件,它对应的依赖文件名为.main.o.cmd)来定义相关的依赖关系。


(     依据arch/arm/kernel/vmlinux.lds 生成linux内核源码根目录下的vmlinux,这个vmlinux属于未压缩,带调试信息、符号表的最初的内核,大小约23MB;

      根据链接脚本vmlinux.lds 链接生成了arch/arm/boot/compressed/vmlinux 文件。

       /*在Build vmlinux小节的注释中,对vmlinux生成原理做了详尽的描述:

     vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE

       vmlinux是由$(vmlinux-init) 和$(vmlinux-main)指定的目标文件最终链接生成的。通常它们是位于各个子目录下的built_int.o目标文件,一些特殊名字的.o文件由arch/$(ARCH)/Makefile生成。

       目标文件.o链接为vmlinux的顺序是非常重要的,$(vmlinux-init)指定的目标文件优先级最高,接着是$(vmlinux-main),最后是kallsyms.o。于此同时System.map包含了内核所有的导出符号表。*/

)

        cmd_vmlinux := arm-linux-androideabi-ld.bfd -EL  -p --no-undefined -X --build-id -o vmlinux(目标文件) -T arch/arm/kernel/vmlinux.lds(依照文件)  arch/arm/kernel/head.o arch/arm/kernel/init_task.o mediatek/custom/out/kernel/built-in.o    xxx.o ...................(需要用到的各种o文件)

     可以看出vmlinux的生成依赖于arch/arm/kernel/head.o,arch/arm/kernel/init_task.o,以及其他子目录下的built-in.o。至于底层还需要什么文件也可以按图索骥了。

【PS】:vmlinux.lds:(初始化优先级)

__initcall_start = .;

*(.initcallearly.init) __initcall0_start = .;

*(.initcall0.init) *(.initcall0s.init) __initcall1_start = .;

*(.initcall1.init) *(.initcall1s.init) __initcall2_start = .;

*(.initcall2.init) *(.initcall2s.init) __initcall3_start = .;

*(.initcall3.init) *(.initcall3s.init) __initcall4_start = .;

*(.initcall4.init) *(.initcall4s.init) __initcall5_start = .;

*(.initcall5.init) *(.initcall5s.init) __initcallrootfs_start = .;

*(.initcallrootfs.init) *(.initcallrootfss.init) __initcall6_start = .;

*(.initcall6.init) *(.initcall6s.init) __initcall7_start = .;

*(.initcall7.init) *(.initcall7s.init) __initcall_end = .;



====>>>>生成mediatek/custom/out/kernel/built-in.o:查看.built-in.o.cmd如下,

       cmd_mediatek/custom/out/kernel/built-in.o :=  arm-linux-androideabi-ld.bfd -EL    -r -o mediatek/custom/out/kernel/built-in.o mediatek/custom/out/kernel/touchpanel/cyttsp4_mt_common.o mediatek/custom/out/kernel/touchpanel/cyttsp4_debug.o mediatek/custom/out/kernel/touchpanel/tpd_debug.o mediatek/custom/out/kernel/touchpanel/cyttsp4_i2c.o mediatek/custom/out/kernel/touchpanel/mtk_ttsp.o mediatek/custom/out/kernel/touchpanel/tpd_init.o mediatek/custom/out/kernel/touchpanel/cyttsp4_mtb.o mediatek/custom/out/kernel/touchpanel/cyttsp4_btn.o mediatek/custom/out/kernel/touchpanel/ft5206_driver.o(先编译) mediatek/custom/out/kernel/touchpanel/tpd_setting.o mediatek/custom/out/kernel/touchpanel/cyttsp4_core.o mediatek/custom/out/kernel/touchpanel/tpd_misc.o mediatek/custom/out/kernel/touchpanel/tpd_calibrate.o mediatek/custom/out/kernel/touchpanel/tpd_default.o mediatek/custom/out/kernel/touchpanel/focaltech_ctl.o mediatek/custom/out/kernel/touchpanel/cyttsp4_bus.o mediatek/custom/out/kernel/touchpanel/cyttsp4_loader.o mediatek/custom/out/kernel/touchpanel/tpd_button.o mediatek/custom/out/kernel/touchpanel/cyttsp4_device_access.o mediatek/custom/out/kernel/touchpanel/ft5x06_ex_fun.o mediatek/custom/out/kernel/touchpanel/mtk_tpd.o(后编译)  mediatek/custom/out/kernel/cam_cal/a5142otp.o mediatek/custom/out/kernel/lens/FM50AF.o mediatek/custom/out/kernel/lens/dummy_lens.o mediatek/custom/out/kernel/magnetometer/cust_mag.o mediatek/custom/out/kernel/magnetometer/lsm303m.o mediatek/custom/out/kernel/magnetometer/mag.o mediatek/custom/out/kernel/flashlight/sub_strobe_2ndPart_2.o mediatek/custom/out/kernel/flashlight/strobe_part_id.o mediatek/custom/out/kernel/flashlight/leds_strobe.o mediatek/custom/out/kernel/flashlight/sub_strobe.o mediatek/custom/out/kernel/flashlight/main_strobe_2ndPart_2.o mediatek/custom/out/kernel/flashlight/kd_flashlightlist.o mediatek/custom/out/kernel/kpd/mtk_kpd_bkl.o mediatek/custom/out/kernel/vibrator/cust_vibrator.o mediatek/custom/out/kernel/lcm/hx8394a_dsi_vdo.o mediatek/custom/out/kernel/lcm/mt65xx_lcm_list.o mediatek/custom/out/kernel/alsps/stk3x1x.o mediatek/custom/out/kernel/alsps/cust_alsps.o mediatek/custom/out/kernel/dct/pmic_drv.o mediatek/custom/out/kernel/core/board.o mediatek/custom/out/kernel/camera/kd_camera_hw.o mediatek/custom/out/kernel/camera/dummyds.o mediatek/custom/out/kernel/imgsensor/sp2529yuv_Sensor.o mediatek/custom/out/kernel/imgsensor/gc2235_Sensor.o mediatek/custom/out/kernel/imgsensor/kd_sensorlist.o mediatek/custom/out/kernel/imgsensor/ov8858mipiraw_Sensor.o mediatek/custom/out/kernel/eeprom/dummy_eeprom.o mediatek/custom/out/kernel/sound/yusu_android_speaker.o mediatek/custom/out/kernel/headset/accdet_custom.o mediatek/custom/out/kernel/ssw/sim_switch.o mediatek/custom/out/kernel/leds/cust_leds.o mediatek/custom/out/kernel/accelerometer/lsm303d.o mediatek/custom/out/kernel/accelerometer/cust_acc.o mediatek/custom/out/kernel/accelerometer/accel.o

可以看出:其实结果就是把“:=”右边对应目录下的文件编译好,连接成build-in.o文件


====>>>>生成mediatek/custom/out/kernel/touchpanel/ft5206_driver.o:查看.ft5206_driver.o.cmd如下


cmd_mediatek/custom/out/kernel/touchpanel/ft5206_driver.o := arm-linux-androideabi-gcc -Wp,-MD,mediatek/custom/out/kernel/touchpanel/.ft5206_driver.o.d  -nostdinc -isystem /home/tonylau/tony-workspace/new-v387/my-ap/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/../lib/gcc/arm-linux-androideabi/4.7/include   -I xxx(包含的头文件等等)  -c  -o  mediatek/custom/out/kernel/touchpanel/ft5206_driver.o    /home/tonylau/tony-workspace/new-v387/my-ap/kernel/mediatek/custom/out/kernel/touchpanel/ft5206_driver.c



1.linux 标准的zimage

该图来自 http://freeelectrons.com/docs/kernelinit

                  

2.android 中的bootimage

      在Android 产品中,内核格式是Linux标准的zImage根文件系统采用ramdisk格式。这两者在Android下是直接合并在一起取名为boot.img,会放在一个独立分区当中。这个分区格式是Android自行制定的格式。

      boot.img的格式比较简单,它主要分为三大块(有的可能有四块)

+—————–+
| boot header | 1 page
+—————–+
| kernel | n pages
+—————–+
| ramdisk | m pages
+—————–+
| second stage | o pages
+—————–+



n = (kernel_size + page_size – 1) / page_size
m = (ramdisk_size + page_size – 1) / page_size
o = (second_size + page_size – 1) / page_size

0. all entities are page_size aligned in flash
1. kernel and ramdisk are required (size != 0)
2. second is optional (second_size == 0 -> no second)


2016-12-22 20:12:47 CodeMyDream 阅读数 19696

1.Android系统层面的底层是Linux,并且在中间加上了一个叫做Dalvik的Java虚拟机,从表面层看是Android运行库。每个Android应用都运行在自己的进程上,享有Dalvik虚拟机为它分配的专有实例。为了支持多个虚拟机在同一设备上高效运行,dalvik被改写过。Dalvik虚拟机执行的是Dalvik格式的可执行文件(.dex)-该格式经过优化,以将内存好用降到最低。

Android内核和Linux内核的差别主要体现在如下11个方面:

1.Android Binder

    Android Binder是基于Openbinder框架的一个驱动,用于提供Android平台的进程间的通信(IPC)。原来的Linux系统上层应用的进程间通信主要是D-bus,采用消息总线的方式来进行IPC。其源代码位于drivers/staging/android/binder.c

2.Android电源管理(PM)

   Android电源管理是一个基于标准Linux电源管理系统的轻量级Andorid电源管理驱动,针对嵌入式设备做了很多优化。利用锁和定时器来切换系统状态,控制设备在不同状态下的功耗,以达到节能的目的。其源码位于kernel/power/earlysuspend.c  kernel/power/consoleearlysuspend.c  kernel/power/fbearysuspend.c kernel/power/wakelock.c kernel/power/userwakelock.c

3. 低内存管理器(Low memory Killer)

   Android中低内存管理器和linux标准的OOM相比,器机制更加灵活,可以根据需要杀死进程来释放需要的内存。Low memory Killer的代码非常简单,里面关键是函数Lowmem_shrinker().作为一个模块在初始化时调用register_shrike注册一个Lowmen_shriker,它会被vm在内存紧张的情况下调用。源码位于drivers/staging/android/lowmemorykiller.c

4.匿名共享内存(Ashmem)

  匿名共享内存为进程间提供大块共享内存,同时为内核提供回收和管理这个内存的机制。如果一个程序尝试访问Kernel释放的一个共享内存块,它将会受到一个错误提示,然后重新分配内存并重载数据。其源码位于mm/ashmem.c

5. Android PMEM(Phsical)

 PMEM用于向用户空间提供连续的物理内存区域,DSP和某些设备只能工作在连续的物理内存上。驱动中提供了mmap、open/release和ioctl等接口。

6.Android Logger

 Android Logger是一个轻量级的日志设备,用于抓取Android系统的各种日志,是Linux锁没有的

7.Android Alarm

 Android Alarm提供了一个定时器用于把设备从睡眠状态唤醒,同时它也提供了一个即使在设备睡眠是也会运行的时钟基准。其源码位于driver/rtc/alarm.c drivers/rtc/alarm-dev.c

8.USB Gadget驱动

 此驱动是一个具有标准Linux USB gadget驱动框架的设备驱动,Android的USB驱动是基于gadget框架的。其源码位于如下文件:

drivers/usb/gadget/android.c  drivers/usb/gadget/f_adb.c  drivers/usb/gadget/f_mass_storage.c

9.Android Ram Console

  为了提供调试功能,Android允许将调试日志信息写入一个被称为RAM Console的设备里,它是一个基于RAM的Buffer其源码位于drviers/staging/android/ram_console.c

10.Android timed device

  Android timed device提供了对设备进行定时控制功能,目前仅仅支持vibrator和LED设备。其源码为drviers/staging/adnroid/timed_output.c

11.Yaffs2文件系统

在Android系统中,采用Yaffs2作为MTD NAND FLASH文件系统。Yaffs2是一个快速稳定的应用于NAND和NOR FLash的跨平台的嵌入式设备文件性,同其他Flash文件系统相比,Yaffs2使用更小的内存来保存运行状态,因此它占用内存小;Yaffs2的垃圾回收非常简单而且快速,因此能够达到更好的性能;其源代码位于fs/yaffs2目录