- 博客(72)
- 收藏
- 关注
原创 如何在Linux上构建Raspberry Pi虚拟环境
下面我们来讲讲如何使用QEMU来仿照树莓派环境。这里首先先分成两大类。第一类是跑比较老的,安全性较低的老树莓派,主要指代的是22年4月份发布之前的版本,这个版本当中,树莓派镜像自己内部就配置了一份默认的账户密码。对于之后的版本则不配备这种默认的账号密码。因此,我们需要区分出两种装载模式。为了省力,我们使用人家已经配置好了的。
2024-07-29 22:15:31
860
原创 Windows系统编程API 学习之路
GetLastError公开的错误代码机制也可供应用程序使用,以类似的方式设置错误代码。这是通过在当前线程上调用SetLastError with error来设置的。函数可以使用许多预定义的错误代码之一,也可以定义自己的错误代码。为了防止与系统定义的代码发生任何冲突,应用程序应在定义的错误代码中设置第29位。以下是一个使用此技术的函数示例:if (!ok) {if (!ok) {
2024-07-29 09:29:47
1079
原创 浅聊如何在Windows上使用GCC14.1且使用C++23的std::print输出Hello, World
笔者这几天也在简单的学习现代C++23,这边也是听闻GCC出14.1了支持更好了,因此准备尝试以下使用GCC14玩玩C++23。
2024-07-27 10:49:11
401
1
原创 使用QPdf库构建的基于Qt的PDF浏览器
本人最近手搓了一个使用了QtPDF库的Qt框架的PDF浏览器,Github地址在:https://github.com/Charliechen114514/CCPDF_View针对任何问题欢迎提Issue,代码供各位看官批评指正
2024-07-27 08:54:27
244
原创 STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置
为什么配置这样的一个环境呢?鄙人受够了Keil5那个简陋的工作环境了,实在是用不下去,调试上很容易跟CubeMX的代码产生不协调导致调试——发布代码不一致造成的一系列问题。CubeIDE虽说不错,但是它的代码辅助功能和构建系统实在不敢恭维,经常出现Makefile未同步导致符号定义冲突,亦或者是埋下了潜在的程序bug。也有人尝试使用Keil Assistance + VSCode + Keil分工写代码与烧录,这听起来不错,但是调试并不方便,常常要来回奔波,实在是有些麻烦。
2024-07-26 20:53:54
1101
原创 [迫真保姆级教程]在Windows上编译可用的Tesseract OCR in C++ 并部署在Visual Studio与Qt6上
本教程是一个截止至2024年7月11日最新的,旨在编译可以运行在x86_64结构上的,其操作系统是Windows11的机器上的,谷歌著名的光学识别库Tessereact OCR。本篇教程将会编译产生:使用msys环境下的,使用mingw64编译器编译的Tessereact OCR动态库使用基于vcpkg的,于msvc19编译器编译的Tessereact OCR动态库文章的最后将会放上Github仓库与自己写的极简的包装器(问就是手动释放折磨人,智能指针万岁!MSYS2。
2024-07-11 13:40:19
1227
原创 解决Ubuntu虚拟机卡死的一种可能情况:文件系统可用率不足
界面挂在/dev/sda3上开不了机了,情况可能的很多,由于我这里是虚拟机,给内存才分配了20G,我一猜就是硬存炸了,果不其然。。。
2024-07-08 08:46:57
655
原创 Coding:小写一个debugfs
上一次整活还是在上一个月,写了一个简单的module并且熟悉了module的挂载查看和卸载。这一次我们自然玩一个大的,就是利用linux的debugfs API写一个调试文件系统。事实上,底层的API全写好了,我们就是简单的调调API就成的事情!
2024-07-04 18:56:31
356
原创 QEMU + Vscode + Arm Arch‘s Linux调试小记
前几天看到了一篇讲授如何调试ARM Linux内核的文章,这里现在记录一下调试ARM Linux内核的办法。
2024-06-19 13:46:57
1368
1
原创 关于如何在Arch Linux上编写自己的第一个module
前一段时间一直想深入学习编写一个module插入到自己的内核当中,但是网上的资料基本上全都针对的Ubuntu和Debian等流行的Linux发行版,这里打算简单的记录一波博客。
2024-06-01 16:38:51
645
原创 CPP Con 2020:Type Traits I
这个其他程序可以是自己也可以是其他程序。确实有点多此一举这个例子,但是这里展现出来元函数的一个重要特点,他可以完成类型操作,这里就是存储了一个type信息,我们之后到哪里都可以传递他进入其他函数内部使用!在C++里,元编程是使用模板完成的,一个带有0个或者是多个模板参数的类是我们的元编程的核心!为了查看type_traits是如何实现的,我们首先来看看一个简单的例子:is_void,他判断一个类型是不是void!啊哈,关于这种非参数模板不是我们的重点,我们已经看到这里的元编程特性可以展现更多的事情。
2024-05-24 22:55:38
972
原创 深入研究Qt Meta - Object System
这篇文章我打算研究一下QMetaObject System,也就是Qt自己构建起来的元对象系统。
2024-05-18 19:56:09
1234
原创 Qt 刷一个计算器
注意本博客使用的solution并不是最简单的方案,这是为了体验一下QUiTools和Qt6所支持的QuiLoader所写。这个计算器特别简单:当你点击中间的"+"时可以切换运算符号,左右两侧都是简单的SpinBox,当你点击=或者变动数字或者变动运算符的时候会自动刷新结果。
2024-05-17 21:55:36
823
原创 宏内核与微内核
这是小文章分享,所有的中文都是机翻()大致来说,操作系统本身由两部分组成:内核空间(特权模式)和用户空间(非特权模式)。对于宏内核:在内核空间中包含所有基本服务有三大缺点:内核大小太大、缺乏可扩展性和可维护性差 为了克服这些可扩展性和可维护性的限制,微内核的想法出现在20世纪80年代末。微内核不再是一个系统服务块,而是代表了几个基本的抽象和基元,用于控制进程之间以及进程与底层硬件之间的通信。微内核领域的研究表明,创建混合内核1不是最好的解决方案,而是一个纯微内核,它必须非常小。
2024-05-15 16:05:18
332
原创 Linux 用户进程启动与Systemd
我们都知道,Linux在内核的初始化自身的流程结束后,就会将程序流的运行转到用户态,也就是进入init进程流之后,他会按照这个流程进行初始化:init进程初始化基础的底层服务:比如说udevd和syslogd网络配置中高层服务,比如说cron和一些打印服务乱七八糟的登录会话。
2024-05-09 16:58:06
477
原创 How Linux Works I - How Linux Start Up
本文章着重分析了Linux启动文件,从而理解Linux启动的基本流程
2024-05-05 20:55:25
1216
原创 程序的执行
进程可以指定它的执行域,这是通过设置进程描述符的personality字段,以及把相应exec_domain数据结构的地址存放到thread_info结构的exec_domain字段来实现的。此外,动态链接的程序的可移植性也不如静态链接的好,因为当系统中所包含的库版本发生变化时,动态链接的程序运行时就可能出现问题。每个高级语言的源码文件都是经过几个步骤才转化为目标文件的,目标文件中包含的是汇编语言指令的机器代码,它们和相应的高级语言指令对应。取而代之的是,要执行的新程序已被映射到进程的地址空间。
2024-05-04 08:34:51
1079
原创 进程之间的通信
为提高效率,仍然要读的数据可以分散在几个未填充满的管道缓冲区内:事实上,在上一个管道缓冲区没有足够空间存放新数据时,每个写操作都可能会把数据拷贝到一个新的空管道缓冲区。)的缩写,通常指允许用户态进程执行下列操作的一组机制: (1). 通过信号量与其他进程进行同步 (2). 向其他进程发送消息或者从其他进程接收消息和其他进程共享一段内存,相应的异常处理程序确定引起缺页的地址是在进程的地址空间内,且相应的页表项为空;换而言之,把异常中断的进程所做的修改退回,而其他进程所做的修改仍然能反映信号量的状态。
2024-05-03 16:34:43
17
原创 深入学习Linux内核页框回收
目录算法1.选择目标页2.PFRA设计3.反向映射3.1.匿名页的反向映射3.2.try_to_unmap_anon()函数3.3.try_to_unmap_one()函数映射页的反向映射优先搜索树try_to_unmap_file()函数PFRA实现最近最少使用(LRU)链表在LRU链表之间移动页mark_page_accessed()函数page_referenced()函数refill_inactive_zone()函数内存紧缺回
2024-05-03 16:18:22
762
原创 页高速缓存
目录页高速缓存address_space对象基树页高速缓存的处理函数查找页–find_get_page()增加页–add_to_page_cache()删除页更新页基树的标记把块存放在页高速缓存中块缓冲区和缓冲区首部管理缓冲区首部缓冲区页分配块设备缓冲区页释放块设备缓冲区页在页高速缓存中搜索块__find_get_block()函数__getblk()函数__bread()函数向通用块层提交缓冲区首部submit_bh(
2024-05-03 15:56:25
50
原创 深入理解Linux内核:访问文件
目录五种常见的模式读写文件从文件中读取数据函数do_generic_file_read()普通文件的readpage方法块设备文件的readpage方法文件的预读page_cache_readahead()函数handle_ra_miss()函数写入文件普通文件的prepare_write和commit_write方法块设备文件的prepare_write和commit_write方法将脏页写到磁盘内存映射内存映射的数据结构创建内存映射
2024-05-03 15:33:29
59
原创 深入学习Linux系统 - 块设备
除了调度队列外,“最后期限”算法还使用了四个队列。其中的两个排序队列分别包含读请求和写请求,其中的请求是根据起始扇区数排序的。另外两个最后期限队列包含相同的读和写请求,但这是根据它们的“最后期限”排序的。引入这些队列是为了避免请求饿死,由于电梯策略优先处理与上一个所处理的请求最近的请求,因而就会对某个请求忽略很长一段时间,这时就会发生这种情况。请求的最后期限本质上就是一个超时定时器,当请求被传给电梯算法时开始计时。
2024-05-03 15:13:10
939
原创 I/O体系结构和设备驱动程序
I/O体系结构为了确保计算机能够正常工作,必须提供数据通路,让信息在连接到个人计算机的CPU、RAM和I/O设备之间流动。这些数据通路总称为总线,担当计算机内部主通信通道的作用。所有计算机都拥有一条系统总线,它连接大部分内部硬件设备。一种典型的系统总线是PCl(Peripheral Component Interconnect)总线。目前使用其他类型的总线也很多,例如ISA、EISA、MCA、SCSI和USB。典型的情况是,一台计算机包括几种不同类型的总线,它们通过被称作“桥”的硬件设备连接在一
2024-05-03 14:29:47
713
原创 一般的文件系统样板(Ext2和Ext3)
目录Ext2Ext2的一般特征Ext2磁盘数据结构超级块索引节点表索引节点的增强属性访问控制列表各种文件类型如何使用磁盘块普通文件目录符号链接设备文件、管道和套接字Ext2的内存数据结构Ext2的超级块对象Ext2的索引节点对象创建Ext2文件系统Ext2的方法Ext2超级块的操作Ext2索引节点的操作Ext2的文件操作管理Ext2磁盘空间创建索引节点删除索引节点数据块寻址文件的洞分配数据块释放数
2024-05-03 14:01:44
593
原创 VFS 虚拟文件系统(下)
目录文件系统安装安装普通文件系统do_kern_mount()函数分配超级块对象安装根文件系统阶段1:安装rootfs文件系统init_rootfsinit_mount_tree阶段2:安装实际根文件系统卸载文件系统路径名查找标准路径名查找父路径名查找符号链接的查找VFS系统调用的实现open()系统调用read()和write()系统调用close()系统调用文件加锁Linux文件加锁文件锁的数据结构FL_FLO
2024-05-03 13:41:39
940
原创 VFS 虚拟文件系统(上)
概念虚拟文件系统(Virtual Filesystem)也可以称之为虚拟文件系统转换(Virtual Filesystem Switch),是一个内核软件层,用来处理与Unix标准文件系统相关的所有系统调用。其健壮性表现在能为各种文件系统提供一个通用的接口。可以认为它屏蔽了不同文件系统之间的实现细节转而依赖它们的接口。VFS支持的文件系统可以划分为三种主要类型: 磁盘文件系统 这些文件系统管理在本地磁盘分区中可用的存储空间或者其他可以起到磁盘作用的设备(比如说一个USB闪存)。VFS支
2024-05-03 13:40:56
92
原创 Linux深入理解内核 - 信号
此外,当内核打算恢复进程的正常执行时,内核态堆栈不再包含被中断程序的硬件上下文,因为每当从内核态向用户态转换时,内核态堆栈都被清空。因此,所处理的信号的另一次出现不能中断信号处理程序,所以,信号处理函数不必是可重入的。这个附加的检查解决了在向一个正在被杀死的进程发送消息时出现的竞争条件的问题:如果另外一个多线程应用正以足够快的速度创建轻量级进程,信号就可能被传递给一个错误的进程。处理这样的信号,即信号可能在进程运行期间的任一时刻请求把进程切换到一个信号处理函数,并在这个函数返回以后恢复原来执行的上下文。
2024-05-03 11:39:53
760
原创 深入理解Linux内核 - 系统调用
欸!回想起来我们用户层是如何与内核层进行交流的呢?或者说是如何请求服务的呢?那正是使用系统调用这个概念!使得用户层同下方的内核层架起交流的大桥!回顾一下优点:使得编程更加容易,把用户从学习硬件设备的低级编程特性中解放出来.(你真的不需要看手册写程序!极大提高了系统的安全性,内核在试图满足某个请求前在接口级就可检查这种请求的正确性.接口使得程序更具有可移植性.接口使得程序更具有可移植性.Unix系统通过向内核发出系统调用实现了用户态进程和硬件设备间的大部分接口.。
2024-05-03 10:37:39
967
原创 深入学习Linux内核 - 进程地址空间
我们在之前更加底层的层面看到了:内核中通过这些函数获得动态内存kmallocvmallocvmalloc_32。使用上述简单方法基于以下两个原因:内核是操作系统中优先级最高的成分。如某个内核函数请求动态内存,则必定有正当的理由发出请求,因此,没道理试图推迟这个请求。内核信任自己。所有的内核函数都假定没错误,故内核函数不必插入针对编程错误的任何保护措施。给用户态进程分配内存时,情况完全不同:进程对动态内存的请求被认为是不紧迫的。如进程的可执行文件被装入时,进程不一定立即对所有的代码页进行访问。
2024-05-03 10:13:14
968
原创 Linux内核深入理解 - 内存管理(下)
但,如动态内存变得极其稀有以至于所有普通内存分配请求都将失败的话,那么作为最后的解决手段, 内核成分就能调特定的内存池函数提取储备得到所需的内存。一样,内核修改主内核页全局目录和它的子页表中的相应项,但映射第4个GB的进程页表的项保持不变。实际上, 如空闲内存不足,则每个内存管理区一般会被检查几遍,每一遍在所请求的空闲内存最低量的基础上使用更低的阈值扫描。但,一般而言,内存池能被用来分配任何一种类型的动态内存,从整个页框到使用kmalloc分配的小内存区。这些页框中既包含已分配的对象,也包含空闲的对象。
2024-05-03 09:43:11
829
原创 深入理解Linux 内核 内存管理(上)
RAM中,剩下的自由部分被称为动态内存!因为这不仅是内进程所需要的宝贵资源,也是内核执行本身所需要的宝贵资源!实际上整个系统的性能都高度取决于如何有效的管理动态内存!因此内存管理是操作系统中非常重要的话题之一!
2024-05-03 09:42:04
1080
原创 Linux内核深入学习 - 进程调度
如current进程因不能获得必须的资源而要立刻被阻塞,就直接调调度程序。此时,要阻塞进程的内核路径按下述步骤:把current进程插入适当的等待队列把current进程状态改为或调schedule检查资源是否可用。如不可用就跳到2。一旦资源可用,就从等待队列中删除current。也可把current进程的标志设置为1,而以延迟方式调用调度程序。由于总是在恢复用户态进程的执行前检查这个标志的值,所以schedule将在不久后的某个时间被明确地调用。以下是延迟调用调度程序的典型例子:当。
2024-05-03 08:52:59
923
原创 Linux内核深入学习 - 定时测量
为了准备讨论稍后的进程调度等相关内容(这是因为很多计算机的活动高度依赖定时器),我们需要首先讨论一下定时驱动。这通常对用户并不可见!为了进行这些跟定时高强度相关的操作程序,必须能从每个文件中检索到文件的最后访问时间及时间戳,因此这些的时间标记是必须由定时测量来完成的。Linux内核必须完成主要两种定时测量:保存当前的时间和日期以便能通过time()ftime()和系统调用把它们返回给用户程序,也可以由内核本身把当前时间作为文件和网络包的时间戳维持。
2024-05-02 08:55:28
614
原创 Linux内核深入学习 - 中断与异常(上)
中断通常被定义为一个事件:让事件改变处理器执行的指令顺序这样的事件,与CPU芯片内外部硬件电路产生的电信号相对应!中断通常分为同步中断与异步中断:同步中断指的是当指令执行时,由CPU控制单元产生的。之所以称为同步,是因为只有在一条指令终止执行后,CPU才会发出中断!异步中断是由其他硬件设备依照CPU时钟信号随机产生的在英特尔微处理器手册中:也会把同步和异步中断分别称为异常和中断中断则是由间隔定时器或者io设备产生的,举个例子你敲击键盘的时候,你的一次按键就会引发一个中断,希望操作系统介入进行处理。
2024-05-01 11:05:09
990
1
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人