Lesson 5: Details, details, details ... (BONUS LESSON)

Printer-friendly versionPrinter-friendly version

What's this all about, then?

It's about some free wisdom, that's what. Officially, this course's free content was supposed to end with lesson four but based on some comments, some e-mail and some review on my part, I think there are a few minor loose ends we can tie up. As for the subscribers, don't worry -- this will in no way affect what you get during the rest of the course.

One note about this bonus lesson, though: You must have covered the previous four lessons in their entirety, and everything there should have worked for you. There's no point reading this bonus material until you've thoroughly covered everything that came before. Seriously. I mean it. I'm not joking.

And on that note, onward.

So ... about that Makefile ...

From back in Lesson 4, a few people were curious about what was going on in that Makefile, so let's take another look at it. Here it is again, ready to turn the module source file crash1.c into the loadable module file crash1.ko:

ifeq ($(KERNELRELEASE),)

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

.PHONY: build clean

build:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
else

$(info Building with KERNELRELEASE = ${KERNELRELEASE})
obj-m :=    crash1.o

endif

At the time, I told you to just copy it, save it and run it, but let's discuss what's going on up there because it's actually fairly interesting.

Recall that compiling a kernel module requires a completely different build environment from your normal userspace programming, and this build environment is supplied by the kernel source tree against which you're doing the compilation.

The kernel source tree (or just the portion that you need for the build) contains all of the libraries, header files and Makefiles that support compiling a module source file for execution in kernel space. But all of that build infrastructure is within the kernel source tree. What good does that do you when your module source file is somewhere else? The Makefile above supplies the answer.

What's unusual about that Makefile is that it's meant to be run twice, and it will run differently based on which of the two phases is being executed.

When you run the make command locally in your directory, the first thing that happens in that Makefile is that the variable KERNELRELEASE is tested for being empty, at which point you should take my word for it that it will be empty, simply because nothing has set it yet. And based on that, the first part of the Makefile is processed.

What the first part of that Makefile does is identify where to find the current kernel's source tree (remember the purpose of that symlink /lib/modules/$(shell uname -r)/build
?), at which point -- and here's the magic -- your Makefile invokes the top-level Makefile of the kernel source tree, passing an argument that tells it where to come back to in order to build a module.

Let me say that again more succinctly: The kernel source tree contains the entire build infrastructure that knows how to compile kernel modules. All you're doing is invoking that Makefile with enough information to tell it where you would like it to visit to build your local module. Clever, no? But that's only the first part of the Makefile.

Once you make the call, the kernel Makefile will set a number of variables to help in the compilation process, including (you guessed it) KERNELRELEASE, which means that when your Makefile is invoked a second time, the second half of it is processed. That would be this part:

else

$(info Building with KERNELRELEASE = ${KERNELRELEASE})
obj-m :=    crash1.o

endif

And what you see above is all you need to set to tell the kernel Makefile what it is you want it to compile.

Is that sweet or what? If you didn't follow all that, don't worry; just keep using the Makefile as is and things will work.

Using a read-only kernel source tree

Although you might not have noticed yet, it should be obvious that when you're compiling your module source file against some kernel source tree, you don't need write access on that source tree -- read-only access will be sufficient since you are not changing anything in the kernel source. In short, multiple kernel programmers can all be compiling their modules against the same source tree with no fear of conflict.

insmod and rmmod and modprobe, oh my!

Recall from early in the course that when you wanted to load or unload a module that came with the OS, you used the modprobe command. That's because modprobe is the more sophisticated of the module management commands in that it understands dependencies and will generally do the right thing in terms of loading all of the appropriate modules.

When you build your own modules, however, you'll use the simpler and older insmod and rmmod commands, which don't understand dependencies and accept as arguments only .ko files. But for the time being, that's all you need.

And modinfo? What about modinfo?

Just as you used modinfo to query system-supplied modules that you loaded with modprobe, you can use it to tell you about your own compiled modules:

