安卓篇--模拟器加载自己编译的内核

2023-11-07 10:48

本文主要是介绍安卓篇--模拟器加载自己编译的内核,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 下载Android 模拟器所用的内核源码, 代号为goldfish  

2. 下载arm-Linux交叉工具链

3. 编译内核文件

4. 让android模拟器运行在刚编译的内核上

5. 编译自己的hello内核模块

6 将hello.ko载入到内核中


1. 下载android 模拟器所用的内核源码, 代号为goldfish  

(goldfish内核是专为android模拟器使用的)

ps:假设我们在~/android-kernel目录下下载android内核文件

$mkdir android-kernel   #创建此目录

$cd android-kernel

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

$cd goldfish

$git branch -a #查看全部的版本


git checkout remotes/origin/android-goldfish-2.6.29

git checkout -b master建立自己工作分支

此时目录下已经可以看到kernel代码了。


2. 下载arm-linux交叉工具链

(ps: 假设工具链的目录为: ~/android-toolchain/)

$mkdir ~/android-toolchain

$cd ~/android-toolchain

$git clone https://android.googlesource.com/platform/prebuilt   #这一步,要下载近1.8GB。


然后将此路径加入PATH变量中, 修改~/.bashrc文件

在最后一行加入:

export PATH=/home/snail/android/android-toolchain/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH


生效:

source ~/.bashrc


到此arm-linux交叉编译工具链就弄好了。


3. 编译内核文件

ps: 为了让内核文件支持动态加载和卸载.ko模块,请大家按下面的步骤进行

$cd ~/android-kernel/goldfish

$export ARCH=arm

$export SUBARCH=arm

$export CROSS_COMPILE=arm-eabi-      #前面已经将路径加入到PATH变量中了

$make goldfish_defconfig


[Android4.1以上平台需要进行如下配置]

$make goldfish_armv7_defconfig


为了支持动态加载和卸载ko模块,否则请跳过。

$make menuconfig  #这步可能会提示缺少个什么库 , 用sudo apt-get install libxxx安装 (多按Tab补全)

然后请把Enable loadable module support项按y选上

然后按回车进入选上三项,如图:





下面开始编译内核

$make -j8    #-j8表示并行编译数,即8个进程并行编译,更快

到此支持loadable 的内核编译完成 ,  编译后的内核为 ./arch/arm/boot/zImage


4. 让android模拟器运行在刚编译的内核上

4.1 打开eclipse -> window -> AVD manager 新建一个模拟器,比如名叫android4.2    (此步的前提是你已经装好了android开发环境)

4.2 使用自己的内核运行

(假设你的android sdk已经安装 , 这里使用 ANDROID_SDK表示android sdk安装目录)

$   $ANDROID_SDK/tools/emulator -avd android4.2 -kernel ~/android-kernel/goldfish/arch/arm/boot/zImage -show-kernel 

到此运行成功!



5. 编译自己的hello内核模块

位置:

在driver/char/下建立yf-hello文件夹

在yf-hello文件夹下建立hello.c

[cpp] view plain copy
print ?
  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3.   
  4. static int __init hello_init(void)  
  5. {  
  6.     printk(KERN_ERR "Hello world\n");  
  7.     return 0;  
  8. }  
  9.   
  10. static void __exit hello_exit(void)  
  11. {  
  12.     printk(KERN_ERR "exit\n");  
  13. }  
  14.   
  15. MODULE_LICENSE("GPL");  
  16. module_init(hello_init);  
  17. module_exit(hello_exit);  
#include <linux/module.h>
#include <linux/init.h>static int __init hello_init(void)
{printk(KERN_ERR "Hello world\n");return 0;
}static void __exit hello_exit(void)
{printk(KERN_ERR "exit\n");
}MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);

 Makefile

[cpp] view plain copy
print ?
  1. obj-y := hello.o  
obj-y := hello.o

在driver/char下,编辑Makefile

加入

[cpp] view plain copy
print ?
  1. obj-y   += yf-hello/  
obj-y	+= yf-hello/

重新编译内核可直接将hello模块编译到内核,启动后可以看到。



说明模块加载成功。


6.动态加载hello.ko

Makefile

[cpp] view plain copy
print ?
  1. obj-m := hello-yf.o        
  2. hello-yf-objs := hello.o       
  3.         
  4. KID :=~/android/android-kernel/goldfish  
  5. PWD := $(shell pwd)  
  6. ARCH=arm    
  7. CROSS_COMPILE=arm-eabi-  
  8. CC=$(CROSS_COMPILE)gcc  
  9. LD=$(CROSS_COMPILE)ld     
  10.         
  11. all:  
  12.     make -C $(KID) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=${PWD} modules  
  13.         
  14. clean:  
  15.     rm -rf *.o .cmd *.ko *.mod.c .tmp_versions  
obj-m := hello-yf.o      
hello-yf-objs := hello.o     KID :=~/android/android-kernel/goldfish
PWD := $(shell pwd)
ARCH=arm  
CROSS_COMPILE=arm-eabi-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld   all:make -C $(KID) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=${PWD} modulesclean:rm -rf *.o .cmd *.ko *.mod.c .tmp_versions

make后,将hello-yf.ko 

用adb push放入



cat /proc/kmsg




这篇关于安卓篇--模拟器加载自己编译的内核的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/363113

相关文章

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

在 PyQt 加载 UI 三种常见方法

《在PyQt加载UI三种常见方法》在PyQt中,加载UI文件通常指的是使用QtDesigner设计的.ui文件,并将其转换为Python代码,以便在PyQt应用程序中使用,这篇文章给大家介绍在... 目录方法一:使用 uic 模块动态加载 (不推荐用于大型项目)方法二:将 UI 文件编译为 python 模

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

idea maven编译报错Java heap space的解决方法

《ideamaven编译报错Javaheapspace的解决方法》这篇文章主要为大家详细介绍了ideamaven编译报错Javaheapspace的相关解决方法,文中的示例代码讲解详细,感兴趣的... 目录1.增加 Maven 编译的堆内存2. 增加 IntelliJ IDEA 的堆内存3. 优化 Mave

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio