几行代码演示linux kernel、libc、userSpace app的关系

news2024/11/15 13:52:28

问一:编译出来的Linux内核镜像(".\build\arch\arm64\boot\Image"),可以单独运行吗?
答案是能,但是加载完就提示panic,然后死掉了。

原因是:
内核代码加载完后,一定要切换到低权限模式运行,
内核是设计来为 运行于低CPU权限的 "userSpace app" 服务的。
 

内核切换到低权限模式去运行的方式,就是去运行一个普通程序——用户态的可执行文件。
        注意了,这是必须的!
 

用户态的可执行文件,下文称为 userapp

问二:内核加载完成后,去哪找这个userapp?
答案是挂载的rootfs文件系统中,挂载路径是 "/",
要“正常”运行内核,必须要有一个包含着userapp的文件系统,userapp数量至少得有一个以上。

问三:最小的linux userapp / 最小的rootfs镜像,应该是这样!
userapp 源文件名:loop.S 一个 arm64汇编代码写的源文件。

.data

.text
.globl main
main:
	b		.	/** 等效于 while(1); **/

编译、打包:

编译:
bin/aarch64-none-elf-gcc -c -fno-builtin -o init.o  loop.S
bin/aarch64-none-elf-ld  -e main init.o -o init

打包:
find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img

即可得到一个史上最最最最小的rootfs——能让内核正常启动哦。。。
只不过它不会有任何输出,它的作用,仅仅是让内核不会panic死掉。

重要的编译参数:-fno-builtin,让编译器不要链接它自带的libc代码,不论是动态的还是静态的。
因为这个loop.S啥也没干,不用libc中的代码。

这份代码用C语言同样可以实现:

int main()
{
    while(1);

    return 0;
}

编译的指令为:

bin/aarch64-none-elf-gcc -c -fno-builtin -o init.o  init.c
bin/aarch64-none-elf-ld  -e main init.o -o init

find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img

用qemu-aacrh64.exe加载这份rootfs.img+内核镜像: 

"/mnt/d/Program Files/qemu/qemu-system-aarch64.exe" \
-kernel ".\build\arch\arm64\boot\Image" \
-initrd ".\build\rootfs.img" \
-append "root=/dev/ram0 rootfstype=ramfs rw init=/init" \
-nographic -machine virt-6.2,gic-version=3,secure=on,virtualization=on -cpu cortex-a53 -m 1024 -semihosting

最重要的部分来了。

上面这个userapp要如何调用内核提供的函数——syscall机制在arm64上如何实现?
直接上代码:loop.S 进化为 ->   init.S :

.data

msg:
    .ascii        "Hello, ARM64!\n"
len = . - msg

.text

.globl main
main:
    /* syscall write(int fd, const void *buf, size_t count) */
    mov     x0, #1      /* fd := STDOUT_FILENO */
    ldr     x1, =msg    /* buf := msg */
    ldr     x2, =len    /* count := len */
    mov     w8, #64     /* write is syscall #64 */
    svc     #0          /* invoke syscall */
	
	b		.

    /* syscall exit(int status) */
    mov     x0, #0      /* status := 0 */
    mov     w8, #93     /* exit is syscall #1 */
    svc     #0          /* invoke syscall */

这段userapp代码的作用,大致等效于:
write(STDOUT, "Hello, ARM64!\n",字符串长度);
或者
printf("Hello, ARM64!\n");

编译指令:

bin/aarch64-none-elf-gcc -c -fno-builtin -o init.o  init.S
bin/aarch64-none-elf-ld  -e main init.o -o init

find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img

ARM64汇编代码中,系统调用的关键指令是 svc 。
上面的汇编代码,调用了内核提供的 write 函数—— 以这种汇编代码封装的方式,libc 运行库封装了内核实现的一两千函数。

libc 就是这么来的,类似的库,还有很多,newlibc, glibc, bonic ...

 

总结:
libc 是内核函数的用户态封装,供用户态的app调用内核函数用的。
它仅仅是内核的一层皮肤。
所以,你知道 gcc 加上 -static 参数去编译一份小exe源码是在静态链接些什么了吗?

其它:
PID为1的init进程,不能调用内核exit()函数,调用了就会结束init进程返回内核,
然后内核接着就是panic ....

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/130925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Wireshark TS | Packet Challenge 之 HTTP 案例分析

前言 来自于 Sharkfest Packet Challenge 中的一个数据包案例,Sharkfest 是 Wireshark 官方组织的一年一度的大会,致力于在 Wireshark 开发人员和用户社区之间分享知识、经验和最佳实践。印象中早期是一年一次,近几年发展成一年两次&#xf…

我的2022年终总结

目录 1 序 1 2 工作 1 3 业余 1 3.1 AI 1 3.2 数学小插曲 3 3.3 金融投资 3 4 生活 4 5 最后 4 1 序 老婆大人每年这个时候都要写年终总结,现在也正在写;CSDN也发起了年终征文活动;各大app也各种年度大数据总结。我好像还是第一次写年终总…

两两交换链表中的节点 -- 虚拟头节点

24两两交换链表中的节点 – 虚拟头节点 通过本题可以: 增加对虚拟头节点的理解。 加强对链表这一基本数据结构的基本操作的理解。 1. 交换过程: 如图,假设链表如图所示。 为了减少对头节点的单独讨论,这里采用虚拟头节点进行…

Allegro如何显示走线和铜皮的网络名操作指导

Allegro如何显示走线和铜皮的网络名操作指导 在做PCB设计的时候,如果可以实时看到走线和铜皮的网络名,对于设计有很大帮助,如下图 具体操作如下 选择Set-up-user preferences选择Display

