Jim's Depository

this code is not yet written
 

History

About 20 years ago Apple rolled out AppKit, the NS* world of user interface programming, though it was already about 10 years old.

About 13 years ago Apple rolled out UIKit, a vaguely similar but significantly altered child of AppKit for the iPhone.

Over the years those frameworks morphed slightly under the coding fashions of the time. Extension by subclassing gave up some ground to extension by delegation, layout went from "chains and springs" to a constraint solver system, the primary client language changed from Objective C to Swift. Warts and debris accumulated in the APIs and backwards compatibility kept them forever.

In recent years, Apple has stopped maintaining and producing the high level documentation which describes how to use a subsystem. They still have API level documentation which describes each individual microscopic fragment, but they no longer produce the fabulous high level documents which tell you how to use an API to solve problems, and show you which areas you should be using, and which are leftovers.

The result is that in 2020 I pity anyone learning AppKit or UIKit. The web is filled with people asking questions and getting answers of varying quality, frequently low, which then become silently obsolete.

Present

18 months ago Apple released SwiftUI. This is a clean start. Not having any pressing new UI needs I decided to let it stew for a year before looking at it.

In a nutshell SwiftUI eschews graphical or imperative code creation of user interface for a terse "in source" declarative approach. Here, terse is largely accomplished with a few of language tweaks that let return be omitted at the end of a function and let let x = X(); x.add(A); x.add(B); x.add(C); return x be written as X { A B C }. It's a lot nicer to read. Writing is weird until you read how function builders work about 12 times, but you can copy-paste your way into an interface even if you don't understand why. Remember: a View is just a regular struct until you get into the body initializer then you are concatenating Views without commas between them

What I Built

I built a cross platform iOS/macOS app with a widget to display some telemetry of remote battery voltages, weather conditions, and a camera picture. It took me about two days to learn enough SwiftUI to make the simple non-interactive widgets and display screens. A fair bit of that was working out WidgetKit which isn't hard, but it took me a while to realize that because my data was driven by realtime data I could just chuck most of the complexity and not hurt my energy consumption story.

The Good

  • The user interface is nicely legible in the source files. It says what it does and does what it says.
  • Making a Widget, with its inherently simple display is really easy. (maybe)
  • Cross platform is beautiful! I essentially paid no attention to it and things just worked. I never once wanted to fly to Cupertino and find the people that think we don't want something to abstract UIColor and NSColor, and UIImage and NSImage for us poor cross platform app writers.

