Hello! First of all this is my first Lemmy post, so if I did anything wrong pls tell me!

Now, I’m 19yo in 4th semester of Computer Engineering, and while I’m doing good in college I realized that they give us good background in electronics (from the basics to microcontrollers. ICs. logical design, etc) but the programming aspect is high level and web-oriented (python. java, php)! I appreciate learning those, but I’m not interested on that but rather on a kernel/firmware development! So… I’ve been learning C for some weeks and while I do love it (mainly been learning from K&R and Zed A. Shaw - Learn C the Hard Way) I don’t really know how to practice the skills required to do the proper bridge between hardware and software.

Basically, how does one begin their first real project to learn how to write drivers/baremetal and testing them? Thanks for reading and sorry if my question is dumb, I just feel a bit lost.

  • wwaaaaa@lemmy.dbzer0.comOP
    link
    fedilink
    English
    arrow-up
    5
    ·
    4 hours ago

    As a first time user in Lemmy, I’m so fascinated by the community, thank you all! I will be around so hopefully I can help others as much as everyone who commented here helped me.

  • CocoaBird@sopuli.xyz
    link
    fedilink
    English
    arrow-up
    4
    ·
    4 hours ago

    I’m going to give a slightly different suggestion.

    You may find it interesting to develop an program without using libc.

    Use raw syscalls and make a completely freestanding binary.

    This is not as low level as bare-metal but might give you a better understanding of how operating systems work.

    You could try writing some core utils replacements

    This will only really work on Linux though. Any systems programming language with inline assembly will work fine.

    • wwaaaaa@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      4 hours ago

      Now that you mention it I was actually messing around with that before commenthing this, I’m on Linux (Arch) already so the idea of writing utils replacement was already there haha, thanks for the suggestion, I’m doing that

  • owenfromcanada@lemmy.ca
    link
    fedilink
    arrow-up
    21
    ·
    edit-2
    7 hours ago

    You’re looking for what’s called Embedded Programming, which is that low-level stuff where the software you create makes things happen in real life outside of just a computer screen. There are lots of hobby beginner kits that come with things like motors, lights, etc. That’s probably your best bet for actually getting some hands-on experience.

    If you want something a little higher-level, go for something like a Raspberry Pi (a Single Board Computer or SBC). On these, you’ll have a full-fledged Linux kernel and operating system, but still have ways of interacting with hardware like lights and such. If you want to get lower level, try Arduino or something based on ESP32 (the key word here is microcontroller). On these, you’ll either use a smaller OS or go “bare-metal”. Though note that Raspberry Pi makes things at this level as well (their “Pico” line).

    For making that connection between computer theory and programming, I recommend experimenting with microcontrollers. You can even do some projects in assembly and understand what all the key registers are doing. I started on PIC micros, which was a great beginner thing. Not sure if they’re still around.

    If you want recommendations on a starter kit, let me know your budget and what country you’re in, and I can send some suggestions.

    Source: embedded programming for 20+ years.

    • wwaaaaa@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      11
      ·
      7 hours ago

      Thanks! Yes you completely nailed it, since I already have some circuitry knowledge (and I really find it fascinating) I guess I should start with microcontrollers, then the Raspberry Pi or similar SBC. I will gladly take into account your recommendations, my budget is kinda low since I live in a quite complicated country (Venezuela), so if you can give me the generals on what I should look for I would really appreciate it. Do you also suggest any book or learning resource?

      Also (sorry if I’m asking too much) do you think it is viable for me to get a remote job in this field, or a similar one that can make use of this skills? As you can imagine in this country the local offer is pretty low, basically non-existant.

      • kibiz0r@midwest.social
        link
        fedilink
        English
        arrow-up
        7
        ·
        5 hours ago

        If hardware cost/availability is an issue, there are a few hardware simulators out there. Wokwi (ESP32 sim) is free for personal open-source use.

        • wwaaaaa@lemmy.dbzer0.comOP
          link
          fedilink
          English
          arrow-up
          2
          ·
          4 hours ago

          Oh wow thanks, I was actually searching for something like that because it is very useful to practice until I can afford all the parts I want to implement.

      • owenfromcanada@lemmy.ca
        link
        fedilink
        arrow-up
        2
        ·
        4 hours ago

        No problem! I love chatting about this stuff, questions are always welcome!

        Not sure what online retailers are available or what you have access to in Vemezuela, but something like this starter kit would be ideal. But anything you can get your hands on can be fun.

        In general, you need:

        • a microcontroller
        • a way to program it
        • hardware to control and usually some sort of input or sensor

        Even if you can’t find a starter kit, finding a USB UART interface lets you hack into all sorts of devices (did that to reprogram a router a while back), as long as you’re handy with a soldering iron. And like another commenter said, hardware emulators would let you get started writing and running code if you can’t get hardware right away.

        Hope it’s fun! Feel free to DM with questions if you’d like.

        • wwaaaaa@lemmy.dbzer0.comOP
          link
          fedilink
          English
          arrow-up
          2
          ·
          4 hours ago

          I see! Well I’m going to take the suggestion and get a STM32 as another user pointed out and after some research I found it to be really good, and a kit with a bunch of resistors and other components, similar to the one you suggested but with less components (little by little I will buy more). I have actually done some soldering myself, not too complicated stuff I must admit, but atleast something. Also taking into account the DM since you are a welcoming person, thanks for helping me so much I have a way clearer plan now.

  • HelloRoot@lemy.lol
    link
    fedilink
    English
    arrow-up
    9
    ·
    8 hours ago

    Get one of those learning kits that come with most of SBC/MCUs (like raspberry pi or ESP32) which have a lot of random stuff (like LEDs, motors etc.) that you can hook up to the pins and write C programs to control them. Learn the different protocols that are used to talk to other devices, like i2c, uart, spi etc. and then buy some hardware that you can talk to via this protocol. Like a sensor, a gps module or an IMU or EEPROM.

    It’s conceptually pretty similar to how computers and device drivers do it. There is some communication protocol and you can write or read some values over it to use any device. It’s just way easier to start small and build up experience from there.

    • wwaaaaa@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      3
      ·
      7 hours ago

      Oh I see, well I’ve done some circuitry so that helps I guess. Thanks for clarifying, it’s just a bit intimidating but exciting field, I’m starting rn with some arduinos and basic sensors then. Also from a job perspective, do you see viable to pursue low-level development remote job? I have worked with git, and I’m working to improve my github profile so that I can offer more while polishing my skills, but I personally haven’t seen much remote job offers for low-level junior dev, sadly in my country it is not common either so that’s why I’m interested in a remote one.

      • HelloRoot@lemy.lol
        link
        fedilink
        English
        arrow-up
        2
        ·
        3 hours ago

        I’m not actually working in the field, so I can’t give you any advice there.

        I studied a related topic, before pivoting into a different career. And I do hardware and drivers stuff in my free time sometimes for some fun projects.

  • FizzyOrange
    link
    fedilink
    arrow-up
    4
    ·
    7 hours ago

    For bare metal definitely get a microcontroller and do some fun electronics project.

    Easiest to get into is Arduino, but don’t stick with that because its only redeeming feature is that it’s easy to get into. The IDE sucks, the build system sucks, the APIs really suck, and the code quality is very low (probably because it’s easy to get into so you get a lot of inexperienced people doing stuff).

    After Arduino I would recommend either going to the Nordic nRF5x series - you can do some cool Bluetooth stuff, or even make you your own radio protocol since the radio peripheral is fully documented… Or ESP32 with Rust and Embassy is probably the most modern and slick way to do microcontrollers.

    It does require learning Rust but Rust is really really good so you should do that anyway.

    There are some extremely good videos on YouTube about that: https://youtube.com/@therustybits

    I would probably still start with Arduino though since you know C. Just don’t stay there for too long.

    • wwaaaaa@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      7 hours ago

      Oh that sounds interesting, also thanks for suggesting the nRF5x series, it sounds quite interesting to experiment with bluetooth. And actually I was planning on also learning Rust as I’ve seen it is quite modern in the memory management and safety.

  • avguser@lemmy.world
    link
    fedilink
    arrow-up
    4
    ·
    7 hours ago

    Tangentially related to your question, Ed from Low Level has really good reverse engineering content that might pique your interest as well as a series of developer courses.

  • litchralee@sh.itjust.works
    link
    fedilink
    English
    arrow-up
    2
    ·
    7 hours ago

    This answer is going to go in multiple directions.

    If you’re looking for practice on using C to implement ways to talk to devices and peripherals, the other commenter’s suggested to start with an SBC (eg Raspberry Pi, Orange Pi) or with a microcontroller dev kit (eg Arduino, MSP430, STM32) is spot-on. That gives you a bunch of attached peripherals, the datasheet that documents the register behavior, and so you can then write your own C functions that fill in and read those registers. In actual projects, you would probably use the provided libraries that already do this, but there is educational value in trying it yourself.

    However, just because you write a C function named “put_char_uart0()”, that isn’t enough to prepare for writing full-fledged drivers, such as those in the Linux and FreeBSD kernel. This next step is more about software design, where you structure your C code so that rather than being very hardware-specific (eg for the exact UART peripheral in your microcontroller) you have code which works for a more generic UART (which abstracts general details) but is common-code to all the UARTs made by the same manufacturer. This is about creating reusable code, about creating abstraction layers, and about writing extensible code. Not all code can be reusable, not every abstraction layer is desirable, and you don’t necessarily want to make your code super extensive if it starts to impact your core requirements. Good driver design means you don’t ever paint yourself into a corner, and the best way to learn how to avoid this is through sheer experience.

    For when you do want to write a full-and-proper driver for any particular peripheral – maybe one day you’ll create one such device, such as by using an FPGA attached via PCIe to a desktop computer – then you’ll need to work within an existing driver framework. Linux and FreeBSD drivers use a framework so that all drivers have access to what they need (system memory, I/O, helper functions, threads, etc), and then it’s up to the driver author to implement the specific behavior (known in software engineering as “business logic”). It is a learned skill – also through experience – to work within the Linux or FreeBSD kernels. So much so that both kernels have gone through great lengths to enable userspace drivers, meaning the business logic runs as a normal program on the computer, saving the developer from having to learn the strange ways of kernel development.

    And it’s not like user space drivers are “cheating” in any way: they’re simply another framework to write a device driver, and it’s incumbent on the software engineer to learn when a kernel or user space driver is more appropriate for a given situation. I have seen kernel drivers used for sheer computational performance, but have also seen userspace drivers that were developed because nobody on that team was comfortable with kernel debugging. Those are entirely valid reasons, and software engineering is very much about selecting the right tool from a large toolbox.

    • wwaaaaa@lemmy.dbzer0.comOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      7 hours ago

      Thanks for the detailed reply, yeah I’m going with the microcontroller kit definitely, I kinda had it in mind before posting but wanted to make sure as I felt a bit lost given how extense (and interesting) the field is. I had no idea of the user space drivers, it is actually a really interesting concept and I’m definitely checking it out as it sounds like a good place to start contributing to the Linux kernel (which is something I wish to do + I daily drive Linux so most likely I will end up writing a solution for a problem I can personally have). Which software do you suggest for testing? The only one I’ve used for virtual ISO is VirtualBox.

      • litchralee@sh.itjust.works
        link
        fedilink
        English
        arrow-up
        4
        ·
        7 hours ago

        I personally started learning microcontrollers using an Arduino dev kit, and then progressed towards compiling the code myself using GCC and loading it directly to the Atmel 328p (the microcontroller from the original Arduino dev kits).

        But nowadays, I would recommend the MSP430 dev kit (which has excellent documentation for its peripherals) or the STM32 dev kit (because it uses the ARM32 architecture, which is very popular in the embedded hardware industry, so would look good on your resume).

        Regarding userspace drivers, because these are outside of the kernel, such drivers are not kept in the repositories for the kernel. You won’t find any userspace drivers in the Linux or FreeBSD repos. Instead, such drivers are kept in their own repos, maintained separately, and often does unusual things that the kernel folks don’t want to maintain, until there is enough interest. For example, if you’ve developed an unproven VPN tunnel similar to Wireguard, you might face resistance to getting that into the Linux kernel. But you could write a userspace driver that implements your VPN tunnel, and others can use that driver without changing their kernel. If it gets popular enough, other developers might put the effort into getting it reimplemented as a mainline kernel driver.

        For userspace driver development, a VM running the specific OS is fine. For kernel driver development, I prefer to run the OS within QEMU, since that allows me to attach a debugger to the VM’s “hardware”, letting me do things like adding breakpoints wirhin my kernel driver.

        • wwaaaaa@lemmy.dbzer0.comOP
          link
          fedilink
          English
          arrow-up
          2
          ·
          7 hours ago

          Oh wow, ok I’m checking both of those kits, also well the userspace being on another repo makes sense, so contributing to it would still be nice for me, not only to contribute to the community but also to learn. QEMU sounds really fitting for my interests so I’m going to experiment with it, thanks! I appreciate all the help