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

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

相关文章

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

Windows环境利用VS2022编译 libvpx 源码教程

libvpx libvpx 是一个开源的视频编码库,由 WebM 项目开发和维护,专门用于 VP8 和 VP9 视频编码格式的编解码处理。它支持高质量的视频压缩,广泛应用于视频会议、在线教育、视频直播服务等多种场景中。libvpx 的特点包括跨平台兼容性、硬件加速支持以及灵活的接口设计,使其可以轻松集成到各种应用程序中。 libvpx 的安装和配置过程相对简单,用户可以从官方网站下载源代码

Golang test编译使用

创建文件my_test.go package testsimport "testing"func TestMy(t *testing.T) {t.Log("TestMy")} 通常用法: $ go test -v -run TestMy my_test.go=== RUN TestMyTestMy: my_test.go:6: TestMy--- PASS: TestMy (0.

Ubuntu22.04回退系统内核

文章目录 起因回退操作卸载内核禁止内核升级 起因 最近因为系统内核自动升级,导致显卡驱动检测不到,炼丹环境被破坏。无奈只能重装驱动,于是跟着手册操作发现驱动要求的是内核版本是5.15.0-25-generic,而我通过uname -r发现这时候的内核版本是6.8.0-40-generic,看来只能回退了。 我搜索了网上很多的文章,没有一篇文章能够完全解决这个问题,所以在我多次尝

C++/《C/C++程序编译流程》

程序的基本流程如图:   1.预处理        预处理相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。 读取C/C++源程序,对其中的伪指令(以#开头的指令)进行处理将所有的“#define”删除,并且展开所有的宏定义处理所有的条件编译指令,如:“#if”、“

跟我一起玩《linux内核设计的艺术》第1章(四)——from setup.s to head.s,这回一定让main滚出来!(已解封)

看到书上1.3的大标题,以为马上就要见着main了,其实啊,还早着呢,光看setup.s和head.s的代码量就知道,跟bootsect.s没有可比性,真多……这确实需要包括我在内的大家多一些耐心,相信见着main后,大家的信心和干劲会上一个台阶,加油! 既然上篇已经玩转gdb,接下来的讲解肯定是边调试边分析书上的内容,纯理论讲解其实我并不在行。 setup.s: 目标:争取把setup.