The Bad

  • Those syntax shenanigans SwiftUI uses to look really clean? They really hurt the compiler and Xcode's ability to produce useful error messages and code inspection information (like throwing down the template arguments as you type a function call). I lost track of how many times Xcode threw up its little hands and asked me to file a bug report while I typed. Lesson: Move everything except the view layout itself to a different file.
  • It looks simple, because it is simple. In many ways SwiftUI is in that early project phase where they just punt on the hard stuff and tell you to live with the simple way, it's good enough. And if your app's visual can be "good enough" or rejiggered into something that SwiftUI can do, then good for you.
  • You may not be able to reach excellence. I draw strip charts of time series data, they look a lot like they come out of an old pen strip recorder. They have horizontal and vertical scale lines which are generally as thin as possible on the display. This requires that the lines be aligned to the display pixel grid or some of them become fuzzy from being smeared over two rows of pixels. You don't notice this with thick lines, but hairlines need to handle this. As near as I can tell, there is no way to find out my View's position in device coordinates to then make my drawing come out right.
  • Not all Views are suitable for deployment to customers. On the Mac, the HSplit appears to have a 1 pixel wide hit zone for moving the divider and no visual indication that the split is moveable. The TextEditor leaves behind visual artifacts if you start selecting text and drag up and down. These are problems that I can't fix without source code or just writing a replacement.
  • You can draw, sort of, there is a Path view that draws a path, and you can absolutely place Text, but only by their center point. I rebuilt my stripchart view, but it works by computing a Path for each line width, color combination and drawing them in a View, then an array of Text with absolute placements to put the labels on. It's gross. Maybe I should have just wrapped my UIKit stripchart and gone on, but this works cross platform.
  • If you do not embrace Combine, you will likely have a lot of parameters being passed up and down your View trees.
  • Swift's inability for let members of a struct to reference each other really hurts when you have related data. I get it, there are reasons, but I'm pretty sure a topological sort in the compiler would take care of that. I dealt with it by making new objects which encompass all the other objects and taking care of the relationships in that init.
  • There are things which will break you. Consider the Label() type. It easily lets you pair an icon and a string. Just the thing for lots of lists. You see them everywhere. Now try to use one outside a list, because say you are a postage stamp sized widget that doesn't have interaction. Suddenly your VStack of Labels looks like garbage because the text no longer lines up and the icons aren't centered over each other. Not illegible, just sloppy. Can you fix it? There is no high level documentation from Apple, so it's off to the internet where possibly with a combination of Geometry and AlignementGuides (which are a little pile of hack) you can probably get the text in line and the icons to right align, which is better than nothing. About 50 lines of obtuse code.
  • No problem, don't use VStack{ Label() }, use a Table. They didn't make a table. I really can't fathom why unless someone was so scarred from the HTML <table> wars or intimidated by the "displays 100000 rows just fine" versions in the older APIs. Developers want to be able to have a few columns and a dozen rows to organize our displays and data. Give us some column sizing, and alignment options (including radix point, we have needs) and lets us get on with life. I don't want to use a native table, I'm trying to be cross platform here, remember "We love the Mac." (As quoted by Tim Cook twice a year at WWDC and Mac product release.)

So What Does a Grumpy Old Coder Do?

So, after all that frustration, the next day I started a new Mac app and chose SwiftUI because it really is easy and seductive and this app is mostly just for me to analyzer data and maybe a few other people. I'm not answering to a graphic designer with a Photoshop Phantasy user interface. It has to be nice, but if SwiftUI doesn't want to go somewhere, I have the liberty to not go there.

