Browsed by
Tag: C. Linux

[Linux 0.11] Draft 5 虚拟内存管理(mm/memory.c)

[Linux 0.11] Draft 5 虚拟内存管理(mm/memory.c)

Overview 本文介绍 32 位保护模式下的内存分页, 以及 linux0.11 对物理内存的管理。 意义 既然要使用内存分页,那么就一定有他的优势所在。我们首先来探讨一下使用内存分页的意义, 分页在于为进程提供了虚拟地址空间,通过提供的这个虚拟地址空间,我们可以做到下面的这些: 精细的权限控制粒度: 内存页大小以 4KB 为一页单位(也可以是4MB, 这里不讨论这种情况), 可以针对每一个内存页设置该4K空间的访问权限。相比分段的粗粒度精细了很多,目前的分段功能只是一个兼容性考虑,分段都是将整个0 – 最大内存空间直接映射为一个段; 可以使得进程独享地址空间: 通过切换CR3寄存器的内容,可以实现多个进程占用同一个虚拟地址空间。 有效的解决了进程对大块连续内存的请求: 这里用一个例子来说明一下。 例子是这样的: 如果我们有16MB的物理内存,现在有进程A B C分别占用5MB, 2MB, 3MB内存, 且不共享内存。然后现在进程B退出了,我们还剩余8MB内存,可是如果不使用分页的话,内存连续分配, 我们现在没有办法分配出一个连续的8MB的空间了,只能分配最多最多6MB连续的内存空间, 如下图所示。 而现在存在分页,虚拟地址,我们完全可以分配连续的8MB的虚拟地址空间,其中2MB映射到物理内存的中间那个2MB空隙,其余6MB映射到最后剩余的6MB。 由此可见,分页是十分必要的,那么下面就来介绍一下如何实现分页&虚拟内存管理 地址转换过程 我们先来看一下虚拟地址是如何转换为物理地址的 完整的转换过程为 虚拟地址 –> (GDT) –> 线性地址 –> (Page Table) –> 物理地址 关于VirtualAddr -> LinearAddr 的过程我在之前的文章中有过介绍,这里就不做说明,想要跳过那个文章的读者可以简单的理解为目前的虚拟地址和线性地址值是相同的,因而我们直接从线性地址出发。首先来看下图   (图片来源:Intel® 64 and IA-32 Architectures Software Developer’s Manual) 线性地址为32位的地址, 其中高十位为 Page Directory,中间十位为 Page Table,最后十二位是 Offset。过程如下: 根据 CR3 寄存器(忘记了寄存器的功能的话戳这里)找到了页目录表的地址。 根据 Linear Address 的高十位与页表目录地址相加,找到了对应的页目录项(PDE)。 页目录项内存有该页目录的起始地址,将此地址与 Linear Address 21 – 12 位(即中间十位)相加,找到对应的页表项(PTE)…

Read More Read More

[Linux 0.11] Draft 4 GCC Assembly

[Linux 0.11] Draft 4 GCC Assembly

全文参考 https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm 阅读文档永远比阅读博客能获得更多的信息哦~ 本文对 GCC Assembly 进行总结和介绍,也是个人的笔记,欢迎各位指正,内容供参考 * Basic Asm — 基本不能用的 assembly * Extended Asm 功能强大的可扩展的ASM

[Archlinux] 如何解决搜狗输入法炸掉的问题

[Archlinux] 如何解决搜狗输入法炸掉的问题

近期不知道什么蜜汁更新导致fcitx-sogoupinyin可能由于魔幻的力量崩溃。而且看错误毫无头绪(炸在奇怪的glibc的函数里) 因此这里提供一个玄学尝试的办法 rm ~/.config/SogouPY pgrep fcitx | xargs kill 再启动fcitx 以及sogou-qimpanel 也许就能救回来哦~ 【又水了一篇文章】

[Linux 0.11] Draft 2 80386 System Architecture

[Linux 0.11] Draft 2 80386 System Architecture

此文对 Intel 80386 的系统架构进行一定程度的说明 80386 在系统层面支持下面的功能 保护 内存管理 多任务 IO 异常和中断 初始化 协处理器,多处理技术 调试功能 上述均通过系统寄存器以及指令来支持,下面会对这些进行介绍 系统寄存器(Registers) 系统寄存器分为如下几类 EFLAGS 内存管理寄存器 控制寄存器 (Control Registers) 调试寄存器 (Debug Registers) 测试寄存器 (Test Registers) 下面对每一类寄存器进行说明 System FLAGS EFLAGS 中的 System FLAG 可以控制如 IO, 可屏蔽中断,任务切换,调试等功能。 IF: 用来控制系统是否接受(可屏蔽的)外部中断请求 IF = 0 为屏蔽 NT: 此位用于控制 Chain interrupted 以及 called tasks, 该位会影响 IRET 指令的操作方式 RF: debug 有关的 flag TF: debug 有关的 flag,将处理器设置为单步执行模式,在这个模式下,所有的指令CPU都会产生一个异常,可以在每一个指令处停下来进行调试 VM: 用于进入 Virtual 8086 Mode 的 flag 这里不做解释 内存管理寄存器 与内存分段管理相关的寄存器,如全局描述符表,中断描述符表,也就是 GDT, LDT, IDT 和 Task 的描述信息存储用的寄存器 GDTR LDTR…