Vue 总结一(简介 基本语法)

目录 Vue 是什么 与其它 JS 框架的关联 Vue 周边库 MVVM模型 怎么用 Vue模板语法有2大类: 数据绑定 data 事件 v-on methods 计算属性 computed 监视属性 watch computed和watch之间的区别: 条件渲染 v-if v-show Vue 是什么 一个动态构建用…

sql根据团队树一级一级汇总统计

1、需求描述 最近碰到了一个需求,是要统计各个团队的员工的销售金额,然后一级一级向上汇总。 架构团队树是类似于这种样子的,需要先算出每个员工的销售金额,然后汇总成上一级的团队金额,然后各个团队的销售总金额再往上…

京东技术发展简史

文章目录前言京东发展历程京东商城技术的演进京东自研技术分布式数据库StarDB京东云移动端Flutter在京东的实践大数据咚咚架构ShardingSphere京东人物参考“京东可以高速发展到今天的规模的原因,其中最核心的是坚持“倒三角”战略:建立出色的团队&#x…

转义字符与strlen(),sizeof()在一起的注意事项

转义字符与strlen(),sizeof() 1. 转义字符每个人都知道是怎么一回事儿,转义字符顾名思义就是转变意思。 2. 首先转义字符肯定是一个字符,不是两个字符,更不用说是数字了,就是字符。 3. 当用strlen()统计字符串长度时或者用sizeo…

2022年度回顾

这一年是不平凡的一年,换了公司,新公司频繁出差,去了临沂,去了河南,去了唐山,去了福鼎,当中最印象深刻的还是河南,项目万分火急,在疫情隔绝的10月份毅然决然的前往河南安…

如何稍微优雅滴完成博文访问计数[SpringBoot+redis+分布式锁]

文章目录前言背景朴素做法Redis方案流量统计接口演示自定义注解计数实现防刷加锁完整代码数据一致性分析自定义注解返回值分析解决方案总结前言 okey,我们来收尾一下,这公历纪年2022年12月31日。这是本年度的最后一篇博文。那么这篇博文主要是用来实现博文的一个访…

【LeetCode】被围绕的区域 [M](深度优先遍历)

130. 被围绕的区域 - 力扣(LeetCode) 一、题目 给你一个 m x n 的矩阵 board ,由若干字符 X 和 O ,找到所有被 X 围绕的区域,并将这些区域里所有的 O 用 X 填充。 示例 1: 输入:board [[&quo…

浅谈Flink批模式Adaptive Hash Join

Flink批Hash Join递归超限问题 随着Flink流批一体能力的迅速发展以及Flink SQL易用性的提升,越来越多的厂商开始将Flink作为离线批处理引擎使用。在我们使用Flink进行大规模join操作时,也许会发生如下的异常,导致任务失败: Hash j…

Es进阶检索

本文用到的测试数据及所有代码链接: https://blog.csdn.net/m0_62436868/article/details/128505566?spm1001.2014.3001.5501 1、SearchAPI ES 支持两种基本方式检索 : 一个是通过使用 REST request URI 发送搜索参数(uri检索参数) 另…

基于华为eNSP的中小企业办公园区网络规划与设计

目录一、需求分析(一)项目背景(二)网络业务需求(三)网络应用需求二、网络结构设计三、网络拓扑图四、网络设备基本配置五、项目测试结语运用到的技术有: 1、虚拟局域网(VLAN&#xf…

人工智能--你需要知道的一切

人工智能--你需要知道的一切 人工智能是当今最受关注的技术之一。但它究竟是什么?你为什么要关心? 人工智能是当今最受关注的技术之一。但它到底是什么?你为什么要关心?在这里,我们将介绍你需要知道的关于人工智能的…

java开发的美妆化妆品电商商城系统

简介 Java基于ssm(可以转springboot项目哦)开发的美妆商城系统,主要是卖化妆品的系统,用户可以浏览商品,加入购物车,下单,在个人中心管理自己的订单。管理员可以管理自己的商品,发布商品,上下架…

2023年留学基金委(CSC)公派访问学者博士后项目选派办法及解读

2023年即将伊始。知识人网祝大家新年快乐,心想事成!同时提醒申请者关注国家留学基金委(CSC)的申报政策。目前CSC官网已经发布了2023年公派访问学者、博士后的项目通知,知识人网小编现将其选派工作流程及选派办法原文转…

C语言 自定义类型

结构体内存对齐 解释1 从内存开始位置存放 解释二 int对齐数是4 vs默认对齐数是8 取其较小值的倍数 那就是4的位置存放 char 对数1 vs是8默认 谁的较小值对数是1 那就是任意数 所以c2防砸8 如下图绿色部分 struct S2 {char c1;int i;double d;//8 };输出结果16 struct S4 …

当我们身边没有示波器就无法测量频率与占空比了?一招教你解决身边没有示波器时如何测量STM32定时器产生PWM的频率与占空比

当我们身边没有示波器就无法测量频率与占空比了?这篇文件小编就教大家如何使用定时器输入捕获功能测量频率与占空比。 原理解析 定时器输入捕获一般应用在两个方面,一个方面是脉冲跳变沿时间测量,另一方面是 PWM输入测量。下面将要使用就是测…

LaTeX快速入门

文章目录LaTeX快速入门一、 概述1、 简介2、 环境配置3、文件结构4、 文档结构二、 基本概念1、 第一个LaTeX程序2、 宏包和文档类2.1 宏包2.2 文档类3、 文件组织的方式4、 相关术语和概念三、 排版文字1、 文字编码2、 排版中文3、 LaTeX中的字符3.1 空格和分行3.2 注释3.3 特…