新人求教 如何移植高通821内核调教方案内核

ARM-Linux内核移植 - 内核启动流程分析_Linux教程_Linux公社-Linux系统门户网站
你好,游客
ARM-Linux内核移植
内核启动流程分析
来源:Linux社区&
作者: K-Style
内核版本:2.6.22& 为什么要采用这样一个较低的版本进行移植了,因为韦东山大牛说了,低版本的才能学到东西,越是高版本需要移植时做的工作量越少,学的东西越少。
内核启动分为三个阶段,第一是运行head.S文件和head-common.S,第三个阶段是允许第二是运行main.c文件
对于ARM的处理器,内核第一个启动的文件是arc/arm/kernel下面的head.S文件。当然arc/arm/boot/compress下面也有这个文件,这个文件和上面的文件略有不同,当要生成压缩的内核时zImage时,启动的是后者,后者与前者不同的时,它前面的代码是做自解压的,后面的代码都相同。我们这里这分析arc/arm/kernel下面的head.S文件。当head.S所作的工作完成后它会跳到init/目录下跌的main.c的start_kernel函数开始执行。
第一阶段:
首先截取部分head.S文件
ENTRY(stext)
&&&&&& msr& cpsr_c,#PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @ andirqs disabled
&&&&&& mrc& p15,0, r9, c0, c0&&&&&&&&&& @ get processor id
&&&&&& bl&&& __lookup_processor_type&&&&&&&&&&&& @ r5=procinfo r9=cpuid
&&&&&& movs&&&&&& r10,r5&&&&&&&&&&&&&&&&&&&&&&&& @ invalidprocessor (r5=0)?
&&&&&& beq& __error_p&&&&&&&&&&&&&&&&&&&& @ yes, error 'p'
&&&&&& bl&&& __lookup_machine_type&&&&&&& @ r5=machinfo
&&&&&& movs&&&&&& r8,r5&&&&&&&&&&&&&&&&&&&&&&&&&& @ invalidmachine (r5=0)?
&&&&&& beq& __error_a&&&&&&&&&&&&&&&&&&&& @ yes, error 'a'
&&&&&& bl&&& __create_page_tables
&&&&&& &*The following calls CPU specific code in a position independent
&&&&&& &*manner.& See arch/arm/mm/proc-*.S fordetails.& r10 = base of
&&&&&& &*xxx_proc_info structure selected by __lookup_machine_type
&&&&&& &*above.& On return, the CPU will be readyfor the MMU to be
&&&&&& &*turned on, and r0 will hold the CPU control register value.
&&&&&& &*/
&&&&&& ldr&& r13,__switch_data&&&&&&& @ address to jump toafter
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& @ mmuhas been enabled
&&&&&& adr&& lr,__enable_mmu&&&&&&&&& @ return (PIC)address
第一步,执行的是__lookup_processor_type,这个函数是检查处理器型号,它读取你的电路板的CPU型号与内核支持的处理器进行比较看是否能够处理。这个我们不关心它的具体实现过程,因为现在主流处理器内核都提供了支持。
&&&&&& 第二步,执行的是__lookup_machine_type,这个函数是来检查机器型号的,它会读取你bootloader传进来的机器ID和他能够处理的机器ID进行比较看是否能够处理。内核的ID号定义在arc/arm/tool/mach_types文件中MACH_TYPE_xxxx宏定义。内核究竟就如何检查是否是它支持的机器的呢?实际上每个机器都会在/arc/arm/mach-xxxx/smdk-xxxx.c文件中有个描述特定机器的数据结构,如下
MACHINE_START(S3C2440,"SMDK2440")&&
&&&&&&&/*&Maintainer:&Ben&Dooks@fluff.org&*/&&
&&&&&&&.phys_io&&=S3C2410_PA_UART,&&
&&&&&&&.io_pg_offst&&&&=&(((u32)S3C24XX_VA_UART)&&18)&&&0xfffc,&&
&&&&&&&.boot_params&&=&S3C2410_SDRAM_PA&+&0x100,&&
&&&&&&&.init_irq&&&=s3c24xx_init_irq,&&
&&&&&&&.map_io&&&&&&&&&&=smdk2440_map_io,&&
&&&&&&&.init_machine&&=&smdk2440_machine_init,&&
&&&&&&&.timer&&&&&&&&&&&&&=&s3c24xx_timer,&&
MACHINE_END&&
MACHINE_START和 MACHINE_END实际上被展开成一个结构体
#defineMACHINE_START(_type,_name)&&&&&&&&&&&&&&&&&\&&
staticconst&struct&machine_desc&__mach_desc_##_type&&&&&&&\&&
&__used&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\&&
&__attribute__((__section__(".arch.info.init")))=&{&&&&\&&
&&&&&&&.nr&&&&&&&&&&=MACH_TYPE_##_type,&&&&&&&&&&&\&&
&&&&&&&.name&&&&&&&&&&&&&=_name,&&
#defineMACHINE_END&&&&&&&&&&&&&&&&&&&&&&&&&&\&&
于是上面的数据结构就被展开为
staticconst&struct&machine_desc&__mach_desc_S3C2440&&&&&\&&
&__used&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\&&
&__attribute__((__section__(".arch.info.init")))=&{&&&&\&&
&&&&&&&.nr&&&&&&&&&&=MACH_TYPE_S3C2440,&&&&&&&&&&\&&
&&&&&&&.name&&&&&&&&&&&&&=”SMDK2440”,};&&
.phys_io&&=&S3C2410_PA_UART,&&
&&&&&&&.io_pg_offst&&&&=&(((u32)S3C24XX_VA_UART)&&18)&&&0xfffc,&&
&&&&&&&.boot_params&&=&S3C2410_SDRAM_PA&+&0x100,&&
&&&&&&&.init_irq&&&=s3c24xx_init_irq,&&
&&&&&&&.map_io&&&&&&&&&&=smdk2440_map_io,&&
&&&&&&&.init_machine&&=&smdk2440_machine_init,&&
&&&&&&&.timer&&&&&&&&&&&&&=&s3c24xx_timer,&&
每个机器都会有一个machine_desc__mach_desc结构,内核通过检查每个machine_desc__mach_desc的nr号和bootloader传上来的ID进行比较,如果相同,内核就认为支持该机器,而且内核在后面的工作中会调用该机器的machine_desc__mach_desc_结构中的方法进行一些初始化工作。
&&&&&& 第三步,创建一级页表。
&&&&&& 第四步,在R13中保存__switch_data 这个函数的地址,在第四步使能mmu完成后会跳到该函数执行。
第五步,执行的是__enable_mmu,它是使能MMU,这个函数调用了__turn_mmu_on函数,让后在_turn_mmu_on在最后将第三步赋给R13的值传给了PC指针 (mov&&& pc, r13),于是内核开始跳到__switch_data这个函数开始执行。
再来看arch/arm/kenel/head-common.S这个文件中的__switch_data函数
__switch_data:&&
&&&&&&&.long&&&&&&&__mmap_switched&&
&&&&&&&.long&&&&&&&__data_loc&&&&&&&&&&&&&&&&&&&&@&r4&&
&&&&&&&.long&&&&&&&__data_start&&&&&&&&&&&&&&&&&&@&r5&&
&&&&&&&.long&&&&&&&__bss_start&&&&&&&&&&&&&&&&&&&&@&r6&&
&&&&&&&.long&&&&&&&_end&&&&&&&&&&&&&&&&&&&&&&&&&&&&@&r7&&
&&&&&&&.long&&&&&&&processor_id&&&&&&&&&&&&&&&&&@&r4&&
&&&&&&&.long&&&&&&&__machine_arch_type&&&&&&&&&&&@&r5&&
&&&&&&&.long&&&&&&&cr_alignment&&&&&&&&&&&&&&&&&@&r6&&
&&&&&&&.long&&&&&&&init_thread_union+&THREAD_START_SP&@&sp&&
&*&The&following&fragment&of&code&is&executedwith&the&MMU&on&in&MMU&mode,&&
&*&and&uses&absolute&&this&is&notposition&independent.&&
&*&&r0&&=cp#15&control&register&&
&*&r1&&=&machine&ID&&
&*&r9&&=&processor&ID&&
&&&&&&&.type&&&&&&&__mmap_switched,%function&&
__mmap_switched:&&
&&&&&&&adr&&&r3,__switch_data&+&4&&
&&&&&&&ldmia&&&&&&r3!,{r4,&r5,&r6,&r7}&&
&&&&&&&cmp&r4,r5&&&&&&&&&&&&&&&&&&&&&&&&&&&@&Copy&datasegment&if&needed&&
1:&&&&cmpne&&&&&r5,r6&&
&&&&&&&ldrne&&&&&&&fp,[r4],&#4&&
&&&&&&&strne&&&&&&&fp,[r5],&#4&&
&&&&&&&bne&&1b&&
&&&&&&&mov&fp,#0&&&&&&&&&&&&&&&&&&&&&&&&&&&@&Clear&BSS(and&zero&fp)&&
1:&&&&cmp&r6,r7&&
&&&&&&&strcc&fp,[r6],#4&&
&&&&&&&bcc&&1b&&
&&&&&&&ldmia&&&&&&r3,{r4,&r5,&r6,&sp}&&
&&&&&&&str&&&&r9,&[r4]&&&&&&&&&&&&&&&&&&@&Save&processor&ID&&
&&&&&&&str&&&&r1,&[r5]&&&&&&&&&&&&&&&&&&@&Save&machine&type&&
&&&&&&&bic&&&r4,r0,&#CR_A&&&&&&&&&&&&&&&@&Clear&'A'&bit&&
&&&&&&&stmia&&&&&&&r6,{r0,&r4}&&&&&&&&&&&&&&&&&&&@&Save&controlregister&values&&
&&&&&&&b&&&&&start_kernel&&
这个函数做的工作是,复制数据段清楚BBS段,设置堆在指针,然后保存处理器内核和机器内核等工作,最后跳到start_kernel函数。于是内核开始执行第二阶段。
第二阶段:&
我们再来看init/目录下的main.c的start_kernel函数,这里我只截图了部分。
asmlinkage&void&__init&start_kernel(void)&&
&&&&&&&…………………….&&
&&&&&&&……………………..&&
&&&&&&&printk(KERN_NOTICE);&&
&&&&&&&printk(linux_banner);&&
&&&&&&&setup_arch(&command_line);&&
&&&&&&&setup_command_line(command_line);&&
&&&&&&&parse_early_param();&&
&&&&&&&parse_args("Booting&kernel",static_command_line,&__start___param,&&
&&&&&&&&&&&&&&&&__stop___param&-&__start___param,&&
&&&&&&&&&&&&&&&&&unknown_bootoption);&&
……………………&&
…………………………&&&&&&&&
&&&&&&&init_IRQ();&&
&&&&&&&pidhash_init();&&
&&&&&&&init_timers();&&
&&&&&&&hrtimers_init();&&
&&&&&&&softirq_init();&&
&&&&&&&timekeeping_init();&&
&&&&&&&time_init();&&
&&&&&&&profile_init();&&
…………………………&&
……………………………&&
&&&&&&&console_init();&&
………………………………&&
………………………………&&
&&&&&&&rest_init();&&
从上面可以看出start_kernel首先是打印内核信息,然后对bootloader传进来的一些参数进行处理,再接着执行各种各样的初始化,在这其中会初始化控制台。最后会调用rest_init();
我们再来看rest_init()函数
static&void&noinline&__init_refok&rest_init(void)&&
&&&&__releases(kernel_lock)&&
&&&&int&&&
&&&&kernel_thread(kernel_init,&NULL,&CLONE_FS&|&CLONE_SIGHAND);&&
&&&&............&&&&&&
他启动了kernel_init这个函数,再来看kerne_init函数
static&int&__init&kernel_init(void&*&unused)&&
&&&&..............................&&
&&&&if&(!ramdisk_execute_command)&&
&&&&&&&&ramdisk_execute_command&=&"/init";&&
&&&&if&(sys_access((const&char&__user&*)&ramdisk_execute_command,&0)&!=&0)&{&&
&&&&&&&&ramdisk_execute_command&=&NULL;&&
&&&&&&&&prepare_namespace();&&
&&&&&*&Ok,&we&have&completed&the&initial&bootup,&and&&
&&&&&*&we're&essentially&up&and&running.&Get&rid&of&the&&
&&&&&*&initmem&segments&and&start&the&user-mode&stuff..&&
&&&&init_post();&&
&&&&return&0;&&
kernel_init先调用了prepare_namespace();然后调用了init_post函数
void&__init&prepare_namespace(void)&&
&&&&..........................&&
&&&&mount_root();&&
&&&&.....................&&
可以看出prepare_namespace调用了mount_root挂接根文件系统。接着kernel_init再执行init_post
static&int&noinline&init_post(void)&&
&&&&.......................................&&
&&&&/*打开dev/console控制台,并设置为标准输入、输出*/&&
&&&&&&&&&&
&&&&if&(sys_open((const&char&__user&*)&"/dev/console",&O_RDWR,&0)&&)&&
&&&&&&&&printk(KERN_WARNING&"Warning:&unable&to&open&an&initial&console.\n");&&
&&&&(void)&sys_dup(0);&&
&&&&(void)&sys_dup(0);&&
&&&&if&(ramdisk_execute_command)&{&&
&&&&&&&&run_init_process(ramdisk_execute_command);&&
&&&&&&&&printk(KERN_WARNING&"Failed&to&execute&%s\n",&&
&&&&&&&&&&&&&&&&ramdisk_execute_command);&&
&&&&&*&We&try&each&of&these&until&one&succeeds.&&
&&&&&*&The&Bourne&shell&can&be&used&instead&of&init&if&we&are&&
&&&&&*&trying&to&recover&a&really&broken&machine.&&
&&&&//如果bootloader指定了init参数,则启动init参数指定的进程&&
&&&&if&(execute_command)&{&&
&&&&&&&&run_init_process(execute_command);&&
&&&&&&&&printk(KERN_WARNING&"Failed&to&execute&%s.&&Attempting&"&&
&&&&&&&&&&&&&&&&&&&&"defaults...\n",&execute_command);&&
&&&&//如果没有指定init参数,则分别带sbin、etc、bin目录下启动init进程&&
&&&&run_init_process("/sbin/init");&&
&&&&run_init_process("/etc/init");&&
&&&&run_init_process("/bin/init");&&
&&&&run_init_process("/bin/sh");&&
&&&&panic("No&init&found.&&Try&passing&init=&option&to&kernel.");&&
注意上面的run_init_process的会等待init进程返回才往后面执行,所有它一旦找到一个init可执行的文件它将一去不复返。
综上,内核启动的过程大致为以下几步:
1.检查CPU和机器类型
2.进行堆栈、MMU等其他程序运行关键的东西进行初始化
3.打印内核信息
4.执行各种模块的初始化
5.挂接根文件系统
6.启动第一个init进程
【内容导航】
相关资讯 & & &
& (03/29/:57)
& (04/22/:32)
& (03/29/:26)
& (03/29/:50)
& (11/09/:59)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款经验2080 米
在线时间458 小时
版本8.3.29
机型红米Note 3-全网通版
签到次数144
MIUI版本8.3.29
}; [+ O$ Z: B5 k
内核编辑与修改,如何移植内核的全面教程
& && & 和标准的Linux开发流程一样,Android平台开发的一个很重要的基础工作就是对其内核的编译和移植。本文结合Android的开发文档以及本人的实践经验,简单介绍了Android内核的编译过程,希望有助于对内核移植感兴趣的开发人员。
 & & Android作为Google公司推出的一款手机开发平台,其本身是基于linux内核的。Google提供的内核源代码中除了linux部分外,有很大一部分是与虚拟处理器Qemu和模拟硬件平台Goldfish相关的。所以如果想将Android移植到实际的硬件平台上需要将这部分代码剥离出来。当然这不是这篇文章的重点,我们现在的目的是要编译出一个可以在模拟器上运行的系统内核
那么,现在就开始我们的工作吧!! o2 J, j&&R2 g# I2 [
2 t5 B/ w/ b& O
本帖隐藏的内容
工作环境及所需软件包系统环境:Redhat Linux 9.0交叉编译器:GNU Toolchain for ARM Processors下载地址:http://www.codesourcery.com/gnu_toolchains/arm/download.htm
l其中第一项选择ARM EABI或ARM GNU/Linux,第二项选择IA32 GNU/Linux即可。 此主题相关图片如下:6 R* y# a+ _/ M% _/ s6 V
+ o&&R5 |' O3 n0 U6 n9 T: [$ Y
! P( R6 E, N0 N& _. X: `$ j
Android内核源代码:linux-2.6.23-android-m5-rc14.tar.gz 下载地址http://code.google.com/p/android/downloads/list注意该内核版本要与你选用的模拟器版本尽量一致。 此主题相关图片如下:$ a% B0 e&&D! O( |$ N
: c0 [9 x9 M* {
Android SDK 下载地址:http://code.google.com/android/download_list.html此主题相关图片如下:# @0 D+ v8 e4 R, z
8 M&&y' _7 l. v
1.搭建交叉编译环境& && & 1) 安装Android SDK: 将android-sdk_m5-rc14_linux-x86.zip解压缩到适当路径下即可使用。本文将其释放至/usr/local/android_sdk_linux路径下,并将其tools路径添加到PATH中$ export PATH=$PATH:/usr/local/android_sdk_linux/tools  2) 安装交叉编译器:将arm--arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 解压缩至/usr/local/arm-2007q3目录下,并将其bin路径添加到PATH中:  $ export PATH=$PATH:/usr/local/arm-2007q3/bin 此主题相关图片如下:; O% h2 h4 p# y5 s6 O
' u% ^3 l5 l8 J6 ?& n' P- U
 3) 解压缩内核源代码:将linux-2.6.23-android-m5-rc14.tar.gz解压缩,得到kernel文件夹,本文中将其放置在/Android目录下。2.获取内核编译配置文件  交叉编译环境搭建好后需要得到android的内核编译参数的配置文件,该文件需要从android sdk 中的模拟器中得到。启动android模拟器,然后通过adb得到模拟器中提供的内核配置文件:   $emulator &   $adb pull /proc/config.gz   这时候adb工具会连接模拟器,并从它里面下载一个叫做config.gz的文件到你的当前目录下。将其移动至kernel目录,解压该文件得到config,将其重命名为.config,这样就可以跳过make config而直接得到Makefile所需要的内核配置文件。  $ gunzip config.gz  $ mv config .config 此主题相关图片如下:
, T&&Y) u, Z) ~
) r5 G$ d+ [9 M; ~8 ^& M% W; S6 X
3.修改Makefile  首先修改第187行,将CROSS_COMPILE值改为arm-none-linux-gnueabi-,这是我们安装的交叉编译工具链的前缀,修改此处意在告诉make在编译的时候要使用该工具链。 此主题相关图片如下:% b% K0 F9 _; K
& t/ V+ Q2 G0 K2 X/ H8 j
然后修改第519、520行,将build id 值注释掉,因为目前版本的android内核不支持该选项。此主题相关图片如下:- {( s/ w' I9 C
4.开始编译  在kernel目录下执行make:   $ make  除个别警告外编译过程一切顺利,最终在/kernel/arch/arm/boot目录下面生成一个zImage,即为编译好的内核镜像了。此主题相关图片如下:
/ Q7 C& @% J1 Z1 X) S. l
4 W0 G+ }' H. E. B+ Y
此主题相关图片如下:! f$ u$ n+ s) ^! k9 z
5.运行该镜像  $emulator -kernel ~/android/kernel/arch/arm/boot/zImage  最终效果如图所示:
教程结束,希望你们能制作属于自己的省电的,强大的内核!!!!!!
分享到微信朋友圈
打开微信,点击底部的“发现”,使用 “扫一扫” 即可将网页分享到我的朋友圈。
经验1277 米
在线时间156 小时
积分 1587, 距离下一级还需 413 积分
积分 1587, 距离下一级还需 413 积分
机型努比亚Z7 mini
签到次数34
MIUI版本5.6.5
通过手机发布
干扰码都不去。。。
经验499 米
在线时间143 小时
版本3.2.22
积分 670, 距离下一级还需 1330 积分
积分 670, 距离下一级还需 1330 积分
机型中兴 U930
签到次数12
MIUI版本3.2.22
经验1227 米
在线时间139 小时
版本6.5.27
积分 1528, 距离下一级还需 472 积分
积分 1528, 距离下一级还需 472 积分
机型努比亚Z5S
签到次数42
MIUI版本6.5.27
膜拜& && && && && && && &&&
经验15321 米
在线时间394 小时
版本8.4.26
机型小米手机5
签到次数155
MIUI版本8.4.26
通过手机发布
这么简单??????
在线时间2 小时
版本4.4.25
积分 37, 距离下一级还需 13 积分
积分 37, 距离下一级还需 13 积分
机型MOTO mb886
MIUI版本4.4.25
通过手机发布
求大神移植mb886的3.4内核!
在线时间3 小时
积分 33, 距离下一级还需 17 积分
积分 33, 距离下一级还需 17 积分
顶酒酒酒酒酒酒酒酒酒酒
在线时间0 小时
积分 27, 距离下一级还需 23 积分
积分 27, 距离下一级还需 23 积分
经验3601 米
在线时间30 小时
积分 4241, 距离下一级还需 759 积分
积分 4241, 距离下一级还需 759 积分
机型小米手机1/1S
签到次数35
MIUI版本8.3.6
MIUI 9纪念勋章
已关注微信
关注腾讯微博
已关注腾讯微博
关注新浪微博
已关注新浪微博
MIUI 3000万
MIUI 3000万发烧友纪念勋章
MIUI 2000万
MIUI 2000万发烧友纪念勋章
1000万用户纪念勋章
MIUI1000万用户纪念勋章
2018新年勋章
参与回帖活动
2017圣诞节勋章
参与回帖活动
全局搜索纪念勋章
参加全局搜索内测
MIUI3亿用户纪念勋章
参与回帖活动
感恩节勋章
参与回帖活动
万圣节勋章
参加回帖活动
米兔月饼勋章
参加回帖活动
MIUI七周年
新版论坛APP
更新新版APP
小米7周年勋章
2017米粉节晒单赢专属勋章
“澎湃S1 ”芯片纪念勋章
参与活动回帖可得
参与红米Note 4X活动
APP 1000万
MIUI论坛APP注册用户突破1000万纪念勋章
MIUI 300周
MIUI 300周更新纪念勋章
MIUI三周年
MIUI三周年纪念勋章
MIUI六周年
MIUI六周年纪念勋章
MIUI七夕鹊桥勋章
Copyright (C) 2017 MIUI
京ICP备号 | 京公网安备34号 | 京ICP证110507号新人求教 关于手机rom的移植 求大神教教
万分感谢【酷派7295吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:8,546贴子:
新人求教 关于手机rom的移植 求大神教教
万分感谢收藏
同求╮  » » »楼主肚子饿了!    » » »不要紧…  » » »我下面给他吃! 
点亮12星座印记,
我也想学╮  » » »楼主肚子饿了!    » » »不要紧…  » » »我下面给他吃! 
点亮12星座印记,
欢迎加入小白rom移植交流群,群号码:
应用吧活动,
登录百度帐号Android高通boot移植怎么弄,真心求来个会的。_百度知道
Android高通boot移植怎么弄,真心求来个会的。
我有更好的答案
你回答了么
为您推荐:
其他类似问题
不记名的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 高通内核boot.img移植 的文章

 

随机推荐