[HN Gopher] A standalone zero-dependency Lisp for Linux
___________________________________________________________________
A standalone zero-dependency Lisp for Linux
Author : keepamovin
Score : 112 points
Date : 2023-11-03 08:44 UTC (3 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| nerdponx wrote:
| > Lone is a freestanding Lisp interpreter designed to run
| directly on top of the Linux kernel with full support for Linux
| system calls. It has zero dependencies, not even the C standard
| library.
|
| Cool project! Not sure if I'm going to start using it any time
| soon, but cool nonetheless.
| matheusmoreira wrote:
| Thank you!
| ashton314 wrote:
| Very cool! In a similar vein there's Zuo:
| https://github.com/racket/zuo
| nerdponx wrote:
| Zuo is interesting because (as far as I know) its primary user
| is the Racket project itself, for bootstrapping the compiler.
| ashton314 wrote:
| That is correct
| ape4 wrote:
| A quick glance shows it uses GNU Make but that's only a build
| time dependency, I guess.
| yjftsjthsd-h wrote:
| All software needs dependencies at build time, saying no
| dependencies always means runtime.
| blueflow wrote:
| I'm surprised the Kernel doesn't count here.
| yjftsjthsd-h wrote:
| At that point we really get into semantics... But now that
| you mention it, I would be interested to see if it could be
| built with APE to benefit from their bare metal support.
| rollcat wrote:
| It does.
|
| Writing your software to directly use the syscalls of a
| specific kernel does not make it "zero dependency", it
| makes it "one dependency" - and non-portable.
|
| The author elaborates on their rationale and the technical
| details in a blog post:
| <https://www.matheusmoreira.com/articles/linux-system-
| calls>
|
| TBH I have mixed feelings about this approach. It's true
| that this is more or less what Go or (Cosmopolitan libc)
| do, but the motivation in their case is to maximize
| portability (by making cross-compilation trivial). However
| when you #include <linux/...>, you not only make your
| software non-portable, you also make it a PITA to cross-
| compile as you need the kernel headers on the host machine.
|
| In contrast, with Go or cosmo, I can trivially build a tiny
| /sbin/init for amd64 Linux, pack it up with cpio, and run
| it with qemu-system-x86_64 -initrd - all from a Mac/arm64
| host.
| craftkiller wrote:
| Surely its more than one dependency. For example, you'll
| need a processor. Not just any processor, but a processor
| for which a C compiler has been written.
| matheusmoreira wrote:
| That's a _great_ question... I wonder if Justine would be
| interested in that. She has her own sector lisp too.
| matheusmoreira wrote:
| > However when you #include <linux/...>, you not only
| make your software non-portable, you also make it a PITA
| to cross-compile as you need the kernel headers on the
| host machine.
|
| Yes, that is certainly a problem that I need to solve.
|
| I added some support for cross compilation in the
| makefile. It currently requires clang for that.
| ifdef TARGET ifndef UAPI $(error UAPI
| must be defined when cross compiling) endif
| TARGET.triple := $(TARGET)-unknown-linux-elf
| override CC := clang -target $(TARGET.triple) else
| TARGET := $(shell uname -m) endif
|
| With this, I was able to cross compile lone for x86_64
| from within the Termux environment of my aarch64
| smartphone. All I had to do was obtain the Linux user
| space API headers for x86_64. Getting those headers was
| somewhat annoying but doable, there are packages for them
| in many Linux distributions.
|
| I made a Termux package request for multiplatform Linux
| UAPI headers specifically so I could cross compile lone
| but unfortunately it was rejected.
|
| https://github.com/termux/termux-packages/issues/16069
| matheusmoreira wrote:
| Yes. It has zero runtime dependencies but development currently
| assumes GNU tools. The test suite for example is entirely
| written in bash and uses GNU coreutils. I submitted a patch to
| coreutils to allow env to set argv[0] of programs specifically
| so I could use it in my test suite.
|
| Currently lone is a single C source file. It could easily be
| compiled manually if necessary. I've started reorganizing the
| repository though so that's likely to change.
| nanolith wrote:
| This is interesting. Although, I think it's always useful to
| point out that runtimes that directly make system calls will have
| portability issues in other *nix systems. For instance, OpenBSD
| has recently restricted system calls to a single offset of their
| libc in order to reduce ROP attacks.
|
| If Lone wishes to be portable, it will need to consider a libc
| dependency as an option. If not, it can probably get away with
| direct syscalls on Linux unless Linux kernel developers decide to
| add support for pinning system calls. I doubt that this would
| ever be a hard requirement in the kernel, as it would break
| userland all over, but I could see this being an option for
| certain distributions as a ROP mitigation. Many features like
| these flow from OpenBSD to other OSes.
| edgyquant wrote:
| Considering the title and use case it seems to be intentionally
| pretty specific to Linux
| nanolith wrote:
| Many projects start this way. But, as per my comment, the
| assumption that direct syscall support will be maintained in
| future Linux distros is also risky.
| matheusmoreira wrote:
| I worry about that risk as well. I assume that even if
| Linux were to introduce a mechanism for system call
| authentication, it would be something lone would be able to
| use to mark its system call primitive as allowed.
| nanolith wrote:
| Perhaps. To be fair, I'm not aware of anything on the
| horizon, other than the fact that OpenBSD has been
| showing off their pinning implementation.
|
| As long as you know it's a possibility, then the point of
| my original comment is met.
|
| Good luck on this project. I look forward to seeing it
| progress.
| matheusmoreira wrote:
| Thank you!
| kwhitefoot wrote:
| Why is it risky? Linus is adamant that the greatest sin is
| breaking userland.
| Conscat wrote:
| I think this decision from OpenBSD will more likely discourage
| developers from even considering it a supportable platform for
| software that originates in Linux land.
| nanolith wrote:
| Direct syscall access is not something that is guaranteed in
| Unix derivatives. Linux is rare in that it provides a stable
| syscall API. Source compatibility is often only guaranteed
| when linked against libc or an equivalent low-level runtime
| library.
| eikenberry wrote:
| And this is generally a bad pattern unless those libc
| equivalents are services you call (like syscalls) and not a
| library you have to import or FFI. Requiring importing a
| library, probably from another language, is not a good
| alternative to syscalls.
| nanolith wrote:
| A bad pattern according to whom? Most language runtime
| libraries import other system libraries as needed. For
| better or for worse, libc is typically considered to be a
| system library. It's something that every distribution or
| Unix flavor provides that is guaranteed to work within
| the POSIX standard for interfacing with the operating
| system. It's up to the distribution maintainers to make
| that happen, even if they tweak things to support syscall
| pinning or seccomp rules.
|
| Userland directly calling a stable syscall API is a rare
| thing outside of Linux, and there is no guarantee that it
| will last forever even in Linux given the latest attacks.
| With modern ROP mitigations like syscall pinning, it will
| in fact be more dangerous to make syscalls directly -- if
| allowed in your distribution -- than it would be to call
| the minimal footprint of libc required to bootstrap a
| high level language runtime.
|
| Of course, with special pleading, it could be possible
| for distribution or OS maintainers to carve out an
| exception for syscall pinning for a particular language
| runtime. Ask Go how that's going for their OpenBSD port.
| eikenberry wrote:
| The problem with system libraries requiring importing
| them as C libraries isn't new and doesn't seem to be
| going away. It has caused all sorts of problems for
| alternative languages over the years that it seems like
| an alternative would give all of computing a giant boost
| by allowing different models that don't work well with C.
| Stabilizing and standardizing the syscall interfaces
| would be one way to accomplish this and is the closest
| thing we have to it now. Implementing syscalls as a
| separate service might also work but then you have the
| IPC overhead. That might not be as bad though as we'll
| end up with something like that anyways as requirements
| ramp up for C to have it's own runtime (eg.
| https://dslab.epfl.ch/research/cpi/).
| dontlaugh wrote:
| No, it's fine. And common, macOS and Windows do the same.
| baq wrote:
| To be fair, linking to kernel32 is a bit different than
| linking to msvcrt, but yeah, it's Linux who's the
| slightly insane person in the room, not the other way
| around.
| dontlaugh wrote:
| I wouldn't say insane exactly, but definitely overly
| restrictive.
| matheusmoreira wrote:
| You're absolutely right, it is not portable to other operating
| systems. I have written about this portability and system call
| stability here on HN a few times, at some point I decided to
| compile all the information into a post on my website.
|
| https://www.matheusmoreira.com/articles/linux-system-calls
|
| I started lone (and previously a liblinux library) in order to
| make applications directly targeting the Linux system call
| binary interface. I chose Linux precisely because it's the only
| one with a stable interface.
|
| I currently have no plans to make lone a portable programming
| language.
| netbioserror wrote:
| So I guess the difference from Janet is no C standard library
| dependency; is this being targeted for hyper-slim and embedded
| uses? Because Janet seems like a good choice for most desktop and
| server cases.
| matheusmoreira wrote:
| Yes. My current goal is to boot Linux directly into Lisp and
| bring up the rest of the system from there. Perhaps even create
| a Lisp user space.
| FredPret wrote:
| I'm new to Lisp - would this then be a modern Lisp machine?
| f1shy wrote:
| Well, if by lisp machine we understand a processor that can
| run native lisp, of course not, but I was dreaming with a
| modern lisp machine, and this is the best that can be
| practically made
| matheusmoreira wrote:
| It's certainly what I had in mind when I started the
| project. Writing a full Lisp operating system is extremely
| hard, better to take advantage of Linux and its drivers so
| as to avoid spending an entire lifetime recreating them.
|
| It's my understanding that a true Lisp machine would have
| hardware support for Lisp abstractions at the instruction
| set level, so I don't think the concept would apply to
| lone. I would be seriously honored if people considered it
| one though, even if only in spirit.
| matheusmoreira wrote:
| Hello everyone! I started this project, happy to answer any
| questions.
|
| I was hoping to polish it up a bit more so it would be worthy of
| a Show HN, never thought someone else would submit it here.
| Really made my day!
| rcarmo wrote:
| Nice. I can see something like this being used with circle
| (https://github.com/rsta2/circle) to run bare metal on a Pi, too.
| gigatexal wrote:
| Very cool project. Not commenting on that. Lisp and it's
| derivatives often hits the front page of HN and I always wonder
| why. What is it about lisp that is so powerful? so much so that
| some see it as the platonic ideal of programming languages or so
| it seems?
| packetslave wrote:
| It doesn't hurt that HN is written in LISP.
| f1shy wrote:
| Well, Y combinator, the domain of HN is intimately related to
| Lisp, as the founder Paul Graham. That is how I landed in this
| site to begin, and I assume is so for many around. That could
| explain it a little bit.
| barbazoo wrote:
| > Ask HN: Why is everyone here so obsessed with Lisp?
|
| https://news.ycombinator.com/item?id=20697493
| gigatexal wrote:
| Ahh okay. Paul Graham and the hackability of the language
| itself. Got it.
| jng wrote:
| Beautiful. Also, after 30+ years of writing C and C++, I learned
| one thing by casually browsing the source code: you can use a
| preprocessor macro in an #include statement. Thanks.
| matheusmoreira wrote:
| Yes! GCC calls it computed includes.
|
| https://gcc.gnu.org/onlinedocs/cpp/Computed-Includes.html
|
| I used it to include architecture-specific source code and also
| a generated C file containing a table of Linux system calls
| defined by the Linux UAPI lone is compiled against.
___________________________________________________________________
(page generated 2023-11-06 21:00 UTC)