有了网卡驱动,接下来要做的就做网络的 syscall 了。为了测试,首先在 busybox 里找可以用来测试的 applet,由于没有实现 poll,所以 nc telnet 啥的都用不了。最后选择到了 ping 和 pscan 上。 ping 大家都很了解,pscan 就是一个扫端口的,对一个 ip 连续的若干个端口发起 tcp 请求。这就要求我提供 raw socket 和 tcp socket 状态的支持。由于网络栈本身是异步的,但 read connect 这些函数在不调 setsockopt 的前提下又是同步的,然而现在又没有 signal 可以用,要是 block 了就再也出不来了。于是就采用了 Condvar 的办法,拿一个全局的条件变量,当 poll 不到内容的时候,先把线程拿掉,等到网络栈更新了,再恢复。这样至少不会把 cpu 也 block 住。 然后就是把 socket 部分改了又改吧,数据结构的设计改了几次,为了解决 ownership 问题上锁啊也有点多,但是也更细了,虽然实际上可能没有必要,因为上面还有大的锁。不过性能还不是现在考虑的重点,关键还要先把 send recv accept bind listen 啥的写得差不多了,然后还有把 poll/select 实现了,这个很关键。 中间遇到的最大的坑就是,接收 pci interrupt 的时候总是啥也没有,然后靠万能的 qemu trace 发现,原来是 mask 掉了,所以啥也收不了,然后最后的解决方案就是用 MSI Interrupt #55 搞定了这个问题。至于为啥是 55 呢,因为 23 + 32 = 55 啊(误
每周分享第 13 期
今天还是早点发吧 Rust concurrent work-stealing queue 可能可以放到调度器里用 https://github.com/kinghajj/deque 支持信用卡/时间等格式信息的输入控件 https://github.com/nosir/cleave.js Rust 的简单 http server https://github.com/svenstaro/miniserve Coroutines & Modules Added For C++20 http://www.phoronix.com/scan.php?page=news_item&px=Coroutines-Modules-CPP20 Implementing TCP in Rust (part 1) https://www.youtube.com/watch?v=bzja9fQWzdA 一个类似 Vuetify 的框架 https://buefy.org/ systemd tmpfiles.d 用于管理特定的临时文件夹 https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html 获取 ASN 信息的 API https://bgpview.docs.apiary.io/#reference/0/asn-prefixes/view-asn-prefixes Rust getter/setter generation https://github.com/Hoverbear/getset Golang 1.12 发布:TLS 1.3 http://www.phoronix.com/scan.php?page=news_item&px=Golang-1.12-Released 一个笑话 https://redd.it/aux77g Rust 的 STM https://github.com/mtak-/swym 自动同步视频和字幕 https://github.com/smacke/subsync 用于快速开发的 http server https://zeroserver.io/ 一个自动加载的 http server https://github.com/tapio/live-server 用 markdown 写 presentation 在线版 https://github.
使用 Rust 实现 e1000 驱动
是的。我又来了。上次做了使用 Rust 实现 VirtIO 驱动之后,继续往 rCore 加更多的驱动支持。由于现在工作重点是 x86_64 下的 syscall 实现,所以选了一个比较有代表性的驱动 e1000 来实现。其实如果只是为了在 qemu 下运行的话,其实只需要支持 virtio-pci 就可以了,原来的 virtio-net 直接拿来用就可以了。 为什么挑 e1000 呢,一方面是支持的设备多,有真实硬件可以测试,虽然不一定要裸机上跑,但是可以通过 PCI passthrough 来测试驱动的正确性。另一方面是网上的资料比较多,有现成的简单的代码可以借鉴。这次主要借鉴了三个来源:一是 Biscuit OS,二是 Judge Duck OS,三是 Linux。 首先是实现了简单的 PCI 总线的枚举,然后找到对应的设备,激活,并且找到映射的内存地址,然后把原来 C 语言的实现搬运到 Rust 中。这个过程中遇到很多坑,例如一开始我以为内核里 pa 和 va 是一个固定的偏移,不过多次尝试后才发现这个假设只对 riscv 平台里的实现成立。 这个时候就可以收到外面给进来的以太网帧了。接着就是把它接入到 smoltcp 的 API 中。但是发包又不工作了,尝试了很多次,各种方法也不行。其中特别要提到的就是 qemu 的 tracing API,它在帮助我调试之前的 virtio 驱动和这次的 e1000(e) 驱动中起到了很大的帮助。不过,遗憾的是,发包相关的代码里的 trace 不足以让我找到问题的所在,我只好采用了最后一招: 下载 QEMU,自己改,然后自己编译。 这个方法果然很有效啊,经过简单的几个修改,很快就定位到问题所在了,原来就是一个简单的错误,把 4 写成了 8。这个过程中我也发现 QEMU 在 incremental build 的时候似乎会 segfault,我没管这么多,反正编译也不慢,次数也不多,每次 clean 再 build 问题也不大。
每周分享第 12 期
看脑王迟到了( Rust Embedded Graphics 库 https://github.com/jamwaffles/embedded-graphics Wireguard for macOS https://lists.zx2c4.com/pipermail/wireguard/2019-February/003853.html Wireguard-go UI https://github.com/aequitas/macos-menubar-wireguard T2 逆向 https://duo.com/labs/research/apple-t2-xpc 脑王剪辑 https://www.bilibili.com/video/av43972717 dram 推荐的工具 notion.so 带授权和审计的 sudo https://github.com/square/sudo_pair rust 的 manpage 生成器 https://github.com/rust-cli/man 才发现 Github 有 Project 功能 https://help.github.com/en/articles/about-project-boards rust 的 elf/macho 生成 https://github.com/m4b/faerie rust 的 elf/macho/pe 读取 https://github.com/m4b/goblin rust 的 glob 实现 https://github.com/rust-lang-nursery/glob 基于 BoringSSL 的 rust 加密库 https://mundane.googlesource.com/mundane 从 linux 交叉编译到 macOS 的方法 https://github.com/tpoechtrager/osxcross cargo-deb 后又有了 cargo-rpm https://github.com/RustRPM/cargo-rpm 自带 diff 的 assert_eq 宏 https://github.
预告 Learn-Project 4.0 版
不知道大家听没听说过 Google Chrome 有个插件,叫做 Learn Project,是一个网络学堂的改良前端。不过,随着网络学堂的不断更(xia)新(gao),它已经不再适用于现在的版本。于是,哈利橙(@Harry-Chen)决定利用寒假时间,在今天(2.17)之前完成 Learn Project 4.0 的开发。为什么叫 4.0 呢,因为哈利橙课程的 GPA 众数是 4.0。这个版本采用先进的 React 框架编写(Vue 塞高),使用了 Material Ui 作为界面框架(这我觉得可以),目前的一个参考图(图源哈利橙): 看那满眼的高分数,希望 Learn Project 4.0 能在 flag 倒下之前完成。
每周分享第 11 期
对不起迟到了( Google 的 fuzzing 家族又来了个新成员 太喜欢造轮子了 https://github.com/google/clusterfuzz 有趣的文本生成工具 https://github.com/TheBerkin/rant 又一个 side channel attack https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/february/downgrade-attack-on-tls-1.3-and-vulnerabilities-in-major-tls-libraries/ 来自 Prof Fan 的一个 cf dns 权限限制分发的工具 https://github.com/ProfFan/cloudflare-proxy-rs 部署到了我的博客的小工具 大家体会到了吗 https://instant.page/ 教育性质的 C on web https://vasyop.github.io/miniC-hosting/ 激活清华教育版 win10? –> dig +short TXT win10.harrychen.xyz windows95 v2.0 发布(误 https://github.com/felixrieseberg/windows95/releases/tag/v2.0.0 已经部署到 tuna 的 rustup-mirror crate https://github.com/jiegec/rustup-mirror Forth 也能有 http 服务端框架 http://www.1-9-9-1.com/ bartender 的开源替代 实测可用 https://github.com/Mortennn/Dozer 给不支持 pac 的客户端在 http proxy 上套一层 https://github.com/williambailey/pacproxy
近来做 Stanford CS140e 的一些进展和思考(9)
距离上一篇 CS140e 系列文章已经过去了很久,距离第一篇文章过了一年零几天。在后来这一段时间内,CS140e 结束了课程,又开始了新一年的 winter 2019 课程,迎来的却是 C 版本的 CS140e,不禁让人感到失望。还好,Sergio Benitez 放出了原来的 CS140e 的镜像,如果大家仍然想回去查看原版优质的 CS140e,可以点进去参考。 后来因为机缘巧合参与到了清华的 Rust OS 课程,又想到回来把原来的 CS140e 进行更新,于是顺带把跑在 QEMU 下的一些需要的工作给做了,另外把 Rust nightly 版本更新了(一年前的 nightly 还能叫 nightly?),才发现标准库变化还是蛮大的,由于 nightly 版本变了,而且原来是内嵌了一个阉割过的 std,所以主要是从新的 std 里抄代码到内嵌的 std 中。另外,原来的 xargo 也不再维护了,转而使用 rust-xbuild 进行交叉编译。 然后又顺手实现了 backtrace 和从 backtrace 中配合 dward symbols 找函数名的功能,不过实践证明,这些东西还是 addr2line 做得更好,所以也就没有做下去,在 relocation 上也是遇到了各种问题。这个经验也是应用到了 rCore 那边。 再之后也就是寒假写驱动了,见之前的一个博文,我就没有在 CS140e 上去实现它了。有时间有兴趣的时候再考虑做一下 Raspberry Pi 的网卡驱动吧。 写于迪拜雨天。
每周分享第 10 期
新年快乐! Haskell to WASM compiler https://github.com/tweag/asterius A ssh tarpit that sends endless banner https://github.com/skeeto/endlessh Use rust to write UEFI app https://github.com/rust-osdev/uefi-rs 神奇的小游戏 https://yeahpython.github.io/game/game.html 又一个后端 rust web 框架 https://github.com/seanmonstar/warp 挺酷的一个网站 https://github.com/pomber/github-history ws 调试工具 https://github.com/vi/websocat React Hooks 进入正式版 https://reactjs.org/blog/2019/02/06/react-v16.8.0.html 又一个关于硬件的 wiki https://wikidevi.com/wiki/Main_Page virtio-fs 项目 旨在替代 virtio-9p https://virtio-fs.gitlab.io/ SergioBenitez 镜像了一份去年的 CS140e https://cs140e.sergio.bz/
每周分享第 9 期
IDA Loader plugin for some Nintendo rom https://github.com/w4kfu/IDA_loader websocket daemon http://websocketd.com/ 实时的游戏开发器 https://script-8.github.io/ 硬核逆向 Leica 相机的固件 https://alexhude.github.io/2019/01/24/hacking-leica-m240.html 做 CTF 时遇到的整数溢出的 CVE https://www.anquanke.com/post/id/104182 发现一个 speedtest 的轮子 https://github.com/adolfintel/speedtest 西数的 RISCV 核实现 https://github.com/westerndigitalcorporation/swerv_eh1 iOS 12.2 会有更多的 PWA 兹瓷 https://twitter.com/mhartington/status/1089292031548145666 代替死去的 git-up: git config –global alias.up ‘pull –rebase –autostash’ 利用已知明文破解旧版加密 zip 的工具 https://github.com/kimci86/bkcrack 在线看 jwt 内容 https://jwt.io/ JS 的 Lua VM https://github.com/fengari-lua/fengari 鲁棒但不优雅的前端 KV https://github.com/gruns/ImmortalDB Emacs Modules doc https://phst.eu/emacs-modules 用 IPv6 的 Flow Label 实现类似 MPLS 的效果 https://github.
使用 Rust 实现 VirtIO 驱动
背景 最近在给 rCore 添加驱动层的支持。一开始是想做网卡驱动,后来发现, qemu-system-riscv32 只支持如下的驱动: # qemu-system-riscv32 -device help Storage devices: name "scsi-cd", bus SCSI, desc "virtual SCSI CD-ROM" name "scsi-disk", bus SCSI, desc "virtual SCSI disk or CD-ROM (legacy)" name "scsi-hd", bus SCSI, desc "virtual SCSI disk" name "virtio-blk-device", bus virtio-bus name "virtio-scsi-device", bus virtio-bus Network devices: name "virtio-net-device", bus virtio-bus Input devices: name "virtconsole", bus virtio-serial-bus name "virtio-keyboard-device", bus virtio-bus name "virtio-mouse-device", bus virtio-bus name "virtio-serial-device", bus virtio-bus name "virtio-tablet-device", bus virtio-bus name "virtserialport", bus virtio-serial-bus Display devices: name "virtio-gpu-device", bus virtio-bus Misc devices: name "loader", desc "Generic Loader" name "virtio-balloon-device", bus virtio-bus name "virtio-crypto-device", bus virtio-bus name "virtio-rng-device", bus virtio-bus 所以要实现网卡的话,只能实现这里的 virtio-net-device ,而 VirtIO 驱动之间有很多共通的地方,于是顺带把 gpu mouse 和 blk 实现了。