> But my first attempt was a complete failure - I understood almost nothing.
This is how I feel every time I dig into something. Disappointingly, rarely do I have the time or focus to truly learn how something really works. Be it a library I am using, or a physics concept I want to learn more about.
Good for him for getting through it. I am adding this to my long ass list of things I would read if I could freeze time like that girl from the 90's TV show.
I recently bought a USB serial cable online to play around with this sort of thing, and promptly saw a blue-screen in windows 10 for the first time I can remember.
It turned out I had unknowingly bought a fake Prolific cable and the (non-fake) windows driver was crashing my whole system every five minutes or so when the cable was connected.
I worked around this by tracking down an older driver with no crash issues so I guess the latest one does this deliberately?
In any case, if you are planning on getting a USB serial cable make sure it's not a counterfeit, if you can.
I personally stick with Silicon Labs CP210x devices ever since I had bad luck with Prolific. I avoid FTDI chips as well because of the aggressive anti-consumer behavior of FTDI in regards to their drivers.
i recommend C to start with because there are more low-level projects you can work on for practice in C than in Rust; the biggest one being kernel hacking. i definitely recommend K&R to get familiar with the language, but it's a small language so that shouldn't take too much time.
i think the best way to get started in low-level programming is to develop in linux on a raspberry pi and hack your own kernel. explore sysfs, ttys, and gpios. implement new syscalls and device drivers. then go bare-metal on the arduino or a PIC16 chip and build an interesting piece of hardware.
i've collected a lot of my favorite low-level programming tutorials and deep-dives on my HN profile page, but if i were to pick just a couple, they would be:
You won't appreciate a lot of the protection that Rust gives you until you have spent some time with the freedom to make the mistakes yourself. Stuff like pointer arithmetic really helps you get into the mindset of how a program really executes. Rust tends to abstract this away and put in all these seemingly arbitrary (that's probably what it would feel like coming from a GC language) rules.
Plus C is well documented and supported everywhere. Tons of learning resources and you can guarantee that if you have a question someone else is bound to have had the same question and asked it. Rust, being newer, doesn't have quite as much.
The C Programming Language is about the best book you can read to learn C, in my experience. Then go work on a non-trivial project like writing a command-line calculator.
I recommend toying with an arduino. The Arduino itself can be obtained for less than 3$ on Aliexpress (Nano with a microusb is a good start)
They don't have any OS, rather, your program runs basically on the CPU directly. You can try to develop a OS from there, the CPU supports almost everything you need; interrupts and timers.
The only real limitation is that you have 2KiB of memory, on the other hand, it can be extended if you are willing to solder on a SRAM (2$ for 64KByte) or you can see it as a challenge to get an OS with a few processes working with such little memory.
The chip also has some advantages; since data and code live in seperate memory, you can't really crash or damage the chip by going out of bounds in an array. You can program something fairly robust in an arduino.
I’d take on a project that benefits from using C over Python. Maybe port something old and valuable to a module with tests and whatnot in comfortable Python.
On the Java side where I live you can also compile native modules without much fuss.
I suggest this because it adds new to something familiar.
One thing I would not do is focus on making the first project maintainable etc or you’ll never get out the gate... stitch it together and redo it. Really 2 different programmers would be doing it, so no harm no foul.
Read documentation like it’s a good book... if it’s boring or not good then you’re not engaged enough so pick another project—supporting the disposable idea.
Learning it will definitely make you a better c/c++ developer. It'll beat memory safety into you with whatever you give it.
That said, although it does have great c abi interop, it doesn't build on as many platforms as c. And I think there might be some knob or levers that c provides for low level stuff that rust doesn't expose on stabe yet (SIMD, const stuff, and probably more)
That said, I think once you get past the borrow checker, programming in rust is considerably more enjoyable.
Nand To Tetris: Building A Modern Computer From First Principles is an accessible, structured, bottom-up course in low-level stuff.
You start out by composing simulated hardware gates to create higher-order gates, eventually creating a CPU and entire computer. Then you move into assembly, and eventually build an OS. All of the homework has automated grading, so it’s very possible to self-study.
I would propose Linux Kernel Development by Robert Love. It is not for beginners though.
That could help you in applying your new C skills in writing a simple device driver/kernel module you can play with. If are really into low level stuff I would propose an Arduino board whose OS is minimal, the Linux kernel is already very complex.
Get a role in an embedded software company and you may learn it all, but some experience is required.
I've recently started to work on an implementation of Forth, targeting the RPi. Only runs on Qemu at the moment. A great way to learn about low level programming
I'm not familiar with low-level, so I'm not sure how "low" you mean, but I've begun the NAND2Tetris course on coursera and it's pretty great so far. You basically implement a VM from scratch: https://www.coursera.org/learn/build-a-computer
I'd also like to learn how to code in C/Rust, but the amount of time I need to invest in it to be even partially sufficient is discouraging. It's completely different from my current job, being a C#/JS full stack web dev.
How does this deal with the binary blobs that need to start the boot loader? From memory the older models needed to launch the graphics chip first which was a hack-y nightmare with no open source way of doing it.
The raspberry pi is built on top of a graphics chip with some ARM cores tacked on as an afterthought. [1]
The binary blobs are not firmware. A full proprietary RTOS called ThreadX is running on the Raspberry Pi as the primary OS and this won't change until they move off of broadcom's video core.
It ignores that and starts at the point where the kernel is loaded by that first-stage bootloader. Which is very reasonable for a beginner's introduction.
Based on the title I was hoping more emphasis on the interesting userland bits, leaving the boring kernel parts to Linux. I feel that osdev generally focuses too much on the well-trodden elementary basic building blocks, and less on actual systems design, which has left the community with endless half-baked (generally more or less posixy style) kernels and few novel userlands.
Android is great example how you can do interesting OS development work by building upon stable foundations, focusing on userland, but also not fearing to poke kernel when needed.
I don't mean to disparage anyone, least of all the repo here that seems pretty nice resource for what it is. Just the title happened to tickle my imagination just right.
[+] [-] vinhboy|7 years ago|reply
> But my first attempt was a complete failure - I understood almost nothing.
This is how I feel every time I dig into something. Disappointingly, rarely do I have the time or focus to truly learn how something really works. Be it a library I am using, or a physics concept I want to learn more about.
Good for him for getting through it. I am adding this to my long ass list of things I would read if I could freeze time like that girl from the 90's TV show.
[+] [-] satori99|7 years ago|reply
It turned out I had unknowingly bought a fake Prolific cable and the (non-fake) windows driver was crashing my whole system every five minutes or so when the cable was connected.
I worked around this by tracking down an older driver with no crash issues so I guess the latest one does this deliberately?
In any case, if you are planning on getting a USB serial cable make sure it's not a counterfeit, if you can.
[+] [-] hueving|7 years ago|reply
[+] [-] oakwhiz|7 years ago|reply
[+] [-] Fnoord|7 years ago|reply
[1] https://www.amazon.de/gp/product/B00QUZY4UG
[2] https://www.amazon.de/gp/product/B00SBBFUAA
[+] [-] O_H_E|7 years ago|reply
How much do you recommend "The C Programming Language" for someone who just used Java / Python, and wanna start learning C and low level?
Do you recommend learning "current" Rust as a first low level Lang.
[+] [-] woodrowbarlow|7 years ago|reply
i think the best way to get started in low-level programming is to develop in linux on a raspberry pi and hack your own kernel. explore sysfs, ttys, and gpios. implement new syscalls and device drivers. then go bare-metal on the arduino or a PIC16 chip and build an interesting piece of hardware.
i've collected a lot of my favorite low-level programming tutorials and deep-dives on my HN profile page, but if i were to pick just a couple, they would be:
"Write a System Call": https://brennan.io/2016/11/14/kernel-dev-ep3/
"The TTY Demystified": http://www.linusakesson.net/programming/tty/
And a book, "Linux Device Drivers, 3rd Edition":https://lwn.net/Kernel/LDD3/ (free!)
protip: as you're getting started with kernel hacking, use kernel 2.6. LDD3 uses 2.6, as do a wealth of other books.
[+] [-] weavie|7 years ago|reply
You won't appreciate a lot of the protection that Rust gives you until you have spent some time with the freedom to make the mistakes yourself. Stuff like pointer arithmetic really helps you get into the mindset of how a program really executes. Rust tends to abstract this away and put in all these seemingly arbitrary (that's probably what it would feel like coming from a GC language) rules.
Plus C is well documented and supported everywhere. Tons of learning resources and you can guarantee that if you have a question someone else is bound to have had the same question and asked it. Rust, being newer, doesn't have quite as much.
[+] [-] saagarjha|7 years ago|reply
[+] [-] zaarn|7 years ago|reply
They don't have any OS, rather, your program runs basically on the CPU directly. You can try to develop a OS from there, the CPU supports almost everything you need; interrupts and timers.
The only real limitation is that you have 2KiB of memory, on the other hand, it can be extended if you are willing to solder on a SRAM (2$ for 64KByte) or you can see it as a challenge to get an OS with a few processes working with such little memory.
The chip also has some advantages; since data and code live in seperate memory, you can't really crash or damage the chip by going out of bounds in an array. You can program something fairly robust in an arduino.
[+] [-] harlanji|7 years ago|reply
On the Java side where I live you can also compile native modules without much fuss.
I suggest this because it adds new to something familiar.
One thing I would not do is focus on making the first project maintainable etc or you’ll never get out the gate... stitch it together and redo it. Really 2 different programmers would be doing it, so no harm no foul.
Read documentation like it’s a good book... if it’s boring or not good then you’re not engaged enough so pick another project—supporting the disposable idea.
Good endeavors grow legs.
[+] [-] swsieber|7 years ago|reply
Learning it will definitely make you a better c/c++ developer. It'll beat memory safety into you with whatever you give it.
That said, although it does have great c abi interop, it doesn't build on as many platforms as c. And I think there might be some knob or levers that c provides for low level stuff that rust doesn't expose on stabe yet (SIMD, const stuff, and probably more)
That said, I think once you get past the borrow checker, programming in rust is considerably more enjoyable.
[+] [-] kaycebasques|7 years ago|reply
You start out by composing simulated hardware gates to create higher-order gates, eventually creating a CPU and entire computer. Then you move into assembly, and eventually build an OS. All of the homework has automated grading, so it’s very possible to self-study.
http://www.nand2tetris.org/
[+] [-] pulsarpietro|7 years ago|reply
That could help you in applying your new C skills in writing a simple device driver/kernel module you can play with. If are really into low level stuff I would propose an Arduino board whose OS is minimal, the Linux kernel is already very complex.
Get a role in an embedded software company and you may learn it all, but some experience is required.
[+] [-] markb139|7 years ago|reply
[+] [-] majidazimi|7 years ago|reply
[0] https://nostarch.com/tlpi
[+] [-] tenaciousDaniel|7 years ago|reply
[+] [-] Phronux|7 years ago|reply
[+] [-] zeth___|7 years ago|reply
[+] [-] imtringued|7 years ago|reply
[1] https://www.heise.de/ct/zcontent/16/08-hocmsmeta/14601932130...
[+] [-] pjc50|7 years ago|reply
[+] [-] zokier|7 years ago|reply
Android is great example how you can do interesting OS development work by building upon stable foundations, focusing on userland, but also not fearing to poke kernel when needed.
I don't mean to disparage anyone, least of all the repo here that seems pretty nice resource for what it is. Just the title happened to tickle my imagination just right.
[+] [-] molteanu|7 years ago|reply