趣味魔法项目 LinuxPDF —— 在 PDF 中启动一个 Linux 操作系统
最近,一位开源爱好者开发了一个LinuxPDF 项目(ading2210/linuxpdf: Linux running inside a PDF file via a RISC-V emulator),它的核心功能是在一个 PDF 文件中启动并运行 Linux 操作系统。它通过巧妙地使用 PDF 文件格式中的 JavaScript 功能,结合 Emscripten 技术,将一个 RISC-V 仿真器嵌入到 PDF 文件中,从而使得 Linux 系统能够在 PDF 中启动。并且可以直接在Chrome浏览器中直接打开(https://linux.doompdf.dev/linux.pdf),打开后如下图所示:
项目工作原理
1. PDF 文件支持 JavaScript
首先,提到 PDF,人们通常想到的是静态文档,通常包含文字、图片等元素,用于文档共享和打印。然而,PDF 文件实际上可以包含多种功能,包括嵌入 JavaScript。这使得 PDF 文件不仅仅局限于显示内容,还可以在其中嵌入交互式功能,甚至可以做一些很酷的计算和模拟任务。
这个项目的目的正是展示这种潜力。它通过将 RISC-V 仿真器 编译为 JavaScript,并嵌入到 PDF 文件中,模拟一个完整的 Linux 系统。虽然这并不意味着 PDF 文件会直接变成一个“操作系统”,但它展示了如何在不离开 PDF 阅读器的情况下运行一个简化的操作系统。
2. 技术实现:Emscripten 和 asm.js
为了将 Linux 系统放入 PDF 中,开发者使用了 Emscripten,一个开源工具链,能够将 C/C++ 代码编译为 JavaScript。Emscripten 支持将代码编译成两种格式:asm.js
或 WebAssembly
。在这个项目中,使用的是 asm.js,一种 JavaScript 子集,专为提高性能而设计,允许 C 代码在浏览器中高效运行。
这个小小的“奇迹”是如何实现的呢?首先,开发者使用 TinyEMU,一个针对 RISC-V 架构 的仿真器,将它编译成 asm.js
。这个 RISC-V 仿真器被嵌入到 PDF 文件的 JavaScript 中。换句话说,PDF 文件通过嵌入 JavaScript 代码来模拟一个完整的计算机系统。这个仿真器可以启动 Linux 内核,并运行一个简单的文件系统(带有 BusyBox)。
3. 虚拟化 Linux 系统
通过在 PDF 中嵌入该仿真器,用户可以启动一个 RISC-V 架构的 Linux 系统,尽管它的性能非常低。Linux 内核和文件系统被嵌入到 PDF 中,用户可以在 PDF 阅读器中使用它进行简单的操作。
4. 在 PDF 中交互:输入和输出
输入:
输入是通过虚拟键盘实现的,用户可以点击键盘上的按钮来向仿真器发送输入。仿真器的输入包括键盘按键,用户可以通过文本框输入命令,控制虚拟机。它还支持一些基本的输入设备模拟,如鼠标点击等。
输出:
仿真器的输出通过文本框来显示。每一行像素都对应一个单独的文本框,里面显示的是 ASCII 字符,这就是模拟器显示图形的方式。虽然这种方式比较原始,但它能够有效地在 PDF 文件中实现图形输出。
5. 解决性能问题:不可避免的“慢”速度
虽然这个项目在技术上非常有趣,但它也面临一个严重的性能瓶颈。由于 V8 引擎(Chrome PDF 引擎使用的 JavaScript 引擎)禁用了 JIT 编译,这导致代码执行效率极低,仿真速度非常慢。例如,Linux 内核启动可能需要 30 到 60 秒,这比正常运行慢了超过 100 倍!然而,这一切都可以理解,因为 JavaScript 的性能远远不如原生 C 代码,而且运行环境(PDF 阅读器)也是有限制的。
项目构建和运行
1. 克隆项目
首先,克隆该 GitHub 仓库。
git clone https://github.com/ading2210/linuxpdf.git
2. 构建
使用虚拟环境来安装依赖:
python3 -m venv .venv
source .venv/bin/activate
pip3 install -r requirements.txt
./build.sh
注意:
如果你想构建 64 位版本而不是 32 位版本,编辑 build.sh 文件,并将 BITS="32" 改为 BITS="64"。
build.sh 脚本会自动下载 Emscripten 1.39.20 版本。
你必须在 Linux 上构建。
生成的文件将位于 out/ 目录下。
3. 运行
构建完成后,你可以在本地启动一个 Web 服务器:并通过浏览器访问该 PDF 文件
cd out; python3 -m http.server
通过这些步骤,就可以通过浏览器访问该 PDF 文件,并在浏览器中运行一个嵌入了 Linux 系统的 PDF 文件,体验一个虚拟机在 PDF 阅读器中的运行。
总结
LinuxPDF 项目结合了深奥的计算机科学原理与一些非常酷的实现方式,展示了如何通过 PDF 文件实现 Linux 仿真。它不仅是对 PDF 格式潜力的挑战,也是对 JavaScript、Emscripten 和仿真技术的有趣展示。尽管这个项目的速度远远不能与传统的操作系统相比,但它却展示了PDF 文件格式在现代技术中可能扮演的新角色——不仅仅是静态文档,而是一个可以嵌入并运行计算任务的环境。这个项目证明了,PDF 不仅仅能用来展示信息,还能用来处理计算任务,甚至运行嵌入式系统。
此外,这种 PDF 中嵌入操作系统 的创意能够启发更多创新的应用,比如:
- 在受限的环境中运行计算任务(如教育工具、嵌入式设备模拟)。
- 用于将操作系统或应用程序打包到单一文件中,方便分发和使用。
- 作为跨平台应用,尽管这需要处理性能和兼容性的问题。
相关文章:

趣味魔法项目 LinuxPDF —— 在 PDF 中启动一个 Linux 操作系统
最近,一位开源爱好者开发了一个LinuxPDF 项目(ading2210/linuxpdf: Linux running inside a PDF file via a RISC-V emulator),它的核心功能是在一个 PDF 文件中启动并运行 Linux 操作系统。它通过巧妙地使用 PDF 文件格式中的 Ja…...

win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一
;运行效果 ;win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一 ;生成2条横的跟踪条,分别设置不同的数值范围,设置不同的进度副度的例子 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>…...

mars3d接入到uniapp的时候ios上所有地图的瓦片都无法加载解决方案
用的是【Mars3d】官网的uniapp的仓库,安卓没有问题,但是ios的不行 相关链接 mars3d-uni-app: uni-app技术栈下的Mars3D项目模板 解决方案:感觉所有图片请求全被拦截了 uniapp的ios内核不允许跨域,需要先把瓦片下载后转base64&…...

使用 Notepad++ 编辑显示 MarkDown
Notepad 是一款免费的开源文本编辑器,专为 Windows 用户设计。它是替代记事本(Notepad)的最佳选择之一,因为它功能强大且轻量级。Notepad 支持多种编程语言和文件格式,并可以通过插件扩展其功能。 Notepad 是一款功能…...
wordpress主题制作
工具/原料 <P><BR>使用divcss语言编写的html静态页面一个</P> <P>Macromedia Dreamweaver软件<BR></P> WordPress主题结构分析 1 1、index.php首页模板(最基本) ---- 1、header.php头部 ---- 2、sidebar.php侧边…...

MybatisPlus常用增删改查
记录下MybatisPlus的简单的增删改查 接口概述 Service和Mapper区别 Mapper简化了单表的sql操作步骤(CRUD),而Serivce则是对Mapper的功能增强。 Service虽然加入了数据库的操作,但还是以业务功能为主,而更加复杂的SQL…...

Citus的TPCC、TPCH性能测试
Citus的TPCC、TPCH性能测试 文章目录 Citus的TPCC、TPCH性能测试测试的目的适用范围测试环境架构信息硬件配置操作系统软件版本 测试结果TPCC测试测试结果TPCH测试测试结果 一、环境部署1.1、安装BenchmarkSQL1.2、PostgreSQL安装1.3、nmon部署1.4、TPC-H测试的生成数据工具安装…...

蓝桥杯---颜色分类(leetcode第75题)题解
文章目录 1.问题重述2.思路分析3.代码分析 1.问题重述 颜色分类,实际上就是赋予了三种颜色不同的数值,0,1,2分别代表的就是一个类型的颜色,我们题目说的是对于颜色进行分类,实际上就是对于0,1,2进行分类,我们把很多数…...

C语言基础13:循环结构 for和while
循环结构 什么是循环结构 代码在满足某种条件的前提下,重复执行,就叫做循环结构。 循环的分类 无限循环:其实就是死循环,程序设计中尽量避免无限循环,如果非要使用,那么这个循环一定要在可控范围内。有…...

六西格玛设计培训如何破解风电设备制造质量与成本困局
2023年,中国风电行业装机容量突破4.3亿千瓦,稳居全球第一,但高速扩张背后暗藏隐忧: 质量痛点:叶片开裂、齿轮箱故障等缺陷频发,运维成本占项目全生命周期成本超30%;成本压力:原材料…...
【Android开发】安卓手机APP使用机器学习进行QR二维码识别
前言:本项目是一个 Android 平台的二维码扫描应用,具备二维码扫描和信息展示功能。借助 AndroidX CameraX 库实现相机的预览、图像捕获与分析,使用 Google ML Kit 进行二维码识别。为方便大家了解项目全貌,以下将介绍项目核心代码文件 MainActivity.java 和 AndroidManifes…...

Zabbix-监控SSL证书有效期
背景 项目需要,需要监控所有的SSL证书的有效期,因此需要自定义一个监控项 实现 创建自定义脚本 在Zabbix的scripts目录(/etc/zabbix/scripts/)下创建一个新的shell脚本check_ssl.sh,内容如下 #!/bin/bash time$(echo | openssl s_client…...

生成式聊天机器人 -- 基于Pytorch + Global Attention + 双向 GRU 实现的SeqToSeq模型 -- 上
生成式聊天机器人 -- 基于Pytorch Global Attention 双向 GRU 实现的SeqToSeq模型 -- 上 前言数据预处理下载并加载数据原始数据格式化数据清洗与字典映射转换为模型需要的数据格式 SeqToSeq 模型Encoder 编码器Decoder 解码器全局注意力机制解码器实现 前言 本文会介绍使用…...
Kickstart自动化安装过程中自动选择较小的磁盘安装操作系统
Kickstart自动化安装过程中自动选择较小的磁盘安装操作系统 需求 在实际生成操作过程中,一般会遇到物理服务器存在多块盘的情况。 安装过程中,磁盘的标签是随机分配的,并不是空间较小的盘,就会使用较小的磁盘标签 而需求往往需要…...

基于进化式大语言模型的下一代漏洞挖掘范式:智能对抗与自适应攻防体系
摘要 本文提出了一种基于进化式大语言模型(Evolutionary LLM)的智能漏洞挖掘框架,突破了传统静态分析的局限,构建了具备对抗性思维的动态攻防体系。通过引入深度强化学习与多模态感知机制,实现了漏洞挖掘过程的自适应进化,在RCE、SQLi、XXE等关键漏洞类型的检测中达到97…...

游戏引擎学习第99天
仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板:制作一些光场(Light Field) 当前的目标是为游戏添加光照系统,并已完成了法线映射(normal maps)的管道,但还没有创建可以供这些正常映射采样的光场。为了继续推进&…...
脉冲当量含义
前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在开发C#的运动控制程序的时候,一个必要的步骤就是设置每个轴的脉冲当…...

docker compose部署flink集群
本次部署2个jobmanager和3个taskmanager 一、部署zookeeper集群 flink使用zookeeper用作高可用 部署集群参考:docker compose部署zookeeper集群-CSDN博客 二、创建目录及配置文件 创建timezone文件,内容填写Asia/Shanghai 手动创建目录:…...
docker compose快速部署kafka-connect集群
先部署kafka集群,启动 参考:docker compose部署kafka集群-CSDN博客 创建timezone文件,内容填写Asia/Shanghai 再部署kafka-connect集群 networks: net: external: true services: kafka-connect1: restart: always image:…...
【核心特性】Go 模块化开发入门(go mod 深度解析)
Go 模块化开发入门(go mod 深度解析) 一、引言 在 Go 语言的开发过程中,随着项目规模的不断扩大,依赖管理变得愈发重要。Go Modules 作为 Go 语言官方的依赖管理工具,自 Go 1.11 版本引入后,极大地简化了项…...

【基础算法】枚举(普通枚举、二进制枚举)
文章目录 一、普通枚举1. 铺地毯(1) 解题思路(2) 代码实现 2. 回文日期(1) 解题思路思路一:暴力枚举思路二:枚举年份思路三:枚举月日 (2) 代码实现 3. 扫雷(2) 解题思路(2) 代码实现 二、二进制枚举1. 子集(1) 解题思路(2) 代码实现 2. 费解的…...
PostgreSQL 的扩展pageinspect
PostgreSQL 的扩展pageinspect pageinspect 是 PostgreSQL 提供的一个强大的底层扩展,允许数据库管理员和开发者直接检查数据库页面的内部结构。这个扩展对于数据库调试、性能优化和深入学习 PostgreSQL 存储机制非常有价值。 一、扩展概述 功能:提供…...

【HarmonyOS Next之旅】DevEco Studio使用指南(三十一) -> 同步云端代码至DevEco Studio工程
目录 1 -> 同步云函数/云对象 1.1 -> 同步单个云函数/云对象 1.2 -> 批量同步云函数/云对象 2 -> 同步云数据库 2.1 -> 同步单个对象类型 2.2 -> 批量同步对象类型 3 -> 一键同步云侧代码 1 -> 同步云函数/云对象 说明 对于使用DevEco Studio…...

TomatoSCI数据分析实战:探索社交媒体成瘾
今天我们尝试对一份社交媒体成瘾的调查数据进行几项简单的分析,看看可以得出哪些有意思的结论?图1A是这份数据的说明,因为篇幅太长只把部分数据贴出来(图1B)。 01 不同性别的成瘾程度会不同吗? 我们使用bo…...
k8s下离线搭建elasticsearch
前提 已经完成k8s安装 已经完成相关组件如helm的安装 下载es的chart包 如下地址 https://helm.elastic.co/helm/elasticsearch/elasticsearch-版本号.tgz 如6.8.10 https://helm.elastic.co/helm/elasticsearch/elasticsearch-6.8.10.tgz 修改配置 修改value.yaml文件…...
<2>-MySQL库的操作
目录 一,创建数据库 二,查看字符集和校验规则 三,修改数据库 四,删除数据库 五,备份和恢复数据库 六,查看连接 一,创建数据库 创建一个名为bin_db的数据库,并设置字符集为utf8…...

《数据挖掘》- 房价数据分析
这里写目录标题 采用的技术1. Python编程语言2. 网络爬虫库技术点对比与区别项目技术栈的协同工作流程 代码解析1. 导入头文件2. 读取原始数据3. 清洗数据4. 数据分割4.1 统计房屋信息的分段数量4.2 将房屋信息拆分为独立列4.3 处理面积字段4.4 删除原始房屋信息列 5. 可视化分…...

C++学习-入门到精通【14】标准库算法
C学习-入门到精通【14】标准库算法 目录 C学习-入门到精通【14】标准库算法一、对迭代器的最低要求迭代器无效 二、算法1.fill、fill_n、generate和generate_n2.equal、mismatch和lexicographical_compare3.remove、remove_if、remove_copy和remove_copy_if4.replace、replace_…...

进程——环境变量及程序地址空间
目录 环境变量 概念 补充:命令行参数 引入 其它环境变量 理解 程序地址空间 引入 理解 虚拟地址存在意义 环境变量 概念 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。打个比方,就像你布置房间,这些参数就类…...
江科大读写内部flash到hal库实现
hal库相关代码 进程结构体 typedef struct {__IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*表示闪存操作过程中的不同状态或过程类型*/__IO uint32_t DataRemaining; /*记录尚未完成的页数或者半字数*/__IO uint32_t Address; /…...