HN user

marcan_42

11,384 karma
Posts4
Comments1,502
View on HN

No, the throttling is much more aggressive than real time. I suspect it's Google's way of sneakily breaking ancient YouTube clients that won't run arbitrary JS as a countermeasure for downloaders, without really breaking them all the way, so users of e.g. ancient smart TVs just think their network is (unusably) slow instead seeing an outright error, so they don't complain en masse that their TV no longer works properly.

Typical video bitrates for bog standard 1080p30 will be in the 1MB/s range, so the throttling is around 20x slower than real time.

This is complete nonsense. The overwhelming majority of video download time is spent transferring the actual video data, limited by throttling or network speed. The time it takes for these tools to start up and deal with the API/JS stuff is inconsequential for any video longer than a minute or so. And even then most of the time is network latency for the API stuff, not local processing. Netcat isn't going to go any faster.

Absolutely nobody thinks optimizing the meta/API processing of yt-dlp & co is worth it. This is exactly why we have high level programming languages that make all of this much easier, instead of trying to write HTML and JS parsing in plain C. Keep in mind these tools support dozens or hundreds or websites, not just YouTube.

If you think rewriting yt-dlp in C is worth it, go right ahead, but you're not going to make it significantly faster; you're just going to make maintenance a much bigger pain for yourself. Pick the right tool for the job. Python is absolutely (one of) the right tools for this job.

(For the record: I use C and Python on a daily basis, and will use whatever language is appropriate for each situation.)

That's one reason why most TrustZone implementations are broken: usually the OS has control over all this clocking stuff. It's also one way the Tegra X1 (Switch SoC)'s last remaining secrets were recently extracted.

It's also how I pulled the keys out of the Wii U main CPU (reset glitch performed from the ARM core). Heh, that was almost a decade ago now.

That's why Apple uses a dedicated SEP instead of trying to play games with trust boundaries in the main CPU. That way, they can engineer it with healthy operating margins and include environmental monitors so that if you try to mess with the power rails or clock, it locks itself out. I believe Microsoft is doing similar stuff with Xbox silicon.

