1. Hello everyone, I am a programmer who has long been immersed in the world of Linux and relies on it for a living. Living in a second-tier city with a poor IT environment, as you may know, programmers here are already quite rare, and Linux programmers are even more of a rare breed! However, there is an old saying that rarity breeds value. Surprisingly, although there are fewer Linux positions here, the salaries are still quite competitive overall. So, I found time to summarize my journey of learning Linux (otherwise, I would have been working overtime to earn a living, haha).However, recently, I have been anxious about one thing. Although I have been living off Linux and have encountered many Linux technologies over the years (whether for work or self-study in my spare time), when I think about it, I realize that I don’t have many tangible works to show for it. I haven’t documented my learning experiences in writing in a timely manner, and I haven’t established any technical influence in my field. As a technical person, thinking about these things makes me feel quite lost. Therefore, after much contemplation, in order to better learn Linux and to connect with more like-minded individuals, I decided to document my learning process in writing. If these writings can bring some benefits to others, I would feel very honored. In fact, recording one’s learning and growth trajectory is a great learning method; these writings will become valuable assets in the future, so that when I look back, I won’t regret or feel remorse for being unproductive. Now, let me share some of my experiences and insights.2. I remember the first time I encountered the Linux system was during my junior year in a course on Advanced Linux Programming. Unknowingly, I have been with Linux for nearly eight years now. I vaguely recall the confusion and helplessness I felt when I first started using Linux. Having been accustomed to the “friendly” user interface of Windows, I often found myself struggling with the command line interface of Linux. Moreover, I remember trying many different Linux desktop distributions, such as Ubuntu 9.10 (time flies, now it’s 19.10), Debian, CentOS, SUSE, and so on. Some might ask why I was so fickle, as if I were not loyal! Haha, the reason is probably twofold: one is that the system kept crashing, so I had to reinstall it, and during the reinstallation, I wanted to try other versions to see if they were better, which was actually due to my lack of skills; the other reason was that I didn’t know how to install software, and for beginners, compiling and installing software on Linux was simply too painful. Back then, I often encountered situations where the system environment did not support certain applications, so I had to manually configure dependency libraries, install new environments, etc., but I didn’t know how (I believe this is also a barrier for many beginners entering Linux). Faced with the need to complete assignments or course designs, I could only keep trying different distributions and searching for solutions from predecessors. Sometimes, when I couldn’t find a solution, I had to give up! This was my painful self-enlightenment phase with Linux.Although this phase was quite painful, I persevered in learning Linux with that stubbornness.Thinking back, I still feel a bit comforted.3. Later, I started working and ended my previous non-professional learning and development mode.I began to engage in some real projects and truly started learning how to develop based on the Linux system.This was also a phase where my technical abilities grew rapidly.I remember that the first project I developed was a system for network data distribution, with the underlying framework based on ACE (at that time, ACE was the standard framework for network development on Linux). I was responsible for the design and implementation of the SNMP client.It was from that time that I began to understand how to write Linux network programs, how to use GDB to debug core files, and how to use various system calls in the Linux system.During that period, I bought the “Advanced Programming in the UNIX Environment,” which is considered the bible of UNIX, and began to study it. This book is very systematic and covers almost all aspects of UNIX-like system development. The author’s precise explanations of the technology are astonishing.In my work, most of the Linux system development issues could be found in it, making it a great mentor and friend for Linux developers.I believe that if you choose the field of Linux development, this book is a must-read, and it should be read repeatedly because many technical details cannot be understood in just one or two readings.Moreover, I found that this book has a magical quality: as my work experience increases, I gain new insights from it every time I study it.This indicates that my understanding of technology is continuously improving, and it also shows that this book is not just a simple explanation of technical knowledge; more importantly, it has thought and soul, which is the fundamental reason why Linux can thrive.That period of work experience made me understand what the Linux system is, what functions can be achieved based on it, and how to realize my ideas based on it.I feel that after that, I had entered the door.Later, as I delved deeper into my work, I gradually began to understand the underlying working principles of Linux, such as what processes and threads are, how they work, how processes and threads communicate with each other, how Linux manages memory, how the TCP/IP protocol stack in Linux is designed and implemented, and so on.Although these topics are very hardcore and learning them is quite painful.However, the less I understand, the more mysterious I find them, and the more I want to learn about them, and gradually, I began to enjoy this feeling.In fact, exploring the unknown and ultimately understanding it brings endless satisfaction, and that is a wonderful enjoyment.4. After that, due to a job change, I began to engage in embedded Linux development. Embedded Linux development requires a more comprehensive understanding of Linux technology, especially at a lower level, because you often need to solve how to design a system from scratch. For example, given a hardware platform, you need to build a complete system from scratch, including BootLoader, Linux kernel, root filesystem, and system tools. This requires not only knowing how to develop applications based on the Linux platform but also understanding fundamental knowledge such as compiler principles, Linux kernel porting, filesystem construction methods and principles, driver programming, Make build systems, shell scripting, and so on. During this phase, I gained a system-level understanding of how Linux systems are applied and developed in embedded systems, further enhancing my understanding and cognition of basic computer principles. So, how can one quickly get started with embedded Linux? My method is to read more, learn from industry community practices, and then apply the learned technologies to work in a timely manner to internalize my skills. There are many communities related to embedded Linux, such as the famous router firmware OpenWrt, the system build system buildroot, and the cross-toolchain publisher linaro, etc. We can choose the areas we are interested in and actively participate in them. There are many experts in the community, and we can have close contact with them and learn many advanced technologies, which will greatly benefit our future technical career paths. Finally, I want to share my views on learning the Linux kernel. Embedded Linux development will inevitably involve some aspects of the Linux kernel. However, often what we encounter are specific technical points, leading to a feeling of being lost in the forest without seeing the trees.This is when my personal experience is to step out of fixed technical points and try to understand the “forest” where this point is located, that is, to understand the entire subsystem, focusing on understanding the position and role of the subsystem in the overall system, the framework of the subsystem, the abstract model, and then how to design and develop functional modules based on the model provided by the subsystem.For example, if a certain chip is based on I2C communication, we need to understand the framework and programming model of the I2C subsystem before implementing the design and development of the specific chip driver. Moreover, the design philosophies of various subsystems in the Linux kernel are interconnected; as long as you thoroughly understand a few systems, most other subsystems are similar, allowing you to draw parallels.5. Today, Linux technology is ubiquitous in various fields. For example, servers in data centers are almost all built on Linux systems, a significant portion of IoT devices are based on embedded Linux systems, and many key components in the booming AI field are also built on Linux.It can be said that Linux is everywhere; it has become the foundational core technology of the entire computer world, and I believe that Linux technology will surely shine in the future.However, the learning path of Linux is quite steep, and it can be very painful at the beginning.So how can we avoid the dilemma of “starting means ending” in the learning path of Linux?Based on my personal experience, I would like to share some thoughts:
- Do not aim too high; learning requires a down-to-earth approach.The technology in the Linux world is complex and diverse, with many particularly attractive technologies. Some people, at the beginning, rush into learning the Linux kernel to pursue these cutting-edge technologies. For example, current popular container technology, before practicing container applications, they start learning the implementation principles of containers in the Linux kernel, diving headfirst into the vast sea of Linux kernel code. Such individuals usually end up “drowning” in the ocean of the Linux kernel due to a lack of basic technical understanding. Therefore, for those who are just starting with Linux, it is essential to learn the most basic technologies in a down-to-earth manner. My suggestion is to first get rid of the habit of operating the computer with a mouse and force yourself to get used to the command line operation mode of Linux. Start learning from the simplest commands, using command line operations to understand how the Linux system works and its operating principles. Here, I recommend “The Linux Command Line” by William Shotts; this book can be considered the bible for Linux beginners, as it provides detailed explanations of various command operations in the Linux system and serves as an encyclopedia of Linux commands. It can truly help you open the door to Linux.Another piece of advice is that when learning Linux commands, remember that you cannot just talk about it on paper; every command must be practiced on the machine. Only in this way can you intuitively and genuinely appreciate the efficiency and value of the commands.This is the first piece of advice.
- Progress step by step, advancing layer by layer.After gaining some experience in operating the Linux system, you can try to undertake some development projects based on the Linux system. However, the development capabilities of the Linux system are incredibly strong, and there are so many things that can be done that newcomers may feel at a loss. Here,I have three suggestions:The first is to be work-content-oriented, progressing from specific points to the broader picture.The second is to systematically learn Linux environment programming; I recommend reading “Advanced Programming in the UNIX Environment”.The third is to choose open-source projects based on Linux, analyze what Linux technologies they use and how they are applied, and then understand how a system is formed and what its framework looks like, etc.In fact, these three points are interrelated: first, the knowledge used in work is often fragmented, and the problems encountered mostly involve specific technical points, which do not form a system. By systematically studying classic books related to Linux environment development, you can accelerate the process of turning technical points into a technical system, ultimately systematizing your knowledge. Then, by analyzing and learning from excellent open-source projects, you can deepen your overall understanding of the Linux system and enrich your application methods for Linux technology. After several detailed analyses of open-source projects, you will gradually master the essence of Linux system development. Finally, regarding the use of Linux system APIs, it is inevitable that various Linux system APIs will be involved in the development process, including system calls and glibc functions. How can we correctly use these APIs for development? My suggestion is that when you receive a function API, the first thing to do is to consult the man manual. Why? Because the authors of the man manual are usually the developers or maintainers of the API, and it provides detailed descriptions of the API’s functionality, basic principles, parameter analysis, and return values. More importantly, it will explain the precautions, usage limitations, and existing bugs of the API in detail, which can help you avoid most pitfalls and allow you to write robust programs from the start.Therefore, sticking to using man is a good habit for mastering Linux and is the most effective shortcut for development and learning.
- Technology has no limits; learning must reach new heights.After gaining considerable experience in Linux system development, we may become dissatisfied with simply using Linux for application development. So how can we elevate ourselves further in the Linux field? Actually, I am currently at this stage and do not have much authority to speak. I can only share some of my experiences for your reference. I have two pieces of advice:The first is to identify pain points in your work based on your industry characteristics and then program solutions to those pain points. Or, to improve development efficiency, design and implement development tool libraries or even frameworks. For example, in the past, when I received a new project, I always had to design and develop various basic tool libraries from scratch, such as logging systems, thread management models, thread synchronization models, string processing models, etc., which greatly reduced development efficiency and wasted development resources. Later, I organized various basic components used in different projects, refactored them, and ultimately integrated them into a set of application development libraries.This approach has the benefits of (1) greatly improving development efficiency.(2) significantly enhancing system stability.Each use of the basic library represents a transformation, with fewer and fewer bugs, thus improving system stability.The second is to effectively learn the Linux kernel. I am also a novice in learning the Linux kernel. Although I have previously done some kernel porting and driver development work, I always felt that those were just application developments based on the Linux kernel, without truly learning the design essence of Linux from the perspective of the operating system. Therefore, I began my journey of learning the kernel. However, I do not recommend that kernel newcomers start by reading those hefty classic kernel books. It’s not that their content is bad; on the contrary, they are very well written, but they are not suitable for beginners.My understanding is that these classics have a problem: they explain certain technical points very well but lack explanations of the overall framework of the kernel and the relationships between various subsystems.This can easily lead one to get lost in specific details without gaining an overall understanding of the system, ultimately expending a lot of energy without truly understanding the kernel.My approach is to analyze a system without rushing to understand specific details; first, I outline the main processes of the system, identify the key points, and form an overall understanding of the system in my mind. Then, I delve into learning the specific implementation methods. With a general concept in mind, I won’t lose direction while learning.It’s like having a map in an unfamiliar place; no matter how you walk, it’s hard to get lost.Therefore, my method for learning the kernel is to first form a mental map of the kernel and then follow the map to tackle the difficult points, ultimately understanding the entire kernel.6. Having said so much, these are some thoughts I have formed along my journey.However, due to my personal technical limitations, there are certainly many misunderstandings, and I hope everyone can be forgiving.I welcome like-minded individuals to come and exchange ideas.Finally, I want to say that technology has no limits, and there is no such thing as a universal method.As technical people, we can only keep running and actively face changes to remain invincible.
