You might be thinking: 'Yet another blog explaining how to write a patch for the Linux kernel? Explaining how to send a plain-text email? Detailing how to build the kernel?' No, not really. This blog is more of a 'story' rather than a tutorial. The story of a four month journey through the Linux kernel. The story of how I answered all the questions I had during what I thought would be a simple process: from knowing nothing about the kernel contribution process to a successfully merged patch.
Before I started, I spent a lot of time digging through guides and blogs telling me how to get a patch merged and many of them looked like they would work fine. But a lot of them threw up more questions than answers. A a rule, I prefer to understand what it is that I'm doing; I like to keep things clean and tidy, I like to learn and not just follow blog instructions. For example: Clone this repository. OK, but why this one? There are plenty of Linux repositories. Use these compilation flags; fine, but what are they supposed to do? I had a lot of questions but then I started to answer the first one. Then the next one. And the one after. I decided to keep track of those answers in order to avoid searching again and also hoping that others might find my answers useful. And here we are! Part 1 of my blog 'story'.
What this blog does: hopefully, if everything works as intended, you should be able to go from cloning Linux's sources to sending a patch. This describes the whole process I used the first time I submitted a patch and the process I look forward to following each time I am a bit confused about the workflow. I will try to explain as much as possible the choices I made during this whole process.
What this blog won’t do: it won't help you to become a 'rockstar kernel developer'. I mean, I wrote this blog so if it magically changes peoples to 'rockstar kernel developers', I would know, wouldn't I?
Now I've explained the above, it's time to start!
Throughout this blog, I will assume that you have a Linux system available. Nothing fancy, a virtual machine or even a development board like a Raspberry Pi would work. However, bear in mind that the stronger your processor is, the faster you will be able to build the kernel ;)
As everything is clear now, we can first install the dependencies:
sudo apt-get install vim libncurses5-dev gcc make git exuberant-ctags libssl-dev bison flex libelf-dev bc mutt
This line will install all you need in order to follow this guide; not a single package is missing! These packages are the names available on Ubuntu, the name may change on different distributions, but you should be able to find them anyway.
Here is why we need all of these:
- Vim: a text-editor. Some would prefer Emacs or any other available IDE. Personally, I prefer to stick to Vim, especially because I configured it the way I need it, meaning I feel perfectly comfortable with it. Also, I do have a set of parameters and plug-ins that works perfectly well for kernel development.
- libncurses5-dev: mainly used for the make nconfig target of the Linux kernel. This will be useful to have Terminal User Interface (TUI) view of the kernel configuration options.
- gcc, make, bison, flex, libelf-dev, bc: for kernel compilation. There is no real reason to avoid installing these packages!
- Git: Linux kernel uses Git as the version control system, so it would be a good idea to download it, if you haven’t already ;)
- exuberant-ctags: ctags generates a file to store all the different tags found in a given source code: function names, variable names etc. With Linux and make tags, we will be able to navigate easily amongst the tens of thousands of source files with ease.
- Mutt: mail client, used to communicate with the maintainers and other contributors.
You may well be thinking: with all these packages, I should be ready to write some code! Hum. Not really. In fact, some configuration is required. The Linux kernel community follows a very strict set of rules about coding and communication; to be part of the community you should follow these rules too! They are defined in order to keep things ordered amongst the thousands of developers working on the kernel. Thus, if each contributor follows the same workflow, it should be easy for maintainers to spot potential errors, for example. So, we need to configure our tools!
This powerful text editor provides a lot of ways to be customised: from coding style to color schema, using plug-ins or not. A lot of things are possible. For us, the main purpose is to ensure Vim won't write code that does not comply to the kernel's guidelines or will not let us write code that does not comply to the guidelines.
The kernel coding style is a long document defining how contributors should write code for Linux. As a wise man might say: 'Better bad coding guidelines that no coding guidelines'.
To configure Vim, the following parameters should be written in the Vim configuration file ~/.vimrc. I added some comments in order to explain the purpose of each parameter:
filetype plugin indent on " Ask Vim to load file-specific parameters syntax on " Enable syntax highlighting, we're fancy people set title " Set shell title, kind of gadget, but useful set tabstop=8 " How many columns a tab count for? set softtabstop=8 " Ensure 8 spaces tabs set shiftwidth=8 " Set indentation operators (<< & >>) width set noexpandtab " Insert tabs, not spaces
Vim is now set up and ready to be used! This short configuration should be good enough for your first patch, but feel free to customise it the way you want.
Git also needs to be configured, first to define the commit's author and then to be able to create patches from those commits! The following configuration can be added locally for a given Git repository (by updating .git/gitconfig in this repository) or globally (by updating ~/.gitconfig):
[user] name = <your_name> email = <your_email>
Here, <your_name> should obviously be replaced by your real name, and <your_email> by... your real email. This information is used by Git to define the author of this commit; Git will add a 'signed-off-by' line to each of your patches with your name and your email address. This is mandatory for your patches to be accepted. By sending those patches, you are certifying that you have read and understood the Linux Developer's Certificate of Origin.
Now, set Git's send-email configuration. As previously stated, this can be done locally or globally:
[sendemail] tocover = 1 # In a patch series, copy first mail's # "To" content to the other ones cccover = 1 # Same, but for "Cc" from =
<name> <<email>> # Fill the "From" field of your email smtpuser = <email> # SMTP server user smtppass = <password> # SMTP server password smtpserver = <smtpserver> # SMTP server address smtpencryption = <smtpencryption> # SMTP server encryption type smtpserverport = <smtpport> # SMTP server port
The "from" parameter should once set, look like Juste Leblanc <email@example.com>.
Now you may be wondering: I don't use Outlook to share source files, why should I use Git to send emails?! This is a legit question. In fact, Git is much more adapted to send patches than any other tool. With Git you can easily create easy-to-send patches from the commit history, define a patch version, an email subject, send patch series etc. I tried different solutions to send my patches and Git is clearly the most straightforward.
Last tool: Mutt. There is a range of email clients which could be used for this task but it would be impossible for me to explain how to configure each one properly. Instead, I will focus on Mutt. Mutt is a text-based email client, highly configurable and very useful to keep in touch with the different maintainers and the other contributors of the Linux kernel. Where Git's send-email is used to send patches easily, Mutt will be used to answer conversations and discussions on the mailing list. Git could be used for both but Mutt provides a nice interface with a thread view which is very useful.
You could also use a different email client but you may have to configure it accordingly in order for your email to follow the Linux kernel etiquette:
- Patches are submitted via email, preferably as inline text. Never send an HTML email.
- Email clients should generate and maintain References: or In-Reply-To: headers so that mail threading is not broken.
- Email clients should not change patch formatting / spacing.
- Don't let your email client do automatic word wrapping for you.
- Email clients should not modify the character set encoding of the text. Emailed patches should be in ASCII or UTF-8 encoding only.
- Reply inline, no top-posting.
- Trim emails you're responding to, in order to keep the conversation clear for everyone.
If you can configure your preferred email client to follow these rules, feel free to use it! Personally, I will stick to Mutt as I know this configuration works fine. If you want to give Mutt a try, add the following parameters to ~/.muttrc:
# Mutt configuration # Credentials set my_user=<email>
# Variable, storing username set my_pass=<password> # Variable, storing user's password set my_name=<name> # Variable, storing user's real name # Connection set ssl_starttls=yes # Attempt to use STARTTLS if advertised set ssl_force_tls=yes # Require all connections to be encrypted set ssl_use_sslv3=yes # Ensure we use SSLv3! set timeout=60 # Lower input timeout set mail_check=60 # Check for new email each minute # Outgoing set realname="$my_name" # Use our real name set from="$my_user" # Set "From" parameter in emails set smtp_pass="$my_pass" # Your mail password (outgoing mails) set use_from=yes # Generate "From" header field set envelope_from=yes # Set the envelope sendar of the message # SMTP server parameters set smtp_authenticators="login" set smtp_url="smtp://$firstname.lastname@example.org:587" # Incoming set imap_user="$my_user" # IMAP server username set imap_pass="$my_pass" # IMAP server password # Default mailbox's location, this one is for Office 365 set folder="imaps://outlook.office365.com:993" set mbox="+INBOX" # Define mailbox folder set postponed="+Drafts" # Define drafts folder set spoolfile="+INBOX" # Define spool folder set record="+Sent Items" # Define sent folder set trash="+Deleted Items" # Define trash folder set imap_check_subscribed # Check all subscribed folders unset imap_passive # Use existing IMAP connection # Caches directories set header_cache="~/.cache/mutt/headers" set message_cachedir = "~/.cache/mutt/bodies" set certificate_file="~/.cache/mutt/certificates" # Useful customisations set smart_wrap=yes # Wrap lines on word boundaries set sort="threads" # Sort messages by threads set sort_aux="last-date-received" # Sort two-same threads by date set edit_headers=yes # Show mail's headers set editor = "vim" # Use Vim to edit emails set charset = "utf-8" # Set email's charset hdr_order Date From To CC # Mutt's headers order
To try Mutt configuration, you can try mutt -s "Test email" <to> < /dev/null, replacing <to> with your email.
There's nothing further to add for the time being, we've configured all our tools and are ready to start the real 'kernel development' part. But this is the subject for another blog! I will continue my ‘story’ in Parts 2 and 3 of my blog which will follow shortly. Part 2 will focus on cloning the kernel's sources to commit (useful) changes. But this is for another day!
Main image credit: Wikimedia Commons
Interested in other ITDev Linux blogs?
Here at ITDev, we often work on client projects that use the Linux operating system, see this search index to other Linux related blogs.
How ITDev Can Help
As a provider of software and electronics design services, we are often working with the Linux and Android operating systems. We have extensive experience in developing, modifying, building, debugging and bring up of these operating systems, be it for new developments or working with existing kernels to demonstrate new device technologies and features.
We offer advice and assistance to companies considering to use or already using Linux or Android on their embedded system. Initial discussions are always free of charge, so if you have any questions, or would like to find out more, email us or call us on +44 (0)23 8098 8890.
Embedded Linux workshop
We are investigating the possibility of running an 'online' workshop focused on the challenges around embedded Linux later this year. If you would be interested in attending a 'virtual' workshop, sign up to our Embedded Linux Interest Group to be kept informed.