本站采用 hexo 架构,部署在 github pages 上,采用 github 作为图床。建议在能够流畅访问 github 的网络环境下浏览。
看见这幅美丽的画了吗?看见了说明你能看见这幅画 (bushi)。
关于左边的这个抽象的双 tags 旋转动画,我也在 diss 它,有时间再把它 ban 掉了。
维修计划:
- 缩进调整
- 关闭 tags 动画
本站采用 hexo 架构,部署在 github pages 上,采用 github 作为图床。建议在能够流畅访问 github 的网络环境下浏览。
看见这幅美丽的画了吗?看见了说明你能看见这幅画 (bushi)。
关于左边的这个抽象的双 tags 旋转动画,我也在 diss 它,有时间再把它 ban 掉了。
维修计划:
活动 | 时间/deadline |
---|---|
大创二阶段 | 03/07 - 03/22 |
阶段一 | 进度 |
---|---|
近纲书评 | |
毛概社会实践材料 0426 | |
OS Lab2 验收 | |
Compiler Lab3 | |
SEEC Lab4 Lab5 | |
初次接触飞腾开发板,我的 ubuntu 系统无法正常使用 USB 串口线连接开发板,问题集中在 CH341 的驱动上面。
物理线路正确连接后,查询 ttyUSB 设备信息,连接后立即 disconnected。
1 | lg@ubuntu:~$ sudo dmesg | grep ttyUSB |
多次尝试后又得到如下报错信息:
1 | lg@ubuntu:~$ sudo dmesg | grep ch341 |
发现是 brltty
服务占用了设备接口。
卸载 brltty
即可:
1 | sudo apt remove brltty |
brltty
的冲突解决后,ls /dev
即可(应该?)看见 ttyCH341USB0
设备,但无法成功连接/连接不稳定,甚至无法识别。
原因是驱动与内核版本不适配。先卸载 ch341 驱动。
1 | sudo rmmod ch341 |
然后按该帖步骤正确安装驱动:
Ubuntu系统上ttyUSB被挂载为ttyCH341USB_ubuntu ch341-CSDN博客
如遇到签名无效则参考下帖:
https://blog.csdn.net/qq_28680277/article/details/129162559
然后重新接入开发板,即可识别。
在计算机体系结构中,特别是在涉及保护模式的操作系统中,选择子是用于指定描述符表(GDT或LDT)中的描述符的索引。选择子包含了几个关键部分:
选择子是放在段选择寄存器中的16位值,通过它,处理器可以访问描述符表中相应的段描述符,进而获得段的具体信息,如基地址和界限等。
描述符是在保护模式下操作系统中使用的一个数据结构,用于定义内存段的属性和访问权限。每个描述符通常存储在全局描述符表(GDT)或局部描述符表(LDT)中。描述符中包含了以下关键信息:
描述符确保了内存段的保护和正确的访问,是实现多任务和内存保护的基础。通过这些信息,操作系统能够管理不同任务的内存访问权限,防止未授权访问,同时允许合法的访问和操作。
GDT(Global Descriptor Table)和LDT(Local Descriptor Table)是在保护模式下使用的两种描述符表,用于定义内存段的属性和访问权限。它们的具体作用和特性如下:
在1.44M软盘上,FAT前三个字节的值是固定的0xF0、0xFF、0xFF,用于表示这是一个应用在1.44M软盘上的FAT12文件系统。本来序号为0和1的FAT表项应该对应于簇0和簇1,但是由于这两个表项被设置成了固定值,簇0和簇1就没有存在的意义了,所以数据区就起始于簇2
FAT项的值代表文件的下一个簇号
值大于或等于0xFF8,表示当前簇已经是本文件的最后一个簇
值为0xFF7,表示它是一个坏簇
静态链接
动态链接
动态链接器自举
动态链接器本身也是一个不依赖其他共享对象的共享对象,需要完成自举。
装载共享对象
将可执行文件和链接器自身的符号合并成为全局符号表,开始寻找依赖对象。加载对象的过程可以看做图的遍历过程;新的共享对象加载进来后,其符号将合并入全局符号表;加载完毕后,全局符号表将包含进程动态链接所需全部符号。
重定位和初始化
链接器遍历可执行文件和共享对象的重定位表,将它们 GOT/PLT 中每个需要重定位的位置进行修正。完成重定位后,链接器执行 .init 段的代码,进行共享对象特有的初始化过程(例如 C++ 里全局对象的构造函数)。
转交控制权
完成所有工作,将控制权转交给程序的入口开始执行。
避免 gcc 进行 glibc 链接。
可执行文件的虚拟地址空间默认从 0x08048000
开始分配。这个地址被选中是因为它足够高,可以让程序员容易地识别出指针和数字之间的差别,同时又低足够避免和系统库及内核空间发生冲突。
1 | typedef struct BPB { |
起因是由于 512G 的 ssd 一盘双系统有些吃紧,ubuntu 的 home 和根分区逐渐膨胀,希望重新分区。Gparted 扩展分区仅限于相邻右侧空闲空间,构造逻辑卷组又比较担心对后续可能的系统迁移有所阻碍,于是决定提前进行系统迁移实验。
网上主流的方法有 systemback 备份,dd 注入,以及 Clonezilla 再生三种手段。对于 systemback 似乎我的主板不太支持,换了三个 U 盘制作四五个镜像都没办法正常打开。dd 与 Clonezilla 原理差不多,不过 Clonezilla 是通过制作镜像实现文件迁移,因此自带备份效果。
这里主要讲讲 Clonezilla 系统迁移。最近实在没什么时间,就写个大纲吧 \^_\^。
请提前备份重要数据!
请提前准备三个 U 盘,两个引导盘 8G 左右即可,一个需要大些,用于存储镜像。
在 linux 系统中,万物皆文件,文件即万物。迁移系统只需将系统中所有分区搬到目标位置,然后修改启动项即可。
使用 Clonezilla 备份之前需要先制作引导盘,可参考我之前的文章(ubuntu 相关配置)。
然后还需要一个数据盘,进入再生龙界面后选择克隆分区到镜像,选中 ubuntu 的分区即可。
使用 Ubuntu 引导盘进入 try 界面,利用 Gparted 建立与原系统分区格式相同的分区,且分区容量需大于原分区。
再次进入 Clonezilla 界面,选择镜像导出到分区,由于一次性选择超过一个分区无法制定目标盘,因此一次选择一个分区注入到目标位置即可。
查看分区 uuid
1 | $ sudo blkid |
新分区的 uuid 与原分区不同,修改 /etc/fstab
中的条目,将对于的 uuid 替换为实际 uuid 即可。
原系统与新系统的 grub 引导会冲突,导致两个系统都无法进入。我的做法是将原系统删除,然后使用 boot-tools
自动修复 grub。
这里主要是我自身的原因。迁移之前我将系统原 nvidia-535 驱动换为了 nvidia-545,导致一个内核崩溃,其余旧版内核可以正常运行。迁移后问题逐渐显现出来,与 gnome 有所冲突,部分包无法显现出来。
解决办法是在图形界面中打开附加驱动
,更换回推荐驱动,并删除有问题的内核,重新进行安装。关于 gnome 相关问题,比如桌面图标消失、设置栏消失等小问题就慢慢修复吧。
微信官方对 linux 系统一直都没有很好的支持,虽然可以用 wine 来兼容 windows 微信,但安装和适配都较为复杂。2022 年 1 月,麒麟软件与腾讯公司联手推动了基于 Linux 平台的原生微信适配工作。优麒麟的原生微信也同样支持 Ubuntu 系统,因此是一个较好的选择。
阅读完本文所有内容再考虑进行安装。
软件的安装参考如下链接:
2024如何在Ubuntu上安装原生微信wechat weixin - 知乎
安装教程中的核心部分为:
1 | sudo apt update |
注意到除了安装的命令之外,还出现了比较特别的两行:
1 | sudo cp /etc/lsb-release /etc/lsb-release.Ubuntu |
其中涉及三个文件:lsb-release
、lsb-release.Ubuntu
、lsb-release.wechat
,下面为了方便简称为 lsb
。
lsb
记录了系统的 Linux 发行版信息,包括发行版的标识、版本号和一些其他信息。强烈不建议更改。
lsb.Ubuntu
是对系统原 lsb
文件的备份。
lsb.wechat
是适配微信的优麒麟系统发行版信息。1 | lg@ubuntu:/etc$ cat lsb-release.Ubuntu |
这两条 cp
指令会将系统元 lsb
备份到 lsb.Ubuntu
,然后用优麒麟系统的 lsb
文件替代。这么做的是因为微信的登陆接口会读取系统的发行版信息,若非优麒麟则无法登陆。操作比较恶心,属于是反向适配了。
目前我的解决办法是采用脚本启动,启动前用优麒麟的 lsb
替换系统 lsh
,然后开始计时,十五秒后替换回来,这意味着在启动微信后十五秒内必须完成登陆,且十五秒内不可强制断电关机。
1 | # /opt/WeChat/files/wechat.sh |
脚本里的两条 sudo 需要在系统配置中添加免密设置。
打开终端,并使用以下命令编辑 /etc/sudoers
文件:
1 | sudo visudo |
在打开的文件中,添加如下规则(假设你的用户名为 lg
):
1 | lg ALL=(root) NOPASSWD: /bin/cp /etc/lsb-release.wechat /etc/lsb-release |
注意:编辑 /etc/sudoers
文件时要格外小心,确保不要修改错误并保存。建议使用 visudo
命令编辑,因为它会在保存前检查语法错误。
因为启动方式发生变化,我们需要修改桌面图标,换为脚本启动。
(由于我的图标是自己创建的,因此文件名可能有所不同,需要注意。)
打开图标配置:
1 | sudo vim /usr/share/applications/wechat.desktop |
将 Exec
条目更换为执行脚本。
1 | Exec=bash /opt/WeChat/files/wechat.sh |
然后重启即可运用配置。
1 | sudo apt purge atzlinux-v12-archive-keyring |
关于微信原生这个问题我也是今天搜索的时候偶然发现,不知道其中是否存在更多的漏洞/问题,这种安装方式还是有待斟酌的。
制作一个 FAT12 镜像查看器。
支持命令:ls, ls -l, cat。
学长的文章(写得好好): FAT12镜像查看工具_解析fat32镜像文件-CSDN博客
cat 需要访问数据区。
ls、ls -l 需要访问目录区。
从第 11
个字节开始的 25
个字节构成一个较为特殊的结构 BPB(Bios Parameter Block)
。
1 | typedef struct BPB { |
FAT1
与 FAT2
互为备份,所以理论上两张表是一样的。
FAT 表项的值的含义:
>= 0xFF8
,该簇已经是文件最后一个簇。= 0xFF7
,表示一个坏簇。簇的编号与 FAT 表中的索引:每个簇都有一个唯一的编号,FAT 表中的项索引与这些簇的编号对应。例如,第一个簇的编号对应 FAT 表中的第一个项,第二个簇对应第二个项,依此类推。
一个目录项占据 32
字节。
1 | typedef struct RootEntry { |
由此,归结起来,FAT12访问文件的基本操作为:
1 | typedef struct Entry{ |
位 | 掩码 | 描述 |
---|---|---|
0 | 0x01 | 只读 |
1 | 0x02 | 隐藏 |
2 | 0x04 | 系统 |
3 | 0x08 | 卷标 |
4 | 0x10 | 子目录 |
5 | 0x20 | 档案 |
6 | 0x40 | 设备(内部使用,磁盘上看不到) |
7 | 0x80 | 没有使用 |
0x0F 是 LFN。
整体是做一个深度优先遍历。从本质上来说,本次实验难度仅存在于定位数据。这里列出一些值得注意的点。
数据区起始于簇 2。事实上这句话我到现在还没读懂,我是通过插入空簇来实现下标与需求匹配的。
FAT 每个表项占 1.5 个字节,因此每次提取三个字节计算两个表项。
若这三个字节十六进制表示为 AB CD EF(按地址从小到大排列)
那么有
1 | 前一个FAT = DAB |
由于 FAT12 文件名仅支持至多 8 位大写的文件名与至多 3 位大写的后缀,若文件名出现小写,在镜像中可能会出现一些 Entry 作为补丁。我们可以通过这些项获取原文件名,但在访问的适合需要将这些项剔除。
插件 Hex-editor。
1 | myString getSpecialName(Entry entry); // 获取特殊文件名(前一个目录的) |
框架中出现的这些属于扩展功能,不需要实现。(某人没看题QwQ)
暂时先不考虑 LFN 的情况。
1 | #include <cstring> |