Of course, all that breaks down once you're trying to secure the main CPU a la SGX. At that point the best you can do is move all this power stuff into the trust domain of the CPU manufacturer. Apple have largely done this with the M1s too; I've yet to find a way to put the main cores out of their operating envelope, though I don't think it's quite up to security standards there yet (but Apple aren't really selling something like SGX either).

Of course, that requires tenants trust Intel's security.

As a security researcher and given past showings from Intel, I wouldn't put much faith in SGX, even if they try to fix past flaws. SGX as a concept for tenant-provider isolation requires strong local attacker security, which is something off the shelf x86 has never had (not up to contemporary standards, ever) and certainly not in anything Intel has put out. They've demonstrated they don't have the culture nor security chops to actually engineer a system that could be trusted, IMO. Plus then there's all the microarchitectural leak vectors with a shared-CPU approach like that, and we know Intel have utterly failed there (not just Spectre; there was absolutely no excuse for L1TF and some of the others, and those really showed us just how security-oblivious Intel's design teams are).

Right now, the x86 world would probably do well to listen to Microsoft, since their Xbox division managed to coax AMD into actually putting out secure silicon (they're one of the two big companies doing proper silicon security at the consumer level, the other being Apple and Google trying to catch up as a distant third). But given the muted response to Pluton from the industry, and the poor way in which this is all being marketed and explained, I'm not sure I have much hope right now...

I actually didn't know about that one. Sounds like it's mostly for specialty applications though (e.g. ceramic packages). Looks like it's something like 80% gold, so that would get expensive really fast if you attempted to use it like regular solder :)

The AGX GPU MMU (variously called "GART" and "UAT", no relation to AGP GART) uses the ARM64 page table format (the GPU coprocessor literally uses it as an ARM page table among other things), so I'd expect it to support huge pages just fine since ARM64 does too. I don't know if macOS supports them, though.

The page size is indeed 16K. I don't know if 4K is supported at all in the GPU.

I agree though, the article reads like a rambly piece that doesn't follow and really just boils down to "my code runs slow on this machine and I'm going to blame the architecture" without going into proper details.

Gold plated connectors are absolutely normal and completely standard and essential. The vast majority of durable data/signal connectors used today are gold-plated. Hack open any random decent microUSB connector if you don't believe me. You need a solid connection for signal integrity. Corrosion messes that up. Of course, with modern cost optimization, usually only the contact surface is gold plated these days, not the entire pin, and the plating is quite thin and cheap. Connectors intended for higher connect/disconnect cycles will be more expensive in part because they need a thicker gold plating to avoid wearing out.

Gold plated PCBs are also completely standard (google ENIG). In this case the plating is even thinner and just serves to ensure solderability and avoid corrosion. It's so thin that it immediately dissolves in the solder during the solder reflow process; it's just there to allow that process to happen properly, and to avoid corrosion in non-soldered areas. Almost every modern high tech PCB

Gold containing solder, on the other hand, is nonsense.

Low quality audio hardware absolutely exists and is rampant at the cheap end. And some standards, like USB2.0 (when used for data), are terrible and will cause audible noise if lots of care isn't taken to filter things and avoid ground loops.

But if you're spending $2500 on a headphone amp instead of $250 on a professional quality audio interface, or $1500 on jewel encrusted RCA cables instead of $30 on balanced XLR cables, or you think 192kHz sounds better than 48kHz because you have superhuman hearing and can somehow hear ultrasound, you're wasting your money and you have no idea what you're doing when it comes to audio quality.

What the lawyers do and how the technology actually works are not necessarily related.

The shaders are completely different, the controller is completely different, the command submission structures are different. Sure, it's still a tiled architecture and they probably have to keep PVRTC for compatibility and pay the royalty for that, and you can see some remaining PVR influence in the design. But it's not PVR, and quite possibly has zero actual PVR technology left (as in silicon IP from IMG). They're probably only paying patent royalties.

We know this because we're reverse engineering AGX and IMG just dumped an upstream submission to Mesa and now anyone can compare them. PVR's architecture is, for starters, a lot more insane than Apple's.

When you are working in a tight embedded system, instead of fighting to slim down a library that is designed to scale to significantly larger systems, it makes much more sense to start from zero and add only what you need. You also shouldn't update your dependencies blindly, ever (even updating the compiler should be done with care).

The considerations are very different from, say, developing apps for an operating system. There is a gradient between those, and the software development considerations shift as you move along. Most people doing embedded development defer to libraries way too early - usually because they're either pure hardware people who haven't learned low-level firmware bring-up and rely on vendor tooling, or people from a higher level software background who find the idea of bare metal scary.

You can see an example of this gradient in the Asahi Linux boot chain:

- m1n1: bare metal, no threads (barebones SMP support for research only), statically linked, no device model, not readily portable, 64-bit only, assumes everything is an M1/Apple Silicon, embedded libc subset, vendored (C: dlmalloc, printf, decompression algorithms, libfdt) or git submodule (Rust: FAT32 implementation) dependencies, single-purpose NVMe & FAT32 implementations (no abstraction).

- u-boot: bare metal, no threads, statically linked, basic device model, portable, embedded libc subset, vendored dependencies, basic filesystem & block device abstraction.

- GRUB: runs on EFI environment, no threads, dynamically linked modules, portable, filesystem & block device abstractions, no actual modifications for Apple Silicon (we use vanilla bins)

- Linux kernel: bare metal, complex thread model, dynamically linked modules, rich device model, portable, embedded libc subset, vendored dependencies, rich filesystem and block device abstractions.

- Linux userspace: you know this.

Notice how none of the components before userspace use a full fat libc, and only have minimal dependencies which are carefully controlled - and this is on a system with gigabytes of RAM.

Personally, I would only use newlib on systems which are roughly equivalent, in terms of model/software stack, to a full desktop OS. That is, embedded systems with at least a threaded RTOS and a filesystem abstraction, possibly a BSD-style sockets layer. Anything smaller than that (no threads? lwip callback style sockets? no filesystem?), you're better off rolling your own.

The solution isn't to stop using rand(). The solution is to stop using newlib.

If you're doing your own custom memory management like this, you shouldn't even have a malloc implementation at all. Even newlib is too bloated for your use case. At this point, chances are you're using a trivial subset of the C library and it'd be easy to roll your own. You can import bits and pieces from other projects (I personally sometimes copy and paste bits from PDClib for this). In such a tight embedded project, chances are you don't even have threads; why even pull in that reentrancy code?

Freestanding C code with no standard library isn't scary. If you need an example, look at what we do for m1n1:

https://github.com/AsahiLinux/m1n1/tree/main/src

In particular, this is the libc subset we use (we do have malloc here, which is dlmalloc, but still not enough of libc to be worth depending on a full one):

https://github.com/AsahiLinux/m1n1/tree/main/sysinc

No, it sounds perfectly fine. Mathematically, interleaving samples like this is equivalent to zero-padding every other sample to upsample, with no antialiasing filter. Then you add the other channel offset by one sample. The end result is that you have both channels summed up in the low 24kHz of spectrum, with half a 48kHz sample of offset for one channel (mostly negligible), and everything mirrored in the top 24kHz of spectrum as aliasing (which you can't hear). In other words, it will be very, very close to what a simple mono downmix would sound like.

No, really, it can't. Feed it a checkerboard input and you'll get gray on the way out. It's horizontally processed at a lower resolution internally. Might be 960x1080 at 30FPS, and it can't do it at 60FPS at all. Yes, you're going to get 1920x1080 JPEG bitstreams out the USB end, but it's not actually 1920x1080.

I suspect this happens because it doesn't actually have enough internal RAM to buffer a full 1080p frame (this chip uses on-die RAM, so probably SRAM since they wouldn't go for a fancy EDRAM process, and SRAM is expensive by capacity).

I can get 1920x1080 at 60fps from it.

No, you can't. It's not just MJPEG, it's internally downsampled to less than 1920 pixels of effective horizontal resolution, even though it technically spits out 1920 pixels via USB. It'll do true 1280x720 though (still with MJPEG). You're also going to get stereo audio on Linux with recent kernels only because I sent in a patch to make that work - due to a hardware bug, it advertises itself as 96kHz mono, so Windows and macOS will give you that (which is actually 48kHz stereo with both channels interleaved, but they couldn't advertise it as such because it does not correctly handle packet boundaries in a way that'd be spec-compliant for stereo audio).

Welcome to the wonderful world of Chinese HDMI capture cards. These particular little dongles are all using MacroSilicon MS2109 chips. Cheap and okay-ish for some use cases, but don't expect a high quality capture card or raw uncompressed video at this price point.

which are programmed somewhat like regular computers but just with an astonishingly high number of threads.

But they aren't that; they are actually wide vector processors, which means groups of threads need to be doing the same thing for it to perform properly! Branches and divergent control flow kill GPU performance.

I'm sure you already know this, but I'm just pointing out for other folks reading. If GPUs were just CPUs with stupidly high core counts then things would be way easier, but it's more complicated than that.

ECDSA is easy to fuck up due to needing a "random" number for signatures (among other things, but that's the one Sony did and many others have since). Thankfully, we've figured out an easy fix for that: just hash the private key and the message, and use that instead of the randomness. That's in the spec for ed25519, so unless you're completely ignoring chunks of the spec (which would be unlikely to work for an algorithm like this, and wouldn't pass test vectors) you're probably fine on that front if you use it, even if you're reimplementing it.

The Load Balancer is there because the M1 Max has two independent Neural Engines (unlike the GPU cores, which are load balanced in hardware and the OS sees as a single one even on the Ultra)... but one ANE is inexplicably disabled on all production systems. The M1 Ultra, logically, has four... and only the first in each die is enabled.

I was waiting for the Mac Studio to drop to come to a conclusion, since it's plausible one ANE could've been disabled for power reasons on the laptops... but with both secondary ANEs in each die in the M1 Ultra off, and with no reports of anyone seeing the first ANE being disabled instead (which could mean it's a yield thing), I'm going to go ahead and say there was a silicon bug or other issue that made the second ANE inoperable or problematic, and they just decided to fuse it off and leave it as dead silicon on all M1 Max/Ultra systems.

The Verilog source code for the N64 ASICs leaked at some point, it's been floating around the internet for a while. So there's very little you couldn't figure out by looking at that, at this point.

That's relatively recent, though; the vast majority of the emulation knowledge was from reverse engineering, patents, and typical devkit leak stuff as you say.

anything that can actually boot macOS almost certainly exists purely to break the macOS license agreement.

Apple provides a hypervisor framework that emulates a standard ARM64 system and macOS ARM64 kernels that run on it. This is how macOS on Apple Silicon virtualization works. It's not really Apple Silicon, it's boring standard ARM on Apple Silicon. Soon after Apple started shipping these kernels, before it was even announced, someone tried it on QEMU on another platform and found it worked just fine in single user mode.

The only catch is the macOS UI requires Metal, and paravirtualized graphics are implemented using serialized Metal passthrough. In other words, if you want to boot ARM64 macOS to a desktop, you have to implement Metal in your VM host.

Well, that's the first time side effects in Haskell made sense to me. Well done.

Not that I've ever seriously tried to learn Haskell, but in the past every time I've lazily come across an article about it it's always seemed like a bizarre confusing world, even though I know how functional programming (in the sense of purity) works.

Now there's just one thing missing. We all know what this style of programming is. It's asynchronous programming with callbacks. Seriously, Haskell folks, if you started with "all side effecting functions are kind of like async operations with a completion callback (the stuff people do in JavaScript all day), and then we have some syntactic sugar to make it suck less" you'd have a much easier time getting people to wrap their head around all this.

(Yes, I know the details aren't exactly the same, but drawing parallels to stuff people already know matters)

Seriously, this idea of there being a central effect dispatcher (the bit that runs `main` behind the scenes) is so eerily like the coroutine scheduler in async coroutine paradigms that I can't believe more people haven't drawn parallels between these programming styles.

The purpose of a fuse is not to blow, but to only blow when dangerous amounts of current flow through the wire they are protecting.

The purpose of these fuses is to blow and serve as write-once storage memory.

eFuses are a hackish way that System on a Chip makers have created to try and permit patching flawed hardware with questionable firmware.

No, eFuses are literally the only mutable nonvolatile storage that can be implemented inside SoCs in modern silicon processes, because you can't put Flash/EEPROM in them for technical reasons. That is why they are universally used for irreversible configuration actions on every single modern high-performance SoC. You will only find Flash memory in small microcontrollers.

And what little "security" features the Librem 5 has, they aren't even using. One of their engineers came at me with "we have RPMB!" (a poor excuse for anti-replay memory that is semi-standard these days, and vastly inferior to dedicated chips like Pixels and iPhones have). I asked what they use it for, and got crickets.

There's a linux driver behind typical basebands. One driver, since there is no device discovery for platform devices.

The Librem 5 doesn't have one driver exposed to the baseband. It has every single USB driver in the kernel exposed to it, because the baseband can present any descriptors it feels like and engage whatever driver it wants, or a combination thereof by presenting itself as a composite USB device, since USB is plug&play. That is a massively larger attack surface. All you have to do is find one exploitable bug in any USB driver in Linux, and you're in.

This can be mitigated with USB descriptor filtering, but the Librem 5 guys haven't implemented that yet, because they don't actually care about security. So while their marketing department is lying about DMA access for the competition (heck, as far as I know no iPhone gas ever given the baseband unchecked DMA access to the system, but Purism claims they all do!), their engineering department can't even bother to lock down the attack surface of the baseband to something smaller than "every single USB driver in the kernel".

Also, for what it's worth, the Librem 5 doesn't even have an IOMMU at all. They can't even use the PCIe ports in their SoC because that would give whatever you plug into them full DMA to the system. This also means that driver bugs that result in bad DMA descriptors for embedded SoC devices will directly escalate to full memory access; there is no safeguard by having to engage the IOMMU subsystem first to map them.