I'm displaying a couple of side by side files, source code and LLVM intermediate language generated from it. Compile the source, look at the LLVM and generated assembly code. Maybe some parse trees or internal AST dumps.

  • The App prototyping was glorious! Quick and easy to noodle about with.
  • @ObserableObject worked nicely for tying my internal data to the screen. Things Just Worked! Hit the compile button, replace the LLVM text, and the screen updates.
  • TextEditor fell on its face. Rendering bugs aside, it doesn't have the capabilities to do what I needed and no where to hook in and extend. SwiftUI does the easy stuff™
  • I wrapped an NSTextView, so goodbye any pretense of multiplatform, but that was never in the cards since its tied to a compiler anyway. I wasted about half a day learning to wrap and coming to grips with the Coordinator and where to keep my delegate and then that I really kind of needed to use Combine to sink my updates around, but after those hard lessons were learned it was pretty good.
  • Totally not SwiftUI, but if I click on a line in the source and I want to jump to the LLVM assembly that corresponds… I just feel I shouldn't have had to fight NSTextView quite so hard. I won in the end, but it took hours. My text is NSAttributedString type so it can have color and line spacing and whatnot, that makes everything like walking through mud.
  • I wanted little line numbers on the side of the NSTextView. Your API is older than your developers! This has to have come up. Fortunately you can find a solution in GitHub from Yichi Zhang. I was ready to waste a few more hours before declaring it a mess and giving up and his one file ruler class worked the first time I hooked it in! (I still had work on it a bit to use small, digit spaced text and to move the digits down to the baseline of the text. That's a little more LayoutManager and NSGlyph than most people want to know about.)
  • I got in a fight with the ToolBar. I just wanted my compile icon with the word "compile" under it because, really, when I said "compile icon" you visualized absolutely nothing. There is no picture for "compile". This is, sadly, too hard. The various toolbars will draw my Label() in different ways, none like that, except the style meant for Preferences which you can not specify in SwiftUI for some reason. It's all hard to work out because although all the API fragments are documented, there are no high level documents, so how to put them together and where to specify them is left as an exercise to the internet Oijia board. I could force it by making the toolbar item be a VStack, but then it renders poorly. After 90 minutes I gave up and make a Button with the text and symbol in it.
  • Adding a menu and menu items would have take 30 fewer minutes if Apple wrote the high level documentation.
  • I've harped on high level documentation, think about putting a NSTextView into an NSScrollView so it can scroll, probably a fair few bits to get right there. You can google it and get a bunch of answers, most either miss something important or do a lot of unnecessary stuff. But how about this: Putting an NSTextView Object in an NSScrollView A small amount of clean code, from people who know how the underlying parts work and can see their source code to verify assumptions. Look at that table of contents, it covers everything to get you up and going. Then you can work with any fiddly bits you need to customize for your situation. These documents require a team of engineers who can write and are expensive, but the number of man hours they save your customers is immense.
  • So at the end of the first day I had listings in parallel columns with syntax coloring. By the end of the second day I had clicking on source jumping to the appropriate spot in the LLVM, line numbers, assembly listings (goodbye sandbox, can't invoke clang from inside the sandbox without heroics). It's now the third day and although I still have a little list of features to add or try and reject, I'm writing this posting instead because my app is ready to use.

Conclusion

  • Use SwiftUI for Widgets. It's really your only choice there. If you already have code to gather your data, budget two days to make your first widget.
  • Use SwiftUI for quick-and-dirty internal apps where user interface defects aren't show stoppers.
  • Maybe use SwiftUI for the high level of a complicated app? Be ready to embrace Combine. I worry about Combine creating unfathomable interactions, but I haven't used it on a complicated enough project to know.
  • If you have anything complicated… table, styled text, drawings, be ready to drop into UIKit or AppKit.

Recommendations to Apple

  • Print out a banner that says "They do need that!" and hang it in the engineers' room (if we ever get to use rooms again).
  • Bring on a couple engineers and writers to write the high level documentation. Also get someone to bonk the coders on the head when I lookup API documentation for foo(bar:Int) and the detail page tells me that it is foo with an argument named bar of type Int which foos. I kind of was looking for a little more than that even if it seemed obvious to the coder when he hit add documentation in Xcode.
  • Send someone out across the internet for postings on "how to" and "swifui" and document all of the API usage questions people have in that high level documentation.

The robots are reading at least. The rate is low enough I'll just manually delete them for now.

I used to use the google recaptcha, but I know I'm annoyed at finding stop lights and street signs and in a more tracking sensitive era I don't feel like feeding people's reading habits to third parties.

That probably means I'll eventually have to make my own human detector system and lose a week to that.

This blog started 13 years ago musing about a language. I'm back to the language.

The goal is a language to use for the user mode code of a concurrent communications based operating system. I need it to catchiest mistakes at compile time, be agile enough to try language experiments, and have reasonable performance which is maybe a small predictable integer off of top notch C.

The State of the Language

  • I chose a name! Yes, this usually happens late for me, but it is atuin. After the turtle.
  • The compiler written in Swift, which is by far the most productive language I've used for writing a compiler. It emits LLVM IR (in text), which clang then compiles into an executable. I've gone to some length to keep my LLVM IR legible, it really helps diagnosing problems.
  • It looks a lot like Swift, but without the hard parts. Call it a 50% of a 90% Swift, without the other 90%.
  • The parser is built to be extended at runtime. Building new features into a language by forcing them into existing syntax seems to just make a mess of your source code. If I want to have something like async/await, I'll extend it into the language instead of making a dance of calls and wrapper types. Source code should be clean.
  • I'm skipping a lot of the complications for now. There is no FFI (I don't need one) and no separate compilation (I don't need to). The parser is slow, it is a combinator based recursive descent which is supposed to be a Packrat Parser, but until I notice it taking up time the rats can wait. I build an AST which directly matches the parse, then walk it and create a whole new AST to generate the code (with a slightly different shape). Coming from single pass compilers with no AST back during the day, this seems colossally wasteful, but after buying big enough hardware to build Swift over and over during my porting attempt, I have cpu cycles.
  • Using the parser is gorgeous! Swift operators and Unicode characters in the source file make it a bit like reading BNF. After each rule there is a binding from its products to variables which are used to build an AST node as a product. Very clean.

Status?

  • integers, characters, strings, bools, arrays
  • structs, classes, enums, functions, methods, closures
  • all the usual flow of control, including defer (there went a week of re-engineering)
  • next up? reference counting (class instances are currently immortal).
  • and then start writing some real programs instead of test programs and see what's needed.

While pondering what progress could be made in programming languages, I delved into how one might write single process, concurrent code to build systems with many simultaneous clients. It seemed that a stumbling block to feeding such a system was the weird mismatch with Unix and its mostly blocking API.

So, I did the only reasonable thing and started to build my own operating system. It started simply enough with a visit to OSDev.org and wondering if I could just make something say Hello World., and then maybe some keyboard input… and a VT console emulator (multiple virtual), well then I needed serial ports to send out diagnostics, and then a TCP/IP over Ethernet. All that meant I needed a filesystem like thing to store my executables and loaders for the executables and some interpreters to run… Lua, then Wren…

Mini-Moral: Don't visit OSDev.org unless you have a few free years.

Stubborn Guiding Principles of My OS

  • Force concurrent programming to be the best way. This is to force me to encounter the warts and problems and resolve them or document them and live with them.
  • Don't have a full C Runtime Library and POSIX. This will keep me from falling back into the easy, decades old solutions.
  • I can make C do concurrent programming, but it really hurts me. For the low level code user mode code I wrote a concurrent programming library for C, but it is really a pain to use it. This is not the answer, but it let me try out some program architectures by implementing the various OS bits and bobs in different styles, if somewhat clumsily.
  • I want the user mode programs to be in a safe, high level language. There just isn't much point in programming in a language that finds bugs at runtime when you build cycle is "build new OS image, reboot computer, test". There isn't much point in a language that finds its bugs at run time anyway, but certainly not here.
  • Communication between user mode programs must be fast and clean. Ideally there will be zero OS intervention in the communication. (except some scheduling when a process blocks on all of its IO options). I don't want IPC costs to impact the architecture. If lots of heterogeneous processes is the answer, then that's the way I'll go.

Questions You Might Have

What is it called?

For a long time it was named os. But I recognized that was going to be a ungoogleable. Eventually I spent a day and named it "osy", because that was short, googleable, a nod to various simple OS names over the years, and clearly one better than OS X. Apple changed their OS name and ruined my joke. I'm keeping the name.

What kind of OS is it?

I don't want to call it a micro kernel, but the kernel does processes, memory management, scheduling, some primitive bootstrap facilities that are done better in user mode once we get up, and a couple of devices that kind of have to be done in the kernel (interrupt controllers and timers).

Have you ever heard of L4?

Yes. I wasn't aiming that way, but I did land pretty close to L4.

What is the kernel written in?

The kernel is ~6600 lines of C and 400 lines of assembler. That for ia32 and x86_64 architectures, though I'll throw out the ia32 next time I'm in there.

I use a number of Clang C extensions to great effect. Between cleanup and overloadable I end up with much more readable code, and cleanup in particular eliminates a whole class of errors.

You seem to have left out a lot of stuff, like devices.

Not a question, but yes. That is all done out in user mode processes. Not untrusted, if you are going to give a process enough access to enumerate your PCI address space, then you are trusting it.

The goal is to make use of the large numbers of cores available in modern systems by splitting tasks among them vertically as well as horizontally. IPC is cheap by design, and we'll see where that leads us in the solution space.

For now Ethernet, IP, ARP, UDP, and TCP are each a separate process communicating as needed. Surely that isn't the ultimate answer, but it lets me stress the communication. Oddly, it might be the answer for the general case, but acknowledge that UDP and TCP arrive as if by magic through off chip accelerators on high performance network cards.

There still seems to be a lot missing.

Most of the work ended up being in user mode. There I struggle with different models of concurrent programming and try to decide what I want.

I've been through C, Lua, and Wren for my user mode code. Device drivers are all in C, but are pretty simple in architecture so that works out. Lua was quick to port, but ultimately it isn't a sturdy enough language to make me happy. Wren was trivial to port and I like it, but I keep having odd performance issues I can't pin down and I've decided I need a real compiled language if I'm to make any judgements about performance.

I spent a couple weeks trying to port Swift to the OS, but was ultimately defeated by the thousands and thousands of lines of CMake with endless build variants and strange special case rules for OSes. So I went back to the "language" that started this blog, started over using Swift to write the compiler, and will use that to make my user mode programs. I just need to understand what the language is generating, and be able to alter the language to handle the concurrent communication without descending into a see of language warts.

The Swift server packages are documented with the inline comment documentation system. I went ahead and used it for my recent test mule project (femtoblogger, you're soaking in it).

It's easy enough to add documentation, Xcode has a CMD-click Add Documentation menu that will jam in a template for your function with spaces for all the parameters and return types. You just type markdown after that. If you add an argument, click it again. Xcode will add more template.

Now people can Option-click on your function name (or whatever) and get a lovely Quick Help pop up.

I appreciate this greatly for libraries.

But…

There doesn't seem to be any pathway from this snippets to a real document where the big picture is explained, and all the functions listed in well organized categories. You know,… like the good old Apple documentation.

"Good enough" is the enemy of "Good".

This isn't a special flaw for the Swift comment based documentation. Essentially all in code systems I've ever used have suffered from this. (Halfway excepting one I wrote, but you can't use.)

The Moral

  • Do your "in code" comments.
  • Update your "in code" comments when you change the code.
  • Write book like documentation somewhere! and put the links to it in HUGE type in the middle of your project page.

Well that was a fair bit of gap in between posts.

Femtoblogger is now on its 4th implementation. I feel the need to try out Swift on the server, so here we are. 100% pure Swift Femtoblogger.

The previous incarnation was Go. Before that was PHP. There was probably a never deployed Python version in there too.

Thoughts on Swift and the design of the server this time around…

  • I very much like the type safety of Swift. When I code in Swift there are no runtime explosions, and very few bugs discovered in testing.
  • The Swift code is more information dense than the Go code was. The Go code felt like a great sea of text with a little bit of content. The Swift code packs a lot of content into a screen of code.
  • Performance appears to be a non-issue. SQLite backed pages are serving in 3-12ms. For comparison I added a caching layer for most popular queries and dropped that into the 80µs range for the query handling. That's not real, I handle them by doing a X-Accel-Redirect header back to Nginx and letting it serve a file out of a RAM disk directly. But it means my process is not going to be buried.
  • I haven't bothered with any compiler optimization. I want the checks to stay in place while I see if I've screwed up somewhere.

The Network End of Things

  • The Swift server network library, NIO, really wants to push you into a futures and promises style of programming. I resisted because it is so clumsy at the source code level. Your code begins to vanish under a sea of ritual. That said, I probably would have been better off to embrace it. A request needs to get out of the network queues to free them up while it gets in a non-concurrent model queue to work with the data, then out of there as soon as possible and into a render queue to do template expansion and back into the network queues to send the data out. It's a lot to coordinate.
  • I suppose I'll continue avoiding futures and promises in femtoblogger until Swift 6 and the beginning of its new concurrency model make it into NIO.
  • I didn't use Vapor or similar web frameworks, I build my server directly on NIOHTTP1 so I'd understand the architecture. The first 90% was simple! Then I needed to parse some form data and couldn't find the calls in the API. Eventually I found an email in a filing cabinet behind a sign that said "Beware of the Leopard" where the NIO team proclaimed that "out of scope". Maybe I'll make a post on parsing "multipart/form-data" (which can't be a String because it might not be valid) and parsing HTTP header values.

Using Other People's Packages

  • I did reach out for 'random dude' packages for a higher level SQLite API, Markdown to HTML conversion, and template expansion. It's a bit of a mixed bag there. I'm glad I did it, but there were issues. As always it seems to take a lot of research time to figure out which solution is well supported, not horrible, and will likely last a while.
  • I used SQLite.swift for accessing SQLite. The tutorial writing crowd on the internet likes it. It gives you a type safe way of interacting with SQLite without too much ritual. The package is a few years old and has been dormant for most of a year. I found a design flaw where it would try to read a mismatched datatype and explode your process. (Just because you called a SQLite column TEXT doesn't mean it isn't going to return a BLOB for one of the rows.) It looked to be an involved fix to use the receiver's datatype instead of the provider's, and in the absence of an active maintainer I didn't want to invest in making the changes. It was easier to rewrite all the rows to have their TEXT really be TEXT.
  • I used Ink for Markdown to HTML conversion. It is simple to use. Out of the box it choked on CRLF line endings. The patch ended up being a , "\r\n" in just the right place, plus about 16 lines of test cases. Hint: "\r\n" is a single Character in Swift… grapheme clusters and all. The maintainer is active so I sent that one in.
  • I used Stencil for template expansion. I've used it before and the rough edges I used to have to hammer off are now addressed. Note: Stencil could really use a SafeExpansion mode which escapes HTML for when you have untrusted users. It has user created filters, I ended up making one instead of forking and adding a safe expansion feature.

When your friend's laptop is at full disk, stop them from trying to make space by going through their tiny documents and deleting things that will be missed or finding that pesky Library folder that contains a bunch of gunk they never wanted and deleting that.

Go to the Mac App Store and download Free Disk Space. It will show what is really taking up all the space and should be dealt with.

Personally, I've used Space Gremlin for years, but Free Disk Space is free and does the job.

Update: Apparently Free Disk Space decided money is good. They are $10 now,

I’ve been using USB cameras on tiny repurposed routers, beagle bones, and raspberry pis for some time. I’d like to deploy more cameras, but I am on a tight power budget where every watt matters and my DC power controller that allocates the power is out of ports and I don’t really want to build another one.

Enter “power over ethernet” (PoE) cameras. These hang on an ethernet cable and receive their power from that cable so I only have to run out a cat5 and I’m set. I can buy ethernet switches with PoE and control which devices are powered at any given time.

Danger: most lower cost “smart” switches allow you to control the port power, but only through their silly web interfaces, they don’t allow it over SNMP until you pay for an enterprise device. It appears SMC has a model that will allow SNMP control.

In the made up land of retail pricing, PoE cameras are a little pricey compared to their less capable friends. Fortunately China is a really big place and lots of things are made and sold there. I found 720P PoE cameras for $25 each delivered half a planet away.

Good: They have pretty good picture quality, aluminum “weather proof” enclosures, IR lights for night time, and you can order with four different focal lengths. H.264 over rstp.

Bad: They really sad documentation, on a mini-CD, like I own a tray loading CD drive. Are hardwired to boot on 192.168.0.103 despite documentation that gives a different address, have an open telnet port with a root account backdoor with fixed password, respond with a web interface only in Chinese that doesn’t let you configure the camera in Chrome and Safari. Chrome will offer to guess at translations and turn the text back near English.

That “Bad” entry took me about 3 hours to work out. I do not have the root password, but apparently some tech support responses give it to you.

Proceeding onward, I got Microsoft to give me a demo copy of Windows 8.1 and spun that up in a VirtualBox. If you hit the camera with Internet Explorer, enable Active-X downloads from unknown and untrusted developers and basically give total control of your machine over to unabashedly anonymous people, then you get a web interface that can be used in English and can tell the camera to use DHCP or some static address of your choosing. (I use DHCP for everything and then tell my DHCP server to give a static address to certain MACs.)

The rstp streams can be found at rtsp://camera.example.com:554/user=ACCOUNT&password=PASSWORD&channel=1&stream=0.sdp?real_stream--rtp-caching=100 for the high res stream, and stream=1 for the low res.

Unresolved: I’d like to find a URL to pull a single frame. Perhaps if I figure out how to query the ONVIF interface enough it will tell me.

Further thoughts: It is hard to fathom how someone can sell me a computer, with a camera for $25, in a nice aluminum case and ship it half a planet on demand. Because I need individual control of the power on the switch ports, I’m spending almost that much on the hole in the switch!

Update:

These were garbage. They weren’t weatherproof in any meaningful way and rapidly succumbed. They also have hard coded root backdoors in them.

The following modules need to be added to the Debian init ramdisk to support root on a 9p disk:

./kernel/fs/9p/9p.ko
./kernel/net/9p/9pnet.ko
./kernel/net/9p/9pnet_rdma.ko
./kernel/net/9p/9pnet_virtio.ko

To add these modules, you will extract an init ramdisk (which is just a compressed cpio archive), add the files, and run a depmod -a in it. Then re-archive it.

The commands I used to make mine are:

#!/bin/sh

set -e

mkdir /tmp/9p-ramdisk
cd /tmp/9p-ramdisk
zcat /boot/initrd.img-3.16.0-4-amd64 | cpio -id

mkdir lib/modules/3.16.0-4-amd64/kernel/fs/9p
mkdir lib/modules/3.16.0-4-amd64/kernel/net/9p

cp /lib/modules/3.16.0-4-amd64/kernel/fs/9p/9p.ko lib/modules/3.16.0-4-amd64/kernel/fs/9p/9p.ko 
cp /lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet.ko lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet.ko 
cp /lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_rdma.ko lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_rdma.ko 
cp /lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_virtio.ko lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_virtio.ko 

depmod -b /tmp/9p-ramdisk

find . | cpio -o -H newc | gzip > /boot/initrd.img-3.16.0-4-amd64-9p

Update: This works, but seems to be a bad idea. When I try to do aptitude update it fails with lines like this…

E: Unable to determine file size for fd 7 - fstat (2: No such file or directory)
E: Problem opening /var/lib/apt/lists/ftp.debian.org_debian_dists_jessie_contrib_binary-amd64_Packages
E: The package lists or status file could not be parsed or opened.
E: Unable to determine file size for fd 8 - fstat (2: No such file or directory)
E: Problem opening /var/lib/apt/lists/ftp.debian.org_debian_dists_jessie_contrib_binary-amd64_Packages
E: The package lists or status file could not be parsed or opened.

… which seems to say that 9p has a problem with some operation aptitude needs.

Back to disk images for me.

Yep, I ran into the same issue last week. There is an open ticket to track it: https://bugs.launchpad.net/qemu/+bug/1336794

If you have an old HP plotter, you will find that the Mac OS X drivers available from HP’s support site can not be installed because they are in an old VISE .hqx format installer.

If you go and get a generic PPD for the printer, and stick it gzipped in /Library/Printers/PPDs/Contents/Resources then you will be able to select it as a printer type when you add the printer.

Attached is the one I found and used. It needs more work, I am getting postscript errors at the end of prints which can use a lot of paper. But it is working.

Update: It looks like you can disable postscript error printing with…

defaults write com.apple.print DoPostScriptErrorHandler NO

…and re-enable it with…

defaults delete com.apple.print DoPostScriptErrorHandler

Update2: The defaults thing does not appear to work.

Update3: Using HP JetDirect as the protocol instead of LPR seems to have fixed the PostScript error problem.

Attachments

Thanks for posting this. I’ve been searching for this PPD for quite a while. Did you did it out of an Adobe set per chance?

Works for me, OS X 10.13.4 on 20180518. Copied gzip directly to /Library/Printers/PPDs/Contents/Resources and renamed to ‘HP DesignJet 755cm.gz’

Selected with JetDirect card & protocol. After print completed (looks good, color from Fusion360 demo sheet size B), there was about a ‘C’ sized drawings worth of blank, followed by text indicating “Error Undefined, OFFENDING COMMAND: Stack”

Thanks, would like to improve it too…tried with Windows drivers and Parallels multiple times. You’ve saved my DesignJet Thanks.

more articles