IP 和 UDP Checksum 的增量更新问题

之前在写 IP Checksum 的增量更新,就是当 TTL -= 1 的时候,Checksum 应该增加 0x0100 ,但是这样会有问题,在于,如果按照原来的 IP Checksum 计算方法,是不会出现 0xFFFF 的(求和,进位,然后取反写入),这种加法就有可能出现 0xFFFF 。于是翻阅了相关的RFC: 首先是 RFC 1141 相关部分: unsigned long sum; ipptr->ttl--; /* decrement ttl */ sum = ipptr->Checksum + 0x100; /* increment checksum high byte*/ ipptr->Checksum = (sum + (sum>>16)) /* add carry */ 这也是比较直接能想到的一种方法,但是会出现刚才提到的问题。于是 RFC 1624 纠正了这个问题: Although this equation appears to work, there are boundary conditions under which it produces a result which differs from the one obtained by checksum computation from scratch.

Read More

每周分享第 25 期

关掉各种 Intel BUG 的 mitigation https://t.me/one_real_world/1517 GCC 10 支持用 MMX 模拟 SSE http://www.phoronix.com/scan.php?page=news_item&px=GCC-10-Emulating-MMX-With-SSE Minecraft Earth 发布 https://www.minecraft.net/en-us/article/new-game--minecraft-earth# Python 官方 format 工具 https://github.com/python/black JS Binary AST Proposal https://github.com/tc39/proposal-binary-ast 用 Rust 实现的 ld https://github.com/aep/elfkit Verilog -> Minecraft https://github.com/itsFrank/MinecraftHDL Rust 实现的 光栅化输出 https://github.com/ecumene/rust-sloth/ Nokia 的 Rust 内存 profiler https://github.com/nokia/memory-profiler Linux 5.2 更新的 Logitech Wireless Device 驱动 正好能用上 http://www.phoronix.com/scan.php?page=news_item&px=Better-Logitech-Linux-5.2

Read More

Nginx 反代到 HTTPS 上游