Read More Read More

[Linux 0.11] Draft 1 Assembly

[Linux 0.11] Draft 1 Assembly

REP前缀 对 源 和 目的 地址的数据进行某些操作 汇编指令形式为 rep <INSTRUCTION> INSTRUCTION 可以是 mov 系列(movb, movw, …) 也可以是 movs 系列,  还可以是cmps系列 该指令涉及到的寄存器有 标志寄存器(DF位) ECX ESI EDI ECX是计数器,用来指定操作的次数 ESI 指定源地址 EDI 指定目的地址 (很好记辣 Source Index (SI) Destination Index (DI)) 当处理 movs 的时候,如果 DF = 0 就是表示 ESI 指向要复制的块的开头,EDI 指向目的块的开头,DF = 0 的时候这两个就变成指向末尾了   JMPI 间接跳转 在实模式下,指定段地址和偏移量,将会设置IP以及CS 磁盘参数表 磁盘参数表存在中断向量0x41中 第二个磁盘的参数表存在0x46中   开启A20地址线 A20地址线关闭状态县 限制最多仅能寻址到1MB空间,更大的空间将会循环 开启方法如下:   字符串比较指令 SCAS, SCASB, SCASW, SCASD AX, ES, DI FLAGS(DF) 比较 AL(AX)(EAX) 与 ES:[DI] 的值,不保留结果,仅保留FLAGS。 根据后缀(B,W,D)的不同,比较的字节数也不同 根据方向位(D FLAG)决定比较之后DI寄存器是增长还是减少 可以与REP前缀一起使用…

Read More Read More

ArchLinux on MBP Installation Guide [大部分内容适合普通ArchLinux安装] 上

ArchLinux on MBP Installation Guide [大部分内容适合普通ArchLinux安装] 上

