Ubuntu虚拟机Linux系统入门
目录
一、安装 Ubuntu Linux 20.04系统
1.1 安装前准备工作
1.1.1 镜像下载
1.1.2 创建新的虚拟机
二、编译内核源码
2.1 下载源码
2.2 指定编译工具
2.3 将根文件系统放到源码根目录
2.4 配置生成.config
2.5 编译
三、安装aarch64交叉编译工具
四、安装QEMU
五、创建基于 Ubuntu Linux 的根文件系统
5.1 BusyBox构建根系文件系统
5.1.1 下载BusyBox源码
5.1.2 制定编译工具链
5.1.3 配置编译BusyBox
5.1.4 创建需要的目录
六、启动QEMU
6.1 创建共享文件目录
6.2 运行QEMU模拟器
6.3 编译一个简单的内核模块并在QEMU上运行
七、总结
一、安装 Ubuntu Linux 20.04系统
1.1 安装前准备工作
1.1.1 镜像下载
下载地址:https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/20.04.4/
选择Ubuntu-releases

选择20.04

1.1.2 创建新的虚拟机
点击创建新的虚拟机,选择镜像文件、安装位置等

安装完成,界面如下,输入密码


快照 Ubuntu快照是一种自包含的软件包格式,它将应用程序及其依赖项打包在一起,使得软件可以在不同的Linux发行版上无缝运行。快照包包含了所有必要的依赖项,用户无需担心软件兼容性问题;快照包在安装和运行时受到严格的权限控制,降低了安全风险;快照包在不同版本的Ubuntu以及其他支持Snap的Linux发行版上保持相同的运行环境。
将此时的虚拟机进行快照操作,保存为原始干净的虚拟机


二、编译内核源码
2.1 下载源码
Linux内核官网:The Linux Kernel Archives
现在最新的稳定的内核版本是Linux6.13.6(Linux 内核的版本号分成三部分,第一个数
字表示主版本号,第二个数字表示次版本号,第三个数字表示修正版本号)

下载好之后,把它拖到虚拟机的文件夹下,并进行解压缩

tar xvf linux-6.13.6.tar.xz
2.2 指定编译工具
![]()
2.3 将根文件系统放到源码根目录
sudo cp ~/linux/rootfs rootfs_arm64 -a
![]()
2.4 配置生成.config
输入以下命令
make defconfig
make menuconfig


添加hotplug支持
Device Drivers -> Generic Driver Options -> Support for uevent helper (/sbin/hotplug) path to uevent helper

添加initramfs支持
[*]Initial RAM filesystem and RAM disk(initramfs/initrd) support(_install_arm64) Initramfs souce file(s)

Virtual address space配置
Kernel Features ---> Page size(4KB) --->Virtual address space size(48-bit)--->


2.5 编译
make all -j8
三、安装aarch64交叉编译工具
下载安装对应架构的交叉编译工具链(arm64架构),搭建QEMU的模拟环境
sudo apt-get install gcc-aarch64-linux-gnu
sudo apt-get install libncurses5-dev build-essential git bison flex libssl-dev
![]()
![]()
安装完成,查看版本说明
aarch64-linux-gnu-gcc -v

四、安装QEMU
QEMU是一个通用的开源机器模拟器和虚拟化器,它可以模拟整个系统,也可以作为虚拟化的宿主程序。使用QEMU可以方便地在不同硬件平台上运行Linux系统。
输入以下命令进行安装
sudo apt install qemu-system-arm

安装完成,输入以下命令查看版本
qemu-system-aarch64 --version

五、创建基于 Ubuntu Linux 的根文件系统
根文件系统是Linux操作系统中最重要的组成部分,它包含了系统启动和运行所需的最基本的文件和目录。创建根文件系统是定制Linux系统的关键步骤。
5.1 BusyBox构建根系文件系统
5.1.1 下载BusyBox源码
将下载的压缩包保存到Ubuntu虚拟机中的文件夹,并对其进行解压

![]()
加压后的文件如下所示:

5.1.2 制定编译工具链
输入以下命令
cd busybox-1.36.1
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
//检测是否配置成功
echo $ ARCH
echo $CROSS_COMPILE

5.1.3 配置编译BusyBox
busybox中文字符支持:若直接编译busybox,使用串口工具时是不支持中文显示的,会显示为“?” ,修改源码,取消 busybox对中文显示的限制
修改内容如下:
/libbb/printable_string.c,将函数printable_string()中的部分程序注释掉,修改后的函数内容如下:


接着打开文件/libbb/unicode.c,修改如下内容:

配置busybox

配置好之后编译BusyBox,输入以下命令
make
make install CONFIG_PREFIX=/home/hututu/linux/rootfs
#CONFIG_PREFIX指定编译结果的存放目录
执行make install CONFIG_PREFIX=/home/hututu/linux/rootfs会报错mkdir: cannot create directory '/home/linux': Permission denied make: *** [/home/hututu/linux/busybox-1.37.0/Makefile.custom:39:install] 错误 1,此时,我们先执行以下命令:
sudo cp ~/linux/rootfs rootfs_arm64 -a
之后再输入以下命令:
make install CONFIG_PREFIX=/home/hututu/linux/rootfs
执行成功,显示如下:

编译完成,BusyBox的所有工具和文件都安装到了roofts目录下,如下图所示:

5.1.4 创建需要的目录
![]()
(1)etc目录更新
分别创建以下几个文件夹

创建profile文件,添加以下内容
#!/bin/sh
export HOSTNAME=user
export USER=root
export HOME=/home
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
创建inittab 文件,添加下面内容
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
创建fstab文件,添加以下内容
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
kmod_mount /mnt 9p trans=virtio 0 0
用以下命令创建init.d目录
mkdir init.d
在init.d目录下创建rcS文件,添加以下内容
cd init.d
mkdir -p /sys
mkdir -p /tmp
mkdir -p /proc
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
用以下命令为rcS添加权限
chmod 777 rcS
![]()
最后输入tree命令查看etc下的目录结构:

如果输入tree命令,提示如下:
ommand 'tree' not found, but can be installed with:
sudo snap install tree # version 2.1.3+pkg-5852, or
sudo apt install tree # version 1.8.0-1
See 'snap info tree' for additional versions.
说明没有安装tree命令,只需要输入如下命令进行安装即可
sudo apt update
sudo apt install tree
(2)dev目录下的必要文件
在主文件夹-->linux-->roofts文件夹下新建一个文件夹,命名为dev,导航到该文件夹,并输入以下命令:
sudo mknod console c 5 1
![]()
输出以下命令来检查是否创建了cinsole的设备文件
ls -l /dev/console
![]()
(3)lib目录下的必要文件
导航到lib文件夹,输入以下命令
cp /usr/aarch64-linux-gnu/lib/*.so* -a .
检查当前文件夹是否包含了.so文件

六、启动QEMU
6.1 创建共享文件目录
输入以下命令,在内核源码目录下创建目录
mkdir kmodules
![]()
6.2 运行QEMU模拟器
在内核源码目录下输入以下命令
qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8" -nographic --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount
启动成功后的内容如下,Enter进入控制台


退出QEMU模拟器,输入以下命令
poweroff
6.3 编译一个简单的内核模块并在QEMU上运行
在根目录下创建一个文件夹,并编写一个简单的代码
// 包含内核模块编程所需的头文件
#include <linux/init.h> // 包含模块初始化和退出函数的宏
#include <linux/module.h> // 包含模块相关的宏和函数
#include <linux/kernel.h> // 包含内核打印函数 printk 的头文件
static int __init test_init(void)
{// 在内核日志中打印 "hello world!"printk("hello world!\n");// 返回 0 表示初始化成功return 0;
}
static void __exit test_exit(void)
{// 在内核日志中打印 "hello exit!"printk("hello exit!\n");
}
// 当模块被加载时,test_init 函数会被调用
module_init(test_init);
// 当模块被卸载时,test_exit 函数会被调用
module_exit(test_exit);
// GPL 是 GNU 通用公共许可证,表示这是一个开源模块
MODULE_LICENSE("GPL");
再编写Makefile文件# 设置目标架构为 ARM64
export ARCH=arm64
# 设置交叉编译工具链前缀为 aarch64-linux-gnu-
export CROSS_COMPILE=aarch64-linux-gnu-
# 定义内核源码目录
KERNEL_DIR ?= /home/xlq/linux-6.13.5
# 定义要编译的内核模块目标文件
# obj-m 表示将 hello.c 编译为内核模块 hello.ko
obj-m := hello.o
# 默认目标:编译内核模块
modules:# 调用内核源码目录的 Makefile,编译当前目录下的模块$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
# 清理目标:删除编译生成的文件
clean:# 调用内核源码目录的 Makefile,清理当前目录下的生成文件$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
# 安装目标:将编译好的内核模块复制到指定目录
install:# 将当前目录下所有的 .ko 文件复制到内核源码目录的 kmodules 子目录中cp *.ko $(KERNEL_DIR)/kmodules
编译module,输入以下命令拷贝到共享目录
make modules
make install
输入以下命令启动QEMU
qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8" -nographic --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount
ls /mnt

可以看到.ko文件
在QEUM执行module的插入与卸载,可以看到成功执行并打印log
[hututu@hututu ]$ cd mnt
[hututu@hututu mnt]$ ls /mnt
hello.ko kmod_mount
[hututu@hututu mnt]$ insmod hello.ko
[ 3679.306752] hello: loading out-of-tree module taints kerne
[ 3679.322242] hello world!
[hututu@hututu mnt]$ rmmod hello.ko
3732.515746] hello exit!

七、总结
通过本次实验,了解了Linux系统的基本安装和配置方法,还对虚拟化技术、软件源管理、根文件系统构建以及跨平台编译等高级概念有了深入的理解。这些知识和技能对于进一步学习Linux系统管理和软件开发具有重要意义。
参考博客:Ubuntu虚拟机中使用QEMU搭建ARM64环境-CSDN博客
相关文章:
Ubuntu虚拟机Linux系统入门
目录 一、安装 Ubuntu Linux 20.04系统 1.1 安装前准备工作 1.1.1 镜像下载 1.1.2 创建新的虚拟机 二、编译内核源码 2.1 下载源码 2.2 指定编译工具 2.3 将根文件系统放到源码根目录 2.4 配置生成.config 2.5 编译 三、安装aarch64交叉编译工具 四、安装QEMU 五、…...
【蓝桥杯】2025省赛PythonB组复盘
前言 昨天蓝桥杯python省赛B组比完,今天在洛谷上估了下分,省一没有意外的话应该是稳了。这篇博文是对省赛试题的复盘,所给代码是省赛提交的代码。PB省赛洛谷题单 试题 A: 攻击次数 思路 这题目前有歧义,一个回合到底是只有一个…...
深入解析区块链技术:原理、应用与未来展望
1 区块链技术原理 1.1 基本概念 区块链本质上是一个分布式账本,它由一系列按照时间顺序排列的数据块组成,每个数据块包含了一定时间内的交易信息。这些数据块通过密码学技术相互链接,形成一个不可篡改的链条。其核心特点包括去中心化、不可篡…...
Linux进程替换与自定义shell详解
引言 进程替换和shell编程是Linux系统中极其重要的概念,它们不仅是系统内部工作的基础机制,也是系统管理员和开发者必备的技能。本文将深入探讨Linux中的进程替换原理、系统调用实现以及如何创建自定义shell,帮助你全面理解这些重要概念并掌…...
【数据结构_4下篇】链表
一、链表的概念 链表,不要求在连续的内存空间,链表是一个离散的结构。 链表的元素和元素之间,内存是不连续的,而且这些元素的空间之间也没有什么规律: 1.顺序上没有规律 2.内存空间上也没有规律 *如何知道链表中包…...
Mybatis的简单介绍
文章目录 MyBatis 简介 1. MyBatis 核心特点2. MyBatis 核心组件3. MyBatis 基本使用示例(1) 依赖引入(Maven)(2) 定义 Mapper 接口(3) 定义实体类(4) 在 Service 层调用 4. MyBatis 与 JPA/Hibernate 对比 MyBatis 简介 MyBatis 是一款优秀的 持久层框…...
JavaScript 性能优化实战:深入探讨 JavaScript 性能瓶颈,分享优化技巧与最佳实践
在当今 Web 应用日益复杂的时代,JavaScript 性能对于用户体验起着决定性作用。缓慢的脚本执行会导致页面加载延迟、交互卡顿,严重影响用户留存率。本文将深入剖析 JavaScript 性能瓶颈,并分享一系列实用的优化技巧与最佳实践,助你…...
1g内存电脑sqlite能支持多少并发
1. SQLite的并发机制 写操作:默认使用串行锁,同一时间仅允许一个写操作(其他写/读需等待)。读操作:支持多并发读取,但受内存、磁盘I/O和配置限制。 2. 关键限制因素 (1)内存资源 …...
jetpack之jetpack的概括和其中组件的简单使用
注意⚠:此篇文章由deepseek大力支持!!!(╹ڡ╹ ) 主要是对不知道学什么,对各个组件一头雾水的jetpack新手准备的文章 不知道jetpack学什么,就看这篇文章!! 1. DataBindingÿ…...
音视频 五 看书的笔记 MediaCodec
MediaCodec 用于访问底层媒体编解码器框架,编解码组件。通常与MediaExtractor(解封装,例如Mp4文件分解成 video和audio)、MediaSync、MediaMuxer(封装 例如音视频合成Mp4文件)、MediaCrypto、Image(cameraX 回调的ImageReader对象可以获取到Image帧图像,可转换成YU…...
物联网|无人自助台球厅源码|哪些框架支持多设备连接?
在无人自助台球厅的智能化管理中,物联网(IoT)技术是核心支撑。如何实现不同设备(如智能门锁、环境传感器、支付终端、灯光控制系统等)的高效连接与协同工作,是系统开发的关键挑战。本文将带大家探讨支持多设…...
Python中NumPy的统计运算
在数据分析和科学计算领域,Python凭借其丰富的库生态系统成为首选工具之一,而NumPy作为Python数值计算的核心库,凭借其高效的数组操作和强大的统计运算功能,广泛应用于机器学习、信号处理、统计分析等场景。本文将系统介绍NumPy在…...
uniapp实现H5页面麦克风权限获取与录音功能
1.权限配置 在uni-app开发H5页面时,需要在manifest.json文件中添加录音权限的配置。具体如下: {"h5": {"permissions": {"scope.record": {"desc": "请授权使用录音功能"}}} }这段配置代码是用于向…...
两个树莓派如何通过wifi direct传输视频并显示
这里写自定义目录标题 在两台设备上安装必要软件Wi-Fi Direct接收端IP(自动发现或静态设置)设置摄像头参数显示初始化网络设置 系统架构概述 发送端树莓派:捕获视频(摄像头或视频文件)→ 编码 → 通过Wi-Fi Direct传输…...
ubuntu 系统安装Mysql
安装 mysql sudo apt update sudo apt install mysql-server 启动服务 sudo systemctl start mysql 设置为开机自启 sudo systemctl enable mysql 查看服务状态 (看到类似“active (running)”的状态信息代表成功) sudo systemctl status mysql …...
selenium快速入门
一、操作浏览器 from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By# 设置选项 q1 Options() q1.add_argument("--no-sandbo…...
Redis:线程模型
单线程模型 Redis 自诞生以来,一直以高性能著称。很多人好奇,Redis 为什么早期采用单线程模型,它真的比多线程还快吗? 其实,Redis 的“快”并不在于并发线程,而在于其整体架构设计极致简单高效,…...
Transformer模型解析与实例:搭建一个自己的预测语言模型
目录 1. 前言 2. Transformer 的核心结构 2.1 编码器(Encoder) 2.2 解码器(Decoder) 2.3 位置编码(Positional Encoding) 3. 使用 PyTorch 构建 Transformer 3.1 导入所需的模块: 3.2 定…...
Java常用安全编码的规范整理及工具
对Java安全编码的主要规范及要求的一些整理: 一、输入验证与数据校验 外部输入校验 对所有外部输入(如用户输入、文件、网络数据)进行合法性校验,采用白名单机制限制输入内容范围 。校验前对输入数据做归一化处理ÿ…...
重返JAVA之路——面向对象
目录 面向对象 1.什么是面向对象? 2.面向对象的特点有哪些? 3.什么是对象? 4.什么是类? 5.什么是构造方法? 6.构造方法的特性有哪些? 封装 1.什么是封装? 2.封装有哪些特点? 数据隐…...
Java设计模式全解析(共 23 种)
一、设计模式全解: Java 中的设计模式是为了解决在软件开发中常见问题的一些“最佳实践”总结。设计模式分为三大类,共 23 种经典模式: 1. 创建型模式(5 种) 用于对象的创建,解决对象实例化过程中的问题。…...
Python10天突击--Day 2: 实现观察者模式
以下是 Python 实现观察者模式的完整方案,包含同步/异步支持、类型注解、线程安全等特性: 1. 经典观察者模式实现 from abc import ABC, abstractmethod from typing import List, Anyclass Observer(ABC):"""观察者抽象基类""…...
springboot框架集成websocket依赖实现物联网设备、前端网页实时通信!
需求: 最近在对接一个物联网里设备,他的通信方式是 websocket 。所以我需要在 springboot框架中集成websocket 依赖,从而实现与设备实时通信! 框架:springboot2.7 java版本:java8 好了,还是直接…...
【玩泰山派】5、点灯,驱动led-(2)ubuntu18.04 升级python3.6到python3.7,安装pip3
文章目录 前言升级python3.71、安装 software-properties-common 包2、添加 deadsnakes PPA 源3、安装 Python 3.71. 安装 Python 3.72. 安装 Python 3.7 的开发包和虚拟环境支持(可选但推荐)3. 设置 Python 3.7 为默认版本4. 验证 Python 版本注意事项 …...
ES6学习03-字符串扩展(unicode、for...of、字符串模板)和新方法()
一、字符串扩展 1. eg: 2.for...of eg: 3. eg: 二。字符串新增方法 1. 2. 3. 4. 5....
c++中的this
在 C 中,this 是一个指向当前对象实例的指针,它隐式地存在于类的非静态成员函数中。以下是 this 的详细用法和常见场景: 1. 常见场景 明确成员归属:当成员变量与局部变量同名时,用 this-> 显式访问成员。当成员变量…...
目前状况下,计算机和人工智能是什么关系?
目录 一、计算机和人工智能的关系 (一)从学科发展角度看 计算机是基础 人工智能是计算机的延伸和拓展 (二)从技术应用角度看 二、计算机系学生对人工智能的了解程度 (一)基础层面的了解 必备知识 …...
Flutter 2025 Roadmap
2025 这个路线图是有抱负的。它主要代表了我们这些在谷歌工作的人收集的内容。到目前为止,非Google贡献者的数量超过了谷歌雇佣的贡献者,所以这并不是一个详尽的列表,列出了我们希望今年Flutter能够出现的所有令人兴奋的新事物!在…...
[数据结构]排序 --2
目录 8、快速排序 8.1、Hoare版 8.2、挖坑法 8.3、前后指针法 9、快速排序优化 9.1、三数取中法 9.2、采用插入排序 10、快速排序非递归 11、归并排序 12、归并排序非递归 13、排序类算法总结 14、计数排序 15、其他排序 15.1、基数排序 15.2、桶排序 8、快速排…...
第16届蓝桥杯c++省赛c组个人题解
偷偷吐槽: c组没人写题解吗,找不到题解啊 P12162 [蓝桥杯 2025 省 C/研究生组] 数位倍数 题目背景 本站蓝桥杯 2025 省赛测试数据均为洛谷自造,与官方数据可能存在差异,仅供学习参考。 题目描述 请问在 1 至 202504ÿ…...
