bios启动流程
虽然我知道现在大多数的pc都已经不再使用bios而是使用更先进、灵活的uefi的方式,但是我们操作系统考试就是只考bios启动。
因此本文会首先用详细版本讲述bios启动的来龙去脉,然后再归纳出一个考试时我会写的一个答案。
详细版本
一、第一阶段BIOS
上个世纪70年代初,“只读内存”(read-only memory,缩写为ROM)发明,开机程序被刷入ROM芯片,计算机通电后,第一件事就是读取它。
这块芯片里的程序叫做"基本输入输出系統"(Basic Input/Output System),简称为BIOS。
在一个x86架构的CPU中(通常我们用的就是这个架构,所以我们这里只研究它,其它架构大差不不差),为了实现计算机通电以后第一件事就读取它,CPU通电后的程序计数器会被CPU自动设置为0xffff0。
为什么是这个地址呢?为了理解这个我们首先需要知道x86架构下cpu的模式。
CPU的模式
x86架构的CPU有几种不同的操作模式,每种模式都有其特定的用途和特性。
实模式(Real Mode):这是最基础的模式,也是CPU在启动时 ...
使用u-boot+linux kernel+busybox实现一个嵌入式小系统
嵌入式作业,要求我们实现
使用QEMU模拟一个嵌入式开发板;
使用交叉编译器,为虚拟平台编译u-boot,并进入下载模式熟悉简单命令;
使用交叉编译器,为虚拟平台编译内核kernel;
为虚拟平台创建根文件系统(借助busybox),并启动平台系统,编写简单的hello world程序,传输到嵌入式平台(可放入根文件系统),运行获得结果。
完成虚拟字符驱动的编写,并加载到内核,获得实验结果;
接下来的实验中,我选择模拟vexpress_ca9x4开发板。
编译和安装
arm编译器
首先要想跨平台安装,就需要安装对应平台的编译链工具。在这里我们选择使用最广的arm架构下的gcc进行编译。
在arch平台下使用下面命令进行安装,一定要按下面的顺序安装
yay -Sy arm-linux-gnueabihf-gcc-stage1yay -S arm-linux-gnueabihf-gcc-stage2yay -S arm-linux-gnueabihf-gcc
其它平台自行搜索对应wiki。
这里提 ...
Linux上的VRF
VRF 的概念可能是大家熟悉的概念,如果你不熟悉可以查阅Linux文档中关于他的描述。当我们谈论 3 层网络隔离时,它们被广泛的使用。正如我们之前所讨论的,它们广泛用于 MPLS VPN 等应用,真正为第 3 层网络隔离奠定了基础。它们通过允许创建多个路由表来实现此目的。然后,可以将任何第 3 层构造映射到 VRF 中。例如:
我可以为接口分配一个 IP 地址,然后将该接口映射到 VRF 中。
同样,我可以配置静态路由,并指定该路由是给定 VRF 的一部分。
更进一步,我可以在其中一个 VRF 接口上建立 BGP 会话,并接收到 VRF 的远程 BGP 路由。VRF 属于第 3 层,就像 VLAN 属于第 2 层一样。
因此,虽然我们已经讨论了它们通常如何在路由器和交换机等网络硬件上使用和实现,但我们还没有讨论它们如何在 Linux 中实现。实际上,它们对 Linux 领域来说是相当新的。该功能实际上是由 Cumulus Networks 编写的,然后贡献给了 Linux 内核(感谢他们这样做)。VRF 是在内核 4.3 版中引入的,大概是在2015 年左右 ...
net.ipv4.icmp_errors_use_inbound_ifaddr内核代码参数详解
学习icmp相关的内核参数的时候,遇到了这个内核参数,看了看官方文档的描述,感觉它描写的云里雾里的,问了问朋友,朋友也看不懂文档的描述,互联网上对这个参数的解读大多又都是直接从内核文档这里复制过来的。既然如此,那就很有必要读一读内核代码,直接从代码层面解决问题了。
📄文档描述
这里先贴出官方文档对这个参数的解释:
icmp_errors_use_inbound_ifaddr - BOOLEAN
If zero, icmp error messages are sent with the primary address of the exiting interface.
If non-zero, the message will be sent with the primary address of the interface that received the packet that caused the icmp error. This is the behaviour many ...
C语言中一种优雅的链表实现方式——Linus way
在一个ted的采访中Linus Torvalds, 大约在14:20处,他快速的谈论了什么是编程的。其中他以链変举例,其中他提到了使用了二级指针,实现了一个链表的操作方式。
这方法我之前确实还不会,本来想自己写一篇博文,但是发现github上mkirchner已有一篇博文介绍了这个方法,作者TaivasJumala对其进行了翻译。因此就不再写,只是mark一下。
TL;DR
直接贴出Linus认为的优雅方式,方便日后查阅:
struct list_item { int value; struct list_item *next;};typedef struct list_item list_item;void remove_elegant(list *l, list_item *target){ list_item **p = &l->head; while (*p != target) p = &a ...
Linux 动态库so的操作
Linux初学者并且对c语言不太熟悉的同学,在接触Linux的时候往往不知道用什么工具来操作linux的动态库.so文件,以及不知道.so文件应该放在哪里,遇到执行程序报错找不到xxx.so文件的时候应该怎么办。
于是乎,针对这些疑问,我写下这篇博文来总结一个动态库的一些操作,希望能帮助到大家。
🔍查看执行文件依赖哪些so文件
运行一个执行文件时,我们往往想要知道它依赖哪些so文件。我们可以使用下面几个方法来获取
1. ldd
这个命令应该是使用最广泛的了,只需要ldd命令后面跟上可执行文件,如:
$ ldd uselib linux-vdso.so.1 (0x00007ffc27709000) libdistance.so => not found libm.so.6 => /usr/lib/libm.so.6 (0x00007ff4bd2c0000) libc.so.6 => /usr ...
POSIX threads中joinable和detached线程的区别
创建方式
这里都以Linux下的实现为例,进行说明。
joinable的创建方式
posix thread默认创建出来的线程就是joinable方式,所以创建方式十分简单
#include <pthread.h>#include <string.h>result = pthread_create (&server, NULL, thread_body, connfd);if (result) fprintf (stderr, "pthread_create: %s", strerror (result));pthread_join(server, &status);
detached线程创建方式
需要在thread_create的时候传入一下特殊的标志。
#include <pthread.h> #include <string.h>pthread_attr_t attr;pthread_attr_init (&a ...
TCP随机初始化序列号(ISN)的原因
TCP的三次握手过程中,要随机初始化seq字段两次,客户端和服务端各一次,那么为什么需要随机初始化序列号(ISN)?而不是默认从0开始?
有两个原因:
1. 避免不同tcp连接的冲突
rfc793的说明
这个可以追溯到tcp最开始的rfc文档(rfc793),其中有一小节(Initial Sequence Number Selection)专门讲述了为什么要这样设计。
下面是我翻译的原文:
该协议对一个特定的连接没有限制,可以重复使用。连接由一对套接字定义。连接的新实例将被称为连接的不同化。由此引发的问题是,“TCP如何识别先前连接的重复段?”如果连接在快速打开和关闭之间进行,或者连接中断并且丢失了记忆,然后重新建立,这个问题就变得明显起来。
为了避免混淆,我们必须防止连接的一个不同化中的段在网络中仍然存在相同的序列号时被使用。即使TCP崩溃并且失去了所有关于它使用的序列号的知识,我们也希望确保这一点。当创建新连接时,会使用一个初始序列号(ISN)生成器,该生成器选择一个新的32位ISN。生成器绑定到一个(可能是虚构的)32位时钟,其低位 ...
为什么kubernetes的ownerReference要设计成列表,存在多个ownerReference的情况吗?
如果我们仔细查看kubernetes的metadata字段,我们会发现owenerReference被设计成了一个列表。按照常理理解,一个资源难道不是只有一个控制器吗?比如Pods资源类型,我们去查看其ownerReference我们在绝大多数情况下(其实在我的集群上,可以描述为“全部”)只会见到类型为ReplicaSets的owner。那么我们是否应该将其改为单一的值类型呢?
先说结论:不能。
要想弄清楚为什么它的类型为list,我们非常有必要理解一下ownerReference字段是做什么用的。
ownerReference字段的作用
1. 作用一 :垃圾清理
在kubernetes中,一些资源是被一些其他资源自动控制的,一个例子就是我们上文提到的ReplicaSets和Pods,一个ReplicaSet是一组Pods的parent。
现在我们可以将这个概念几乎拓展到kubernetes中的所有资源,这意味着这个可以控制多个资源之间的parent与child关 ...
学习过程中看到的,做的真不错,通俗易懂,mark一下:
Raft (thesecretlivesofdata.com)