TL;DR 这两天OS X的虚拟机挂了,两个月的工作成果都丢了,因为本人是重度Archlinux依赖用户既然虚拟机这么难用(不能用全部内存&有快照损坏的风险)因而,唯一的选择就是在MBP上装Archlinux了。同时因为这是第一次用UEFI的模式Dual boot Archlinux + OS X,并且是第一次使用KDE而不是一直用的Gnome,因而踩了很多坑,所以本文会比较长( 本文介绍的是在MBP上Dualboot OS X + ArchLinux 使用KDE并配置好所需的必备软件的整个过程 ArchLinux 优点 如果连这个都不知道的话那么说明可能温豆师/污班图还是比较适合你((其实是很麻烦不想写因为已经写烂大街了 那么我们就开始吧OwO 材料准备 一个容量足够装下ArchISO的U盘 一台Macbook 畅通的网络 一些干粮(不然熬久了会饿的) rEFInd 不确定是否要禁用Apple的 Configuring System Integrity Protection 如果在操作引导过程中遇到问题,那么就设置一下这个 足够大的空间(用OS X 自带的 Disk Util 将要用来装Arch的空间划分出来,不用管文件系统,反正一会儿也得删) 引导安装 EFI 介绍 EFI boot是比 BIOS Boot 要先进的 boot 方式,古老的 BIOS 需要让CPU先进入16bit的实模式,仅仅能执行有限的一些 BIOS 提供的中断,并且 BIOS因为是直接用CPU的汇编编写的,对硬件平台有非常高的依赖,包括在BIOS下运行的驱动,尤其网络驱动,还要独立的给每一个架构的CPU编写一套独立的驱动,维护难度和开发难度都比较高,而 EFI 加载的驱动是以 EFI 字节编码 ,独立于CPU架构,因而更优,且BIOS无法支持大于 2TiB 的硬盘,因而对目前的很多机器这都是致命的瓶颈 (参考资料), 因而目前的个人PC开始采用 UEFI (EFI的一个更新版本)进行系统的引导。 引导过程以及ESP EFI 的引导不同与 BIOS,不需要将 Bootable program 放在 first sector ,而是将引导程序放在 ESP 中 ESP (EFI System Partition) 存放了EFI引导的必备程序,路径格式需要符合此规范<EFI_SYSTEM_PARTITION>/BOOT/BOOT<MACHINE_TYPE_SHORT_NAME>.EFI (此行摘自wikipedia) 例如/efi/BOOT/BOOT (具体识别哪个路径,以及能否识别不同的路径跟固件的实现有关,具体讨论如下…

Read More Read More

Eudyptula Challenge 1 — 8 总结

Eudyptula Challenge 1 — 8 总结

TL;DR (PS: 昨天竟然在一个非计算机领域的朋友口中听到TLNR好神奇) 从开始做eudyptula-challenge已经有一个多月了,也从原来的连第一关都会卡关好久到现在第八关只用了不到四十分钟的时间就写好了(虽然第八关的coding要求很简单,主要是要练习git send-mail的使用方法)随着Challenge的进行,之前关卡学到的一些东西难免会遗忘,因此在继续进行之前,现将前面学到的知识进行总结。注意: 本文不是Eudyptula Challenge的攻略,Eudyptula Challenge明确禁止了对答案代码的公布和分享,个人也赞同这种做法,毕竟是Challenge,需要你自己研究,而不是直接上网就能搜到答案(尽管现在的确能搜到答案了,比如某章鱼猫(( Intro What is Eudyptula Challenge? 这里就引用官网的介绍了 The Eudyptula Challenge is a series of programming exercises for the Linux kernel, that start from a very basic “Hello world” kernel module, moving on up in complexity to getting patches accepted into the main Linux kernel source tree. How does it work? 官网上也给了相应的介绍,不过窝认为从一个例子来介绍更为形象: Eudyptula-Challenge的评判系统是由”A set of convoluted shell scripts that are slow to anger and impossible to debug.”(摘自官网)来进行的,也就是全部自动评测(不过有的时候它的只能程度让我猜想后面有人在操作*****(大雾 以一个Task为例, 当你注册成功Eudyptula Challenge之后,会收到一封说明邮件以及你的第一个任务,之后你所有的任务提交都将通过在第一个任务里给你分配的ID以plain-text mail的形式进行。 当你收到一个Task的时候,根据相应的知识完成任务要求的代码之后,你需要通过纯文本邮件客户端(如mutt)将proof运行结果的输出作为正文,将写好的代码作为附件(这里不能用gmail的plain-text模式,因为它会把邮件附件转为base64格式)通过客户端发送给[email protected],之后你会收到一封通知邮件,表示系统已经成功收到你的提交(有可能收不到,因为脚本也许会卡住,这时候你如果等了一天还没收到,那你可以再次发送一封,不要频繁重发,小企鹅会生气的(不要问我怎么知道的Orz)) 通知邮件的格式是这样的 blabla,…

Read More Read More

Gmail + Mutt 报错 no authenticators found 解决办法

Gmail + Mutt 报错 no authenticators found 解决办法

初步测试是配置文件错误导致的,这里要注意几个配置不要填错 下面是一个可用的配置 set imap_user = ‘[email protected]’ set imap_pass = ‘************’ set folder = ‘imaps://imap.gmail.com/’ set spoolfile = +INBOX set record = “+[Gmail]/Sent Mail” set postponed = “+[Gmail]/Drafts” set smtp_url = ‘smtps://[email protected]’ set smtp_pass = ‘***************’ 注意: smtp_url 要填写 smtps://[email protected] 而不是下面的其中一种 smtps://[email protected]@smtp.gmail.com:465 smtps://[email protected]:587 。。。 填写正确之后, 可以使用mutt进行邮件的发送  

IO 多路复用 — select 和 poll

IO 多路复用 — select 和 poll

本文为 高性能网络编程学习 系列文章的第2篇 下面我们使用select, poll, epoll来进行IO multiplexing 本文我们演示 select 和 poll做IO多路复用 select的用法查看man page就可以得到,这里只列出遇到的问题 nfds参数,表明要watch的最大fd的数字 举例说明,如果你要watch的文件描述符为24 — 31,那么你应该将nfds设置为32 为了防止SIGPIPE信号终止程序运行,要讲SIGPIPE信号忽略掉 代码如下 /************************************************************************* > File Name: server.c > Author: VOID_133 > Mail: ################### > Created Time: Wed 21 Dec 2016 04:03:25 PM HKT ************************************************************************/ #define _GNU_SOURCE #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<pthread.h> #include<arpa/inet.h> #include<sys/socket.h> #include<sys/select.h> #include<string.h> #include<sys/errno.h> #define MAX_BUF_SIZE 1000 void usage(char *proc_name) { printf(“%s [port]\n”, proc_name); exit(1); } void setnonblock(int fd) { int old_flag = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, old_flag | O_NONBLOCK); return ; }…

Read More Read More

Linux Kernel Development Resources

Linux Kernel Development Resources

Here are some resources for digging into linux kernel development (Keep updating) Books Understanding Linux Kernel [ULK] Linux Kernel Development [LKD] Linux Driver Development [LDD] Linux Kernel Module Programming Guide [LKMPG] Linux in a Nutshell   Sites Eudyptula Challenges: A step-by-step challenge for kernel newbies to get familiar with kernel. it promise you can get into kernel development after finish all tasks http://eudyptula-challenge.org/ The Linux Documentation Project: Website provide useful resources for linux & kernel http://www.tldp.org/ The Linux Kernel Archives: Official Kernel…

Read More Read More