基于android2.3.5系统:开天辟地Android启动机制[四]

来源:互联网 发布:2011网络歌曲排行榜 编辑:程序博客网 时间:2024/05/23 22:28

***************************************************************************************************************************
作者:EasyWave                                                                                 时间:2013.02.08

类别:Android系统源码分析                                                              声明:转载,请保留链接

注意:如有错误,欢迎指正。这些是我学习的日志文章......

***************************************************************************************************************************

在我的博文基于android2.3.5学习之:开天辟地Android启动机制[三]中,详细的介绍了ueventd的解析机制,在分析andriod2.3.5中的action_list、action_queue、service_list,之前,还是先来详细介绍在Andriod是如何调用内核中的一些函数,比如:chown以及chroot等等。Andriod中的三大链表如下图所示:

详细的介绍,将留在后面的文章中详细解释,因为,在这之前,需要先了解下linux中的syscall,就是系统调用。以chown命令为例,详细的解析Android中是如何执行chown这个命令的,在system/core/init/keywords.h中,我们可以看到如下的定义:

这里只分析红色圈中的部分,其他部分的代码,请自行分析,都是大同小异啦。进入do_chown函数中,可以看到如下的代码(在/system/core/init/Builtins.c):

进入深入进去发现chown是调用bionic\libc\arch-arm\syscalls下的chown.s文件,当然如果是其它的平台,那么路径是不一样的,这里只讨论ARM架构下的代码,如下图所示:

看到了吗,最终是调用__NR_chown32这个标号指定的函数地址,它是在哪里调用的呢,我们可以从上面的#include <sys/linux-syscalls.h>中找到答案。如下代码:

/* auto-generated by gensyscalls.py, do not touch */#ifndef _BIONIC_LINUX_SYSCALLS_H_#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__  #  define __NR_SYSCALL_BASE  0x900000  #else  #  define  __NR_SYSCALL_BASE  0  #endif#define __NR_exit                         (__NR_SYSCALL_BASE + 1)#define __NR_fork                         (__NR_SYSCALL_BASE + 2)#define __NR_clone                        (__NR_SYSCALL_BASE + 120)......#define __NR_chown32                      (__NR_SYSCALL_BASE + 212)#define __NR_lchown32                     (__NR_SYSCALL_BASE + 198)......#ifdef __arm__#define __NR_exit_group                   (__NR_SYSCALL_BASE + 248)#define __NR_waitid                       (__NR_SYSCALL_BASE + 280)#define __NR_vfork                        (__NR_SYSCALL_BASE + 190)#define __NR_openat                       (__NR_SYSCALL_BASE + 322)......#define __NR_ARM_set_tls                  (__NR_SYSCALL_BASE + 983045)#define __NR_ARM_cacheflush               (__NR_SYSCALL_BASE + 983042)#endif#endif#endif /* _BIONIC_LINUX_SYSCALLS_H_

从上面的代码中,我们看到#define __NR_chown32                      (__NR_SYSCALL_BASE + 212) 这行代码,不错,这个就是我们需要了解的。

在bionic\libc\kernel\arch-arm\asm中的Unistd.h文件中,我们也可以看到如下的代码,注意,这个是linux内核相关的。如下所示:

红色圈中的部分,看出来什么名堂没有呢,当然它们都是指向__NR_SYSCALL_BASE + 212 这个偏移地址,而在linux系统中定义如下(arch\arm\include\asm\Unistd.h):

看到了吗,上面红色圈中的部分的定义是跟Andriod中的定义是一样的,都是:#define __NR_chown32   (__NR_SYSCALL_BASE+212) 这个偏移地址。我们再来看看syscall调用的定义是在哪里的呢。最终调用的是:arch\arm\kernel\entry-common.S下的syscall函数,如下图所示:

同时syscall的函数代码如下所示:

最终会将#include "calls.S"文件加入进来,而calls.S文件主要是定义了一个sys_call_table表格而已,如下所示:

/* *  linux/arch/arm/kernel/calls.S * *  Copyright (C) 1995-2005 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  This file is included thrice in entry-common.S *//* 0 */CALL(sys_restart_syscall)CALL(sys_exit)CALL(sys_fork_wrapper)CALL(sys_read)CALL(sys_write)/* 5 */CALL(sys_open)CALL(sys_close)CALL(sys_ni_syscall)/* was sys_waitpid */CALL(sys_creat)CALL(sys_link)....../* 210 */CALL(sys_setresgid)CALL(sys_getresgid)CALL(sys_chown) //212 : 调用sys_chown函数CALL(sys_setuid)CALL(sys_setgid)....../* 300 */CALL(sys_semctl)CALL(sys_msgsnd)CALL(sys_msgrcv)CALL(sys_msgget)CALL(sys_msgctl)/* 305 */CALL(sys_shmat)CALL(sys_shmdt)CALL(sys_shmget)CALL(sys_shmctl)CALL(sys_add_key)/* 310 */CALL(sys_request_key)CALL(sys_keyctl)CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))/* vserver */CALL(sys_ni_syscall)CALL(sys_ioprio_set)/* 315 */CALL(sys_ioprio_get)CALL(sys_inotify_init)CALL(sys_inotify_add_watch)CALL(sys_inotify_rm_watch)CALL(sys_mbind)/* 320 */CALL(sys_get_mempolicy)CALL(sys_set_mempolicy)CALL(sys_openat)CALL(sys_mkdirat)CALL(sys_mknodat)......CALL(sys_preadv)CALL(sys_pwritev)CALL(sys_rt_tgsigqueueinfo)CALL(sys_perf_event_open)/* 365 */CALL(sys_recvmmsg)#ifndef syscalls_counted.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls#define syscalls_counted#endif.rept syscalls_paddingCALL(sys_ni_syscall).endr 

       至此,我们了解了Anriod系统中的chown命令是通过syscall来调用linux内核中的系统函数chown函数,现在应该明白了吧,其他的命令基本一致,其实在busybox中也是采用内似的方法来做的。具体关于syscall的调用方法,可以到网络上去搜索,我这里就不详细的解释了。

 

原创粉丝点击