This question appears to be off-topic. The users who voted to close gave this specific reason:

"Requests for learning materials (tutorials, how-tos etc.) are off topic. The only exception is questions about where to find official documentation (e.g. POSIX specifications). See the Help Center and our Community Meta for more information." – derobert, Ramesh, jimmij, John WH Smith, jasonwryan

@Josh These books were written 5-6 years ago, are they still topical?
–
Alex BolotovFeb 27 '12 at 21:00

I can't answer that with any reasonable credibility :( Other responsibilities consumed my time, and I never got around to reading it. Hopefully wzzrd sees these comments and can comment.
–
Joshua EnfieldFeb 27 '12 at 21:40

Linux Device Drivers is another good resource. It would give you another way to get into the inner workings. From the preface:

This is, on the surface, a book about
writing device drivers for the Linux
system. That is a worthy goal, of
course; the flow of new hardware
products is not likely to slow down
anytime soon, and somebody is going to
have to make all those new gadgets
work with Linux. But this book is also
about how the Linux kernel works and
how to adapt its workings to your
needs or interests. Linux is an open
system; with this book, we hope, it is
more open and accessible to a larger
community of developers.

I always find goal oriented learning more productive than abstract learning for me. The LDD book gave me a chance to bite off a small enough chunk to make progress.
–
Larry SmithmierAug 23 '10 at 16:12

Start with Linux Kernel Primer by Claudia Salzberg et al. Good one to start with for beginners. Robert Love's book is definitely not the book that beginners should start with. Latter book is above intermediate level.

"Men do not understand books until they have a certain amount of life, or at any rate no man understands a deep book, until he has seen and lived at least part of its contents". –Ezra Pound

A journey of a thousand code-miles must begin with a single step. If you are in confusion about which of the following books to start with, don't worry, pick any one of your choice. Not all those who wander are lost. As all roads ultimately connect to highway, you will explore new things in your kernel journey as the pages progress without meeting any dead ends, and ultimately connect to the code-set. Read with alert mind and remember: Code is not Literature.

What is left is not a thing or an emotion or an image or a mental picture or a memory or even an idea. It is a function. A process of some sort.
An aspect of Life that could be described as a function of something "larger".
And therefore, it appears that it is not really "separate" from that something
else. Like the function of a knife - cutting something - is not, in fact, separate
from the knife itself. The function may or may not be in use at the moment,
but it is potentially NEVER separate.

Read not to contradict and confute; nor to believe and take for granted; nor to find talk and discourse; but to weigh and consider. Some books are to be tasted, others to be swallowed, and some few to be chewed and digested: that is, some books are to be read only in parts, others to be read, but not curiously, and some few to be read wholly, and with diligence and attention.

Reader should be well versed with operating system concepts; a fair understanding of long running processes and its differences with processes with short bursts of execution; fault tolerance while meeting soft and hard real time constraints. While reading, it's important to understand and n/ack the design choices made by the linux kernel source in the core subsystems.

Threads [and] signals [are] a platform-dependent trail of misery, despair, horror and madness (~Anthony Baxte). That being said you should be a self-evaluating C expert, before diving into the kernel. You should also have good experience with Linked Lists, Stacks, Queues, Red Blacks Trees, Hash Functions, et al.

The beauty and art of the Linux Kernel source lies in the deliberate code obfuscation used along. This is often necessitated as to convey the computational meaning involving two or more operations in a clean and elegant way. This is especially true when writing code for multi-core architecture.

"Music does not carry you along. You have to carry it along strictly by your ability to really just focus on that little small kernel of emotion or story". -- Debbie Harry

Your task is basically to establish a high speed communication interface between the hardware device and the software kernel. You should read the hardware reference datasheet/manual to understand the behavior of the device and it's control and data states and provided physical channels. Knowledge of Assembly for your particular architecture and a fair knowledge of VLSI Hardware Description Languages like VHDL or Verilog will help you in the long run.

static irqreturn_t phy_interrupt(int irq, void *phy_dat)
{
struct phy_device *phydev = phy_dat;
if (PHY_HALTED == phydev->state)
return IRQ_NONE; /* It can't be ours. */
/* The MDIO bus is not allowed to be written in interrupt
* context, so we need to disable the irq here. A work
* queue will write the PHY to disable and clear the
* interrupt, and then reenable the irq line.
*/
disable_irq_nosync(irq);
atomic_inc(&phydev->irq_disable);
queue_work(system_power_efficient_wq, &phydev->phy_queue);
return IRQ_HANDLED;
}

“Call it a clan, call it a network, call it a tribe, call it a family: Whatever you call it, whoever you are, you need one.” - Jane Howard

Understanding a packet walk-through in the kernel is a key to understanding kernel networking. Understanding it is a must if we want to understand Netfilter or IPSec internals, and more. The two most important structures of linux kernel network layer are: struct sk_buff and struct net_device

Unless in communicating with it one says exactly what one means, trouble is bound to result. ~Alan Turing, about computers

Brian W. Kernighan, in the paper Unix for Beginners (1979) said, "The most effective debugging tool is still careful thought, coupled with judiciously placed print statements". Knowing what to collect will help you to get the right data quickly for a fast diagnosis. The great computer scientist Edsger Dijkstra once said that testing can demonstrate the presence of bugs but not their absence. Good investigation practices should balance the need to solve problems quickly, the need to build your skills, and the effective use of subject matter experts.

There are times when you hit rock-bottom, nothing seems to work and you run out of all your options. Its then that the real debugging begins. A bug may provide the break you need to disengage from a fixation on the ineffective solution.

On a UNIX system, everything is a file; if something is not a file, it is a process, except for named pipes and sockets. In a file system, a file is represented by an inode, a kind of serial number containing information about the actual data that makes up the file. The Linux Virtual File System VFS caches information in memory from each file system as it is mounted and used. A lot of care must be taken to update the file system correctly as data within these caches is modified as files and directories are created, written to and deleted. The most important of these caches is the Buffer Cache, which is integrated into the way that the individual file systems access their underlying block storage devices.

Cryptography forms the basis of trust online. Hacking is exploiting security controls either in a technical, physical or a human-based element. Protecting the kernel from other running programs is a first step toward a secure and stable system, but this is obviously not enough: some degree of protection must exist between different user-land applications as well. Exploits can target local or remote services.

You might not think that programmers are artists, but programming is an extremely creative profession. It's logic-based creativity. Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter. As you already know, there is a difference between knowing the path and walking the path; it is of utmost importance to roll up your sleeves and get your hands dirty with kernel source code. Finally, with your thus gained kernel knowledge, wherever you go, you will shine.

Immature coders imitate; mature coders steal; bad coders deface what they take, and good coders make it into something better, or at least something different. The good coder welds his theft into a whole of feeling which is unique, utterly different from that from which it was torn.

Beginner's start with Linux 0.11 source (less than 20,000 lines of source code). After 20 years of development, compared with Linux 0.11, Linux has become very huge, complex, and difficult to learn. But the design concept and main structure have no fundamental changes. Learning Linux 0.11 still has important practical significance.

You should be subscribed and active on at-least one kernel mailing list. Start with kernel newbies.

You do not need to read the full source code. Once you are familiar with the kernel API's and its usage, directly start with the source code of the sub-system you are interested in. You can also start with writing your own plug-n-play modules to experiment with the kernel.

Device Driver writers would benefit by having their own dedicated hardware. Start with Raspberry Pi.