-
Ubuntu20.04双系统安装详解(内容详细,一文通关!)
制作ubuntu系统安装盘 下载ubuntu镜像文件 这里给出两种下载方式: 1、官网下载 传送门🔗Download Ubuntu Desktop | Download | Ubuntu 如今官网上只能找到较新的ubuntu版本(截至到笔者写文时官网上显示的是Ubuntu 22.04.3 LTS和Ubuntu 23.04),较老的版本不太方便找到(反正笔者是真没找到呜呜呜)。【下载较新的ubuntu版本,容易导致在配置环境时有些插件不适配新版本的环境,产生诸多问题,所以不太推荐下载最新的版本】 2、清华大学开源软件镜像站(推荐!!) (1)传送门 🔗清华大学开源软件镜像站 | Tsinghua Open Source Mirror 搜索ubuntu-releases,点击20.04文件夹,即出现下图文件内容 选择文件“ubuntu-20.04.6-desktop-amd64.iso”,即可自动进行下载 (2)也可以直接点击下方文件链接进行下载 ubuntu-20.04.6-desktop-amd64.iso https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/20.04/ubuntu-20.04.6-desktop-amd64.iso 制作ubuntu启动盘 首先需要准备一枚8GB以上的U盘,然后需要将上述下载的iso镜像文件写入U盘中 【注意,制作成启动盘后U盘内的所有内容都会被清除,所以请事先备份好其中所有的文件】 有关写入操作,在这里笔者使用的是win32diskImager工具 防止跑错网站,这里直接给出链接 传送门🔗Win32 Disk Imager download | SourceForge.net 点击Download即可 下载完成并打开后显示如下的界面: 在“映像文件”部分(红线表示)选择之前下载好的iso文件,“设备”部分(蓝线表示)选择将要制作成启动盘的U盘的盘符(在“我的电脑”界面会显示,一般是E、F、G等巴拉巴拉的,对应好就行),然后点击“写入”(绿色部分)。 【注意】如果搜索文件映像时找不到文件,可以点击右下角黄色涂抹区域更换一下文件类型,由“磁盘映像”文件类型更换为“*.*”文件类型,就可以显示iso文件咯~ 点击写入之……
SE_Wang 2024-11-29
1.1K+ 0 0 -
【Linux】文件操作的艺术——从基础到精通
前言:一切皆文件 在正式开始文件操作的介绍之前,我们先来解决一个问题,什么是文件? 我们常见的文件有:文本文件(如.txt,.cpp),二进制文件(如编译后的可执行文件),图像文件等等,我们和这些文件打交道,无非就是对文件写入和对文件读取,然而我们是怎么实现对文件的写入和读取的呢?其实操作系统为我们提供了这一切,我们告诉系统要访问哪个文件,调用系统提供的方法,就实现了对文件的操作。 但文件的概念并不仅仅局限于磁盘上的存储内容,在操作系统中,几乎所有资源都可以通过类似“文件”的方式来进行访问和操作。无论是硬盘上的数据,还是连接计算机的外设设备,操作系统都通过类似文件的机制来统一管理他们。这是操作系统设计的一个重要思想——一切皆文件。 在这个框架下,设备(如键盘、鼠标、网络接口、内存等)不再是与文件不同的资源,而是被抽象为一种特殊类型的文件,通过统一的系统调用接口,我们可以像操作普通文件那样,操作这些设备,这种设计方式使得我们能够以一种一致的方式访问硬件资源。 下面我们来介绍操作系统具体是如何对文件进行操作,以及如何以“文件”的方式管理各种设备的。 📚一、C语言的文件接口 任何对文件的操作都可以看成对数据的访问、读取和写入,系统为我们提供了这些操作的接口,下面我们就来看看C语言下的文件接口: 📖1.文件打开 🔖语法 C语言提供了标准库函数 fopen() 用于打开文件: FILE *fopen(const char *filename, const char *mode); ① 参数1:filename,表示文件名,指定要打开的文件路径,可以是绝对路径也可以是相对路径 ② 参数2:mode,文件打开模式,指定打开文件的方式(文件操作的权限),常见的有: "r",只读方式打开文件,文件必须存在 "w",只写方式打开文件,文件不存在则创建,存在则清空文件 "a",追加模式,文件不存在则创建,存在则数据……
SE_Wang 2024-11-28
87 0 0 -
【Linux】权限管理
一.shell命令以及运行原理 Linux严格意义上说的是一个操作系统,我们称之为核心(kernel),但我们一般用户,不能直接使用kernel。而是通过kernel的"外壳"程序,也就是所谓的shell,来与kernel沟通。如何理解?为什么不能直接使用kernel? 从技术角度,Shell的最简单定义为命令行解释器主要包含: 将使用者的命令翻译给核心处理。 同时,将核心的处理结果翻译给使用者。 为什么要存在外壳程序? 用户不擅长直接与操作系统打交道,这是外壳程序的存在,使得用户操作更方便。 若用户进行了极其不合法的操作,外壳程序直接将该操作阻挡在外面,从而保护内核。 外壳程序以进程的方式呈现,当有新命令到来的时候,进程会创建子进程来执行新命令,子进程由于某种操作挂掉时,不会影响外壳程序。 对比windows GUI,我们操作windows 不是直接操作windows内核,而是通过图形接口,点击,从而完成我们的操作(比如进入D盘的操作,我们通常是双击D盘盘符或者运行起来一个应用程序) shell 对于Linux,有相同的作用,主要是对我们的指令进行解析,解析指令给Linux内核。反馈结果在通过内核运行出结果,通过shell解析给用户。 二.Linux权限管理 1.Linux中的用户 Linux含有两种用户 root用户:可以再linux系统下做任何事情,不受限制。 普通用户:权限低,受限制。 超级用户的命令提示符是"#“,普通用户的命令提示符是”$" 用户之间的身份切换:要从root用户切换到普通用户user,则使用 su user。 要从普通用户user切换到root用户则使用 su root(root可以省略),此时系统会提示输入root用户的密码。 2.sudo指令提权 sudo:用于指令的短暂提权(比如:安装软件到系统中,需要root管理员权限,其实只安装了一份,允许用户都可以使用) 3.权限 权限的本质:能或不能做什么事情。 权限控制用户的行为,防止错误的发生。 权限首先……
SE_Wang 2024-11-27
122 0 0 -
【Linux】「共享内存揭秘」:高效进程通信的终极指南
1. 什么是共享内存 共享内存(Shared Memory)是一种进程间通信(IPC,Inter-Process Communication)的方式,允许多个进程通过访问同一块内存区域来实现数据共享和快速通信。它是一种效率极高的通信机制,因为数据不需要在进程间进行复制,只需在同一块内存中直接读写即可。 1.2 共享内存的特点 高效:数据在高效内存区域是直接共享的,不需要在进程之间进行复制,从而减少了CPU和IO的消耗。 全局性:共享内存是所有附加到该内存的进程都可以访问的,由此它是一种全局资源。 同步机制依赖:虽然共享内存提供了数据共享的功能,但是不会自动提供对数据的访问同步机制。需要结合其他IPC方法(如信号量、互斥锁等)来避免多个进程同时读写时产生的数据竞争。 1.3 共享内存的工作原理 操作系统内核会在物理内存中分配一个共享内存段。 各个进程通过特定的标识符(shm_id)访问同一块共享内存空间。 共享内存区域是进程的地址空间外的内存,进程需要将其映射到自己的地址空间中才能访问。 还记得在进程地址空间时的内容吗? 共享内存的工作原理可以理解为:操作系统在内存中开辟了一块共享内存段,让两个不同的进程的虚拟地址同时对这块空间建立起映射关系,此时两个独立的进程能看到同一块空间,可以直接对此空间进行写入或者读取操作。 2.在Linux中使用共享内存 虽然Linux提供了POSIX和System V两种共享内存接口。但是本文将聚焦于System V 2.1 介绍System V System V(读作“System Five”)是 UNIX 操作系统家族的一个版本,由美国 AT&T 的贝尔实验室开发。它是早期 UNIX 的一个重要分支,并对后来的 UNIX 系统以及其他现代操作系统产生了深远影响。 虽然 System V 本身已经很少被直接使用,但它的思想和功能在现代操作系统中得到了传承。 比如:POSIX:吸收了 System V 的许多特性,成为跨平台的通用标准。 2……
SE_Wang 2024-11-26
180 0 0 -
【Linux】进程的生命之旅——诞生、消逝与守候(fork/exit/wait)
一、进程创建 1.fork函数 操作系统中进程的创建通常是通过系统调用实现的,在Linux中是通过fork(),它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 #include<unistd.h> // 使用需包含头文件unistd.h pid_t pid = fork(); // 在子进程中返回0,父进程中返回子进程pid,出错返回-1 fork是操作系统提供的一种高层封装,它抽象了进程创建的复杂过程,fork将底层的一系列操作封装在一个简单的系统调用中,屏蔽了许多复杂的细节: 📚高层封装特性 ① 简化进程创建的步骤: fork的调用接口非常简洁,只需要调用一次,系统会自动创建一个子进程并返回。父进程和子进程共享相同的代码,子进程可以继续从父进程的当前执行点运行。 ② 屏蔽底层细节: 底层需要分配新的内存空间、复制父进程的状态、初始化子进程的资源,fork函数将这些细节全部封装起来。 ③ 依赖操作系统: fork的具体实现以来于操作系统内核,它负责管理进程表等关键数据结构,系统调用fork,当控制转移到内核中的fork代码后,内核做: 1. 分配新的内存块和内核数据结构给子进程 2. 将父进程部分数据结构内容拷贝给子进程 3. 添加子进程到系统进程列表当中 4. fork返回,开始调度器调dan'ddandan 当一个进程调用fork之后就会有两个二进制代码相同的进程,并且都能运行到相同的地方,各自开始往下走: int main() { printf("Before: pid is %d, ppid is %d\n",getpid(),getppid()); fork(); printf("After: pid is %d, ppid is %d\n",getpid(),getppid()); return 0; } ❓这里为什么只有三行输出,子进程共享父进程的代码,并各自独立执行,应该是打印两次Before才对。分析打印结果,10226应该是父进程,确实打印了Before,而子进程10227没有打印Before,说明子进程并没有执行Before的代码,正如上面所说的,子进程继续从父进程……
SE_Wang 2024-11-25
139 0 0 -
Linux 链式与层级中断控制器讲解:原理与驱动开发
1.处理流程对比 Linux 4.9.88内核源码 Linux-4.9.88\drivers\gpio\gpio-mxc.c📎gpio-mxc.c Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi 1.1 下级中断控制器的类别 在后续课程中我们把GIC之下的中断控制器分为两类:链式(chained)、层级(hierarchy)。 (这个分类并没有官方定义) 1.1.1 链式中断控制器(chained) 上图中,左边的"chained intc"就是链式中断控制器。 它底下的4个中断触发时,都会导致GIC的33号中断被触发。 处理中断时,需要分辨:是谁触发了GIC 33号中断?这需要读取"chained intc"中的寄存器。 1.1.2 层级中断控制器(hierarchy) 上图中,右边边的"hierarchy intc"就是层级中断控制器。 它底下的4个中断,跟GIC中的4个中断一一对应。 处理GIC 100~103号中断时,不需要读取"hierarchy intc"的寄存器来分辨是谁触发了中断。 两种类型的中断控制器是可以组合的 1.2 链式中断控制器的处理流程 下图中: handleA、irq_dataA由GIC驱动提供 handleB、irq_dataB由GPIO驱动提供 handleC也是GPIO驱动提供 假设GPIO模块下有4个引脚,都可以产生中断,都连接到GIC的33号中断 GPIO就是一个链式中断控制器,它底下有4个中断 对于GPIO模块中0~3这四个hwirq,分配四个irq_desc 可以一下子分配4个:legacy,老方法 也可以用到时再分配:linear,新方法 假设这4个irq_desc的序号为100~103,在GPIO domain中记录(0,100) (1,101)(2,102) (3,103) 对于KEY,注册中断时就是:request_irq(102, ...) 按下KEY时: 程序从GIC中读取寄存器知道发生了33号中断,通过GIC irq_domain可以知道virq为17 处理virq 17号中断:调用irq_desc[17].handle_irq,即handleB mask/ack中断: 调用irq_desc[17].irq_data->irq_chip的函数,即irq_dataA 细分中断源、处理 读取GPIO寄存器,确定是GPIO里2号引脚发生中断 通过GPIO irq_dom……
SE_Wang 2024-11-22
114 0 0 -
Linux :进程间通信之管道
一、进程间通信 1.1 是什么和为什么 1、进程间通信是什么?? ——>两个或多个进程实现数据层面的交互,但是由于进程独立性的存在,导致通信的成本比较高。 2、既然通信成本高,那为什么还要通信呢?? ——> 在某些场景下我们需要不同进程之间进行(1)基本数据的交互。(2)发送命令。(3)实现某种协同。(4)通知某些信息…… 1.2 如何实现进程间通信 1、进程间通信的本质:要想办法让不同的进程看到同一份资源(以特定形式存在的内存空间)! 2、这个资源必须由操作系统提供!! 问题: 为什么必须由操作系统提供呢??难道不能由其中一个进程提供么?? ——>假设由一个进程提供,而我们又让另一个进程看到这份资源,那么这份资源应该属于谁呢?? ——>所以这种做法会破坏进程的独立性!!所以我们必须需要第三方空间,因此只能由操作系统提供! 举个例子:保持进程独立性,可以理解为就是我俩不能见面,就好比说一个绑匪把你绑架了,但是他并不会直接去你家取赎金,也不会让你家人把赎金送到自己的住所,而是会要求你的家人把钱放到一个地方,然后你再去取。 3、我们进程访问这个空间,本质上就是在访问操作系统!! ——>因为进程代表的就是用户,而操作系统并不相信用户,所以“资源”从创建、使用再到释放,必须使用系统调用接口!! 4、一般操作系统,会有一个独立的通信模块——隶属于文件系统——IPC通信模块 其中有两套标准 system V && posix 5、基于文件级别的通信方式——管道 1.3 进程间通信的方案设计 进程是具有独立性的,但是早期有的人发现我们很多时候需要通信,比如果进程需要通信,网络也需要通信,所以大家发现通信很重要,另一方面由于通信模块的设计相对简单,且可实现方案多样化,因此大家你做你的,我做我的,导致现在很多Linux发型版本都不一样,即使一样,内部的标准也不一……
SE_Wang 2024-11-21
85 0 0 -
详解Linux 中 Git 工具的使用与相关知识点
1. Git 的基本概念 版本控制:Git 记录每次代码变化的历史,用户可以随时查看和恢复到之前的版本。 分布式:每个用户都有完整的代码库和版本历史,可以在本地进行开发,直到准备好将修改推送到远程仓库。 快照:Git 将每一个文件的状态视为一个快照,而不是对比前后状态。 2. Git 的安装 在 Linux 系统中,可以通过包管理器安装 Git。例如,在 Ubuntu 中,可以使用以下命令: sudo apt update sudo apt install git 查看是否安装成功: git --version 出现上面这种版本号就代表已经安装成功了 3. 创建与配置 Git 仓库 3.1 创建新的 Git 仓库 在项目目录下初始化 Git 仓库: git init 这一步就直接在你的Linux系统的路径下输入该指令即可,比如我此时的项目目录为: 输入该指令创建新的Git仓库 3.2 克隆现有的 Git 仓库 如果想要从远程仓库克隆项目,可以使用: git clone <repository-url>(仓库链接) 这一步是比较重要的一步,我们需要先将仓库的链接复制下来,就拿gitee来举例,gitee的仓库链接位置在: 复制下来仓库的位置,将我们的项目传到远程仓库的例子如下: 我们可以看到执行语句如上,然后我们查看一下我们当前目录下的文件: 会发现有一个蓝色的文件名,这个文件名正是我所创建的仓库名,有这个就代表我们仓库已经克隆成功了 3.3 配置用户信息 设置 Git 用户名和电子邮件,这些信息会被记录到每次提交中: git config --global user.name "Your Name" git config --global user.email "your.email@example.com" 这里的用户名和电子邮件一定要设置成与你远程仓库中一样的 4. Git 的基本操作 4.1 查看状态 查看当前工作区和暂存区的状态: git status 4.2 添加文件到暂存区 在进行提交之前,需要将文件添加到暂存区: git add <file-name> # 添加单个文件 git add . # 添加当前目录下所有变……
SE_Wang 2024-11-20
93 0 0 -
【Linux】进程优先级&&进程切换
进程优先级 进程优先级是操作系统中用于决定进程调度顺序的重要属性。它表示一个进程在系统资源分配和 CPU 调度中的相对重要性。优先级越高的进程通常会获得更多的 CPU 时间和资源,从而更快地完成其任务。 查看进程优先级 ps -l 通常ps -l查询不到我们启动的进程的信息,所以我们一般都是用ps -al查询进程信息。 可以看到我们启动的myprocess。 这里有两个信息来觉得我们的优先级。 一个是PRI,一个事NI值,这两个决定了进程的优先级。 最终优先级的计算公式:P R I (最终) = P R I (默认) + N I PRI(最终)=PRI(默认)+NIPRI(最终)=PRI(默认)+NI NI值也称为nice值,是优先级的修正数据。 这里还有一个比较重要的信息:UID UID是操作系统中用于唯一标识用户的数字。在Linux中,每个用户都有一个唯一的 UID,用于控制访问权限和资源管理。 这里可以看到myprocess这个进程是由UID是1000的用户启动的。 UID的作用:我们知道Linux中有权限的概念,那么权限是如何实现的呢?其实每个文件也是有UID的。 当我们用某个指令的时候,比如说touch,mkdir等等指令,操作系统是如何判断是否有权限的呢,因为使用指令实际本质上也是启动一个进程,这个进程势必也是有UID的,所以操作系统可以对比这个文件的UID和这个操作的UID,看这个操作的UID对应的文件是否有这个权限,最后决定是否能进行这个操作。 进程优先级的修改 进程优先级的修改本质上是修改nice值,修改的是优先级修正数据,进而最终影响我们的最终优先级 进程优先级的修改主要有两种: 指令 代码 指令修改: 利用top指令修改进程优先级: 打开top,输入r进入到优先级修改的模式,通过PID来对优先级进行修改,输入我们对应的PID,然后对进程的nice值进行修改。 可以看见我们的NI值由默认的0修改为了1,最终优先级也是由默认的80,变为了81,这里我们可以……
SE_Wang 2024-11-19
94 0 0 -
【Linux】进程信号全攻略
一:🔥 再谈信号的捕捉 关于信号捕捉有三种方式: signal(2, handler); // 自定义捕捉 signal(2, SIG_IGN); // 忽略一个信号 signal(2, SIG_DFL); // 信号的默认处理动作 SIG_IGN 是一个特殊的宏,用于指示系统忽略该信号。 信号可能不会被立即处理,而是在合适的时候处理,那么合适的时候是什么时候呢? 先给结论:从进程的内核态返回到用户态的时候,进行处理。 💦 简单来说,执行自己的代码,访问自己的数据,这就叫做用户态。 💦 当我们进入系统调用时,我们以操作系统的身份来执行时,此时就进入了内核态,操作系统把我们的底层工作做完,做完这些工作后返回到我们的调用处,继续执行下面的代码,但是操作系统,由内核态返回到用户态时,在返回的这个时候信号的检测和处理 这是因为管理信号的数据结构(也就是我们的三张表)都位于进程的控制块(PCB)内,而PCB属于内核数据。因此,信号的检测和处理必须在内核态下进行。 当进程从内核态返回用户态时,内核会检查是否有待处理的信号,并根据信号的处理方式(默认处理、忽略或自定义处理)进行相应的操作。但操作系统不能直接转过去执行用户提供的handler方法,这是出于对安全性的考虑。 如果信号的处理动作是⽤⼾⾃定义函数,在信号递达时就调⽤这个函数,这称为捕捉信号。 由于信号处理函数的代码是在⽤⼾空间的,处理过程⽐较复杂,举例如下: ⽤⼾程序注册了 SIGQUIT 信号的处理函数 sighandler 。 当前正在执⾏ main 函数, 这时发⽣中断或异常切换到内核态。 在中断处理完毕后要返回⽤⼾态的 main 函数之前检查到有信号 SIGQUIT 递达。 内核决定返回⽤⼾态后不是恢复 main 函数的上下⽂继续执⾏,⽽是执⾏ sighandler 函数, sighandler 和 main 函数使⽤不同的堆栈空间,它们之间不存在调⽤和被调⽤的关系,是两个独⽴的控制流程。 sighandler 函数返回后⾃动……
SE_Wang 2024-11-18
81 0 0