$ modinfo crash1.ko
filename:       crash1.ko
description:    Doing a whole lot of nothing.
license:        Dual BSD/GPL
author:         Robert P. J. Day, http://crashcourse.ca
srcversion:     313338BBCB9A6CACA4A049B
depends:        
vermagic:       2.6.32-22-generic SMP mod_unload modversions
$ 

So ... where do we go from here?

What you do is work carefully through all of the content up to here and, while you do that, I'll be putting together the rest of the course, the next lesson which should be up sometime this weekend, with each new lesson coming every few days.

Oh, and feel free to subscribe to the rest of the course. That's what this is all about, remember?

Happy hacking.

Comments

topics

Thanks for sharing your wisdom with free lessons. I like the format of your lessons. would you be covering advanced topics like workqueus, handlling interrupts,working with gpios,tasklets etc? I would like to subscribe if these topics are covered in detail.
Also, would you be posting the TOC for rest of the lessons?

What's the course going to cover?

It's unlikely that I'm going to cover all the topics you mention above for a couple reasons.

First, there simply isn't enough time in a course of this length to cover all of that. Keep in mind that this course is an introduction to Linux kernel programming, so my focus will be on establishing some solid fundamentals, not trying to cover every possible topic.

In addition, things like GPIO have little value in a general course in kernel programming -- they're more relevant to embedded Linux systems so covering things like GPIO (and SPI, and other topics) wouldn't be of much use to a lot of students who register for this course. I'm considering designing something that would cover the principles of embedded Linux that would include topics like that, but that won't happen right away.

As for a Table of Contents, the Overview and Syllabus page is the closest thing you'll get right now, and even that list isn't complete as I'm still pondering what extra topics I'm going to add, but you can be assured that this course will cover at least everything that's mentioned there.

So that's the best answer I have for you right now.

Que 1) You said that Makefile

Que 1)
You said that Makefile is invoked twice I am not clear how it is invoked twice.Are you talking about the Makefile in
/lib/modules/$(uname -r)/build/

to be invoked twice or some thing else.

Que 2)
You also mentioned that in the above Makefile a few variables

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

I am not clear with use of ? above

Que 3) use of := below is not clear as what does it do?

PWD := $(shell pwd)

Ques4) Why you used .PHONY and you mentioned build clean is it some thing like switch case?

.PHONY: build clean

Quest5) How do you decide which *.o and *.c to delete and why would you do that?

clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c

Ques6) I saw in some blogs on internet as
obj-m+=hello.o

where as you used

obj-m := crash1.o

When should we use += and what purpose does it serves.

"make check" for preliminary checking....

check:
modinfo $(MOD).ko
sudo insmod $(MOD).ko
mod=`lsmod | egrep $$'^$(MOD)[ \t]'` ; \
test -n "$$mod" ; \
echo "$$mod"
sudo rmmod $(MOD)
sudo grep -f ' $(MOD) module' /var/log/messages

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <br> <pre> <h1> <h2> <h3> <h4>
  • Lines and paragraphs break automatically.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.

We know

We're aware of the time and budget pressures at most companies, normally accompanied by the plaintive cry from management of, "Yes, I know we need training on that topic, but I just can't afford to send my entire team away for three (or four or five) days to get it!" And that's where we come in.

Choices!

The main focus at Crashcourse is to offer a choice of intense, 1-day, hands-on courses on specific topics in Linux and open source. And given that we already have the laptops for the delivery of that training, the idea is to show up early, set up a classroom, then spend the day teaching exactly the topic you're interested in. No travel time, and no wasted classroom time.

Customization

If we don't already have a course that addresses the topic you're interested in, drop us a note and we'll see what we can do -- our content providers can almost certainly put together a course that's precisely what you're after.

The difference

While there are a variety of sources for Linux and open source training, we at Crashcourse are taking a slightly different approach. Our philosophy is simple: exactly the training you want, and no wasted time or travel to get it.