这次遇到一个需求,要反代到不在内网的地址,为了保证安全,还是得上 HTTPS ,所以尝试了一下怎么给 upstream 配置自签名 HTTPS 证书的验证。 upstream subpath { server 4.3.2.1:4321; } server { listen 443 ssl; server_name test.example.com; location /abc { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_ssl_trusted_certificate /path/to/self_signed_cert.crt; proxy_ssl_name 1.2.3.4; // to override server name checking proxy_ssl_verify on; proxy_ssl_depth 2; proxy_ssl_reuse on; proxy_pass https://subpath; } } 可以用 openssl 获得自签名的 cert : echo | openssl s_client -showcerts -connect 4.3.2.1:4321 2>/dev/null | \ openssl x509 -text > /path/to/self_signed_cert.crt ref: https://stackoverflow.

Read More

每周分享第 24 期

在线波形绘制 https://wavedrom.com/editor.html Python 波形绘制 https://github.com/wallento/wavedrompy GDB 8.3 发布 http://www.phoronix.com/scan.php?page=news_item&px=GDB-8.3-Debugger-Released 命令行自动搜索 StackOverflow https://github.com/WindSoilder/hors 从 C 到 Rust 的翻译 https://github.com/immunant/c2rust SHA-1 碰撞攻击新进展 https://www.zdnet.com/article/sha-1-collision-attacks-are-now-actually-practical-and-a-looming-danger/ macOS 配置 AD 管理员组 https://derflounder.wordpress.com/2011/02/17/adding-groups-from-your-directory-service-to-your-macs-admin-group/ ssh 后自动安装并打开 code-server 同步配置 https://github.com/cdr/sshcode HTTP Sunset 头 https://tools.ietf.org/html/rfc8594

Read More

在 FPGA 上实现路由器(2)

前言 月初的时候,有了一个完整可用的路由器(上一篇系列博文),但当时测了一下速度,只有几十 Mb/s ,只要往上提就会失效,得 reset 才能继续。当时也先没管性能的事情,先把和 OS 交互的部分做了。现在又回头来做性能调优。 之前,逻辑部分的主频只有 10 MHz ,这自然不行,不提高肯定做不到千兆。于是试着把主频拉高, FIFO 加大,然后遇到了很多问题,慢慢修复了,学到了很多新知识,目前也接近千兆的水平了吧,贴图: TCP 测速: UDP 测速: 测试环境是 macOS 虚拟机外打虚拟机内,走网桥把虚拟机和一个 USB 网卡接起来,然后从另一个 USB 网卡打到路由器。 尝试 700Mb/s 接下来讲讲,在这个过程中遇到了什么问题,怎么解决的。第一个是速度过快就会挂,这肯定是丢包逻辑没写对,后来在仿真里开够了时间,于是就找到了一个 BUG ,其实就是一行的修复。接着就是提高主频,但大家也知道,CPU不能随便超频,由于各种延迟的原因,比如 Setup 时间,如果超了一个时钟周期的时间,本来应该下个周期就得到新数据的,结果到了下下周期才有,那有的状态可能就乱了,我目前遇到的也主要就是这个问题。 于是就对着 Timing 里汇报的各种问题修啊修,发现了很多以前没有注意到的问题,它们不影响功能,但是会让逻辑变慢。第一个问题是 High Fanout ,以上就是说一个输出接到了很多输入,这看起来没啥问题,但数设课上也讲过,每个门的输入输出电流是有限制的,例如按书上的数据,一个门输出只能带十个门,更多只能级联一层。级联的话,延迟自然就高了。后来发现,这里的原因是,开了一个大的数组,但是没有变成 RAM ,综合出了几千个逻辑单元,自然是出问题。解决方法很简单,用 xpm_memory_tpdram 即可。这样一搞,主频就能上 200MHz 了。 这个时候测了一下,发现 UDP 能打到 700Mb/s 了,TCP 由于丢包率比较高,只有 400Mb/s ,距离预期还有一段距离。于是继续进行优化。 向 900Mb/s 进发 要继续提速,自然要提高主频。下一个主频目标就是 250MHz 。随着提高主频,时序的要求也会更高,自然也出现了新的问题。 这次的问题主要在于,一个路径上逻辑门数过多,多的有7到10个,每一步零点几到一点几纳秒,叠起来4纳秒哪里够用。于是把一些不需要依赖条件的逻辑挪到条件外面,这样就减少了一些路径的依赖。 解决了这个以后,现在的 WNS (Worst Negative Slack)只剩下 0.6 ns 了。这时候的问题一部分还是来自于逻辑门过多,但这个时候就没这么简单了,只能继续细化流水线,打一拍,这样才能把延迟降下来。 虽然 Timing 没有完全解决,但还是写进了 FPGA 中。幸好工作一切正常,就得到了上面那个图片的结果,接近千兆的速度了。

Read More

每周分享第 23 期

VS Code Remote https://code.visualstudio.com/blogs/2019/05/02/remote-development Rust 命令行看图片 https://github.com/atanunq/viu GCC 9.1 发布 https://readhacker.news/s/42Ruk Rust 的 Unikernel https://github.com/hermitcore/libhermit-rs Rust 的 QRCode 库 https://www.reddit.com/r/rust/comments/bk7z2x/announcing_bardecoder_a_qr_detector_and_decoder/ 鲁迅说过搜索引擎 http://cx.luxunmuseum.com.cn/ JIT 的 golang REPL https://github.com/gijit/gi Github 私有 Package Repo https://github.com/features/package-registry

Read More

给 Rocket Chip 挂接串口外设

前沿 最近在给 rCore 添加 Rocket Chip 支持。下面讲讲最近做了哪些工作,遇到了哪些坑,都是怎么解决的。 踩坑过程 Rocket Chip 运行代码 首先分析了一下已有的代码和工作方式,这个 Rocket Chip (ucb-bar/fpga-zynq)的设计大概是这样的:在 PS 上通过 fesvr 向 Rocket Chip 写入程序。Rocket Chip 本身暴露出一个 TSI ,一个串口的调试接口,通过 Zynq Adapter 挂到了 PS 下的 AXI 总线,暴露出若干个寄存器,大概如下: /** * Address Map * 0x00 - serial out FIFO data * 0x04 - serial out FIFO data available (words) * 0x08 - serial in FIFO data * 0x0C - serial in FIFO space available (words) * 0x10 - system reset * 0x20 - req FIFO data * 0x24 - req FIFO data available (words) * 0x28 - data FIFO data * 0x2C - data FIFO data available (words) * 0x30 - resp FIFO data * 0x34 - resp FIFO space available (words) * 0x38 - nsectors * 0x3C - max request length */ 前面的是调试接口,后面的是 block device 和 network ,我们暂时还没有用到这些 UCB BAR 做的私货。在 Vivado 中,地址 Offset 是 0x43C00000 ,所以代码中就这样访问对应的物理地址:

Read More

每周分享第 22 期

AXI-Stream Components https://github.com/alexforencich/verilog-axis go self update 库 https://github.com/rhysd/go-github-selfupdate Atomic Pi https://www.cnx-software.com/2019/04/26/buy-atomic-pi-cherry-trail-sbc/ 静态网站生成器 Hugo https://github.com/gohugoio/hugo C++ enum 的反射 https://github.com/Neargye/magic_enum 又一个开源的反编译器 https://github.com/BoomerangDecompiler/boomerang

Read More