Errata

Understanding the Linux Kernel

Errata for Understanding the Linux Kernel

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date Submitted
Printed Page 100
2nd paragraph, last sentence

nine macros --> eight macros

Rick Hutcheson  Apr 11, 2024 
Printed Page Page 104
2nd paragraph from bottom

Text reads "In the Intel's original design" instead of "In Intel's original design"

Cris S.  Mar 30, 2024 
PDF Page 570
In Section "Submitting a Request", 4th paragraph

"The bi_size field is set to the number of sectors covering the data."
But the bi_size field should be (as also pointed out in the table of fields) the number of bytes, not sectors.

Haotian  May 25, 2023 
PDF Page 44
2nd to last paragraph.

In 1st sentence, text after the colon:
"[the] BIOS code makes use of segments," should instead be
"[the] BIOS code makes use of these segments,"

That is, insert "these" in sentence.

Bert N.  Mar 01, 2023 
PDF Page 44
Last paragraph.

In 2nd sentence:
"[BIOS] code makes use of segments," should instead be
"[BIOS] code makes use of these segments,"

Bert N.  Mar 01, 2023 
PDF Page 41
Figure 2-5

The rounded box labeled "gdt or ldt" has two incoming arrows on the left. The lower arrow should be deleted.

Bert N.  Feb 24, 2023 
PDF Page Page 94
Figure 3-5.

The first box linked to index 199 of the hash table reads "PID 199". In the text on the preceding page (Page 93), it is stated that "[...] The processes having PIDs 2,890 and 29,384 hash into the 200th element of the table, [...]"

So the aforementioned box on Page 94 should read "PID 2890" instead.

Bert N.  Feb 22, 2023 
PDF Page Page 93
2nd paragraph below the box titled "The Magic Constant."

The final sentence in the paragraph states "[...] while the process having PID 29,385 hashes into the 1,466th element of the table."

Looking at Figure 3-5, the process whose PID is 29,385 hashes into index 1466 in the hash table. That is actually the 1467th element. And that would make the sentence in question consistent with the description of PIDs 2,890 and 29,384 hashing into the 200th element whose index in Figure 3-5 is 199.

Bert N.  Feb 22, 2023 
ePub Page B.2.3 Module Dependency
2nd paragraph

Text:

"The modules_which_use_me field of the module object of A is the head of a dependency list containing all modules that are used by A"

"all modules that are used by A" should be "all modules that use A".

Marja Hölttä  Dec 30, 2022 
Printed Page 93
the 3rd paragraph counting backwards

"while the process having PID 29385 hashes into the 1,466th element"
should be
"... the 1,467th element"

unifreak  Sep 17, 2022 
Other Digital Version 6.6.1 The time() and gettimeofday() System Calls
do_gettimeofday() steps 3 and 5

Step 3: "If some timer interrupt has been lost (...), the function adds to usec the corresponding delay."

-> Why is this necessary? Step 2 says "Determines the number of microseconds elapsed since the last timer interrupt" and e.g., "compares the current value of the HPET counter with the value of the same counter saved in the last execution of the timer interrupt handler". If the timer interrupt was lost, the timer interrupt handler was not executed, so the time should already be inclued in the count?

Step 5: "Copies the contents of xtime into the user-space buffer specified by the system call parameter tv, adding to the microsends field the value of usec:
tv->tv_sec = xtime->tv_sec;
tv->tv_usec = xtime->tv_usec + usec;"

1) xtime is not a pointer; also step 4 uses xtime.tv_nsec, not xtime->tv_nsec.
2) xtime is of type timespec, and it has fields tv_sec and tv_nsec, there's no tv_usec in it.

-> Is this step supposed to use some 'timeval' (not 'timespec') variable instead of xtime?

Or is it supposed to be:
tv->tv_sec = xtime.tv_sec;
tv->tv_usec = usec;

(We've already added xtime.tv_nsec / 1000 to usec in step 4.)

Marja Hölttä  Sep 01, 2022 
Other Digital Version 6.2.1.2 The jiffies variable
Source code of get_jiffies_64()

The source code has these lines:
seq = read_seqbegin(&xtime_lock);
and
} while (read_seqretry(&xime_lock, seq));

-> The latter should also be xtime_lock, not xime_lock.

Marja Hölttä  Aug 25, 2022 
Other Digital Version 5.2.10 Completions
Second to last paragraph of the section

The text says: "Then, the function checks the value of the done flag: if it's equal to zero the function terminates, otherwise, the current process is suspended again."

Isn't this the wrong way around; done > 0 means complete() has been called, so wait_for_completion() can return?

Previously in the same paragraph: "[...] and checks the value of the done flag. If it's greater than zero, wait_for_completion() terminates, becaues complete() has already been executed on another CPU."

Marja Hölttä  Aug 22, 2022 
Other Digital Version 5.2.4.1 The spin_lock macro with kernel preemption
Steps 6 and 7

The described algorithm sets break_lock to 1, but it never sets it back to 0. Shouldn't it be set back to 0 between steps 6 and 7 (after the wait cycle)?

Marja Hölttä  Aug 20, 2022 
Printed Page 596
Section a.

"Checks whether the inode->i_bdev field of the inode object is not NULL; if it is, the block device file has been opened already,".

The common interpretation of this sentence has the opposite meaning of what is true, and is at best ambiguous. It's unclear whether the "if it is" is referring to the object being NULL or not NULL.

A different example:
"Sam will check to see if it is not dark outside; if it is, it must be daytime".

This is either obviously incorrect, or ambiguous/confusing at best.

Corrected, it should read:
"Checks whether the inode->i_bdev field of the object is not NULL, in which case the block device file has been opened already,".

Matviy Kotoniy  Aug 10, 2022 
PDF Page 72
the code

Should the 13th line of the code "set_pmd(pmd, __pmd(phys_addr | pgprot_val(__pgprot(0x1e3))));" be revised to "set_pmd(pmd + j, __pmd(phys_addr | pgprot_val(__pgprot(0x1e3))));"? Because the pmd never be changed, so the loop will set the same entry.

Ingsuifon  Jun 26, 2022 
Printed Page 106
3rd paragraph

On the 3rd paragraph it says "-that is, the prev local variable allocated on the Kernel Mode stack of A". Should it be "the prev local variable allocated on the Kernel Mode stack of C" instead?


Jiapeng Liu  Nov 09, 2020 
PDF Page 147
1st paragraph

In the description of set_task_gate. the DPL of it should be 0 other than 3.
"The Offset field is set to 0, while the DPL field is set to 3." should be changed to "The Offset field is set to 0, while the DPL field is set to 0."

Canjiang Lu  Dec 02, 2019 
PDF Page 37
First paragraph of the section 'Segment Selectors and Segmentation Registers'

"...The segment identifier is a 16-bit field called the Segment Selector (see Figure 2-2), while the offset is a 32-bit field..."

offset is a 16-bit field as well

Felipe Pedrosa  Apr 22, 2019 
Printed Page 215
5th paragraph or 2nd under "Local Interrupt Disabling"

"The irqs_disabled() macro yields the value one if the IF flag of the eflags register is clear, the value one if the flag is set."

Should one of the values be zero ans if so which one?

Kenneth Benson  Sep 22, 2018 
PDF Page 122
step 25

In step 25 tsk->current->tgid should be changed to current->tgid in following sentence:
"a. Initializes tsk->tgid to tsk->current->tgid."

Canjiang Lu  Oct 17, 2017 
PDF Page 60
1st paragraph, under the description of PUD_SHIFT

Page Global Directory should be changed to Page Upper Directory in the following sentence:
The PUD_SIZE macro computes the size of the area mapped by a single
entry of the Page Global Directory.

Upper Air fields should also be removed from the following sentence:
The PUD_MASK macro is used to mask all the bits of the Offset, Table, Middle Air, and Upper Air fields.

The send error is already found by an anonymous guy on Jun 27, 2015 and listed in the unconfirmed errata.

Canjiang Lu  Oct 12, 2017 
PDF, Other Digital Version Page 541-542
9rd (13.4.4. Accessing the I/O Shared Memory)

The following is the origin text:

The correct form for the second statement might therefore look like:
io_mem = ioremap(0xfb000000, 0x200000);
t2 = *((unsigned char *)(io_mem + 0x100000));
The first statement creates a new 2 MB linear address interval, which maps physical addresses starting from 0xfb000000; the second one reads the memory location that has the 0xfc000000 address. To remove the mapping later, the device driver must use the iounmap( ) function.

The following is my trouble:

I think the right text is:
The correct form for the second statement might therefore look like:
io_mem = ioremap(0xfb000000, 0x2000000);
t2 = *((unsigned char *)(io_mem + 0x1000000));
The first statement creates a new 32 MB linear address interval, which maps physical addresses starting from 0xfb000000; the second one reads the memory location that has the 0xfc000000 address. To remove the mapping later, the device driver must use the iounmap( ) function.

the following is my reason:
if the second parameter of ioremap function is 0x200000,the physical address can't get to 0xfc000000 as (0xfb000000+0x200000-1)< 0xfc000000(the 0xfb000000+0x200000-1 is the last physical address). so I think you lost a zero in 0x200000,but if it is 0x2000000,the region will be too large to be wasteful, so it can be set to a number which is more than 8MB but less than 16MB . As the same ,t2 should be *((unsigned char *)(io_mem + 0x1000000));

kelyvon  Jun 07, 2017 
PDF Page 820
4th paragraph

The following snippets

sprintf(cmd, "cat /proc/self/maps");
system(cmd);

wil print memory regions of the process "cat", instead that of current process.

Richard Y.  Jul 22, 2016 
PDF Page 25
6th paragraph, second sentence ("The up() method ... ")

The book says the following:
"The up( ) method increases the value of the semaphore
and, if its new value is greater than or equal to 0, reactivates one or more processes in
the semaphore list."

However, it should read:
"The up( ) method increases the value of the semaphore
and, if its new value is less than or equal to 0, reactivates one process in
the semaphore list."

Anonymous  Jun 07, 2016 
Printed Page 275
point 7

"In multiprocessor systems resched_task() also checks whether the old value of whether TIF_NEED_RESCHED falg was zero, [...]"
The second whether in this sentence is probably a mistake.

Anonymous  Aug 04, 2015 
Printed Page 237
section 2b

" ... , but the kernel uses the APIC Power Management Timer ... "
should be
" ... , but the kernel uses the ACPI Power Management Timer ... "

According to earlier sections of the same chapter the PMT is part of the ACPI not the APIC.

Anonymous  Jul 30, 2015 
Printed Page 92
last line

'each hash table is strored in four pages frames and include 2,048 entrys'.

is 4 page frames right?
should it be 2 pages frames?
2048 (#hlist_entrys) * 4 (sizeof(hlist_head) / 4096 (pagesize) = 2

mplus  Jul 10, 2015 
Printed Page 93
Fig. 3-5

Fig. 3-5 @page 94 use pid 199/29384/29385,
while the text @page 93, use pid 2890/29384/29385.

mismatch between 199 and 2890.

mplus  Jul 09, 2015 
Printed Page 89
1st paragraph

(hlist) `the pprev field of the first element and the next field of the last element are set to NULL.'

the pprev of first element is not NULL, it is &hlist_head.

mplus  Jul 09, 2015 
Printed Page 146
bottom of page

In the definition of set_trap_gate() a reference to the above set_system_intr_gate() function is made, which is a mistake as it should be referencing the set_system_gate() function instead.

Currently the definition of set_trap_gate() states that it inserts a _interrupt_ gate, while the name and source code suggest otherwise (it inserts a trap gate). Thus this function is analogous to set_system_gate(), not set_system_intr_gate().

Anonymous  Jul 08, 2015 
Printed Page 60
top of page

Currently in the book the definition of PUD_MASK and PGDIR_MASK are the same.
The sentence "The PUD_MASK macro is used to mask all the
bits of the Offset, Table, Middle Air, and Upper Air fields." should be changed to "The PUD_MASK macro is used to mask all the bits of the Offset, Table and Middle Air fields."

Anonymous  Jun 27, 2015 
Other Digital Version 59
PMD_SHIFT description

In

PMD_SIZE (2PMD_SHIFT)

PMD_SHIFT represents power and should be in superscript.


Alexander Ruditsky  Dec 27, 2011 
Other Digital Version 45
4th paragraph of "Regular paging"

In the following passage:

If a simple one-level Page Table was used, then it would require up to 220 entries

220 should be 2 to the power of 20, i.e. the last two digits should be in superscript.

Alexander Ruditsky  Dec 26, 2011 
Other Digital Version 914
Title

The ePub version of the third edition has chapter 20 as
"Program ExZecution"
instead of
"Program Execution" (from the PDF)

It appears twice: in the TOC and the title of chapter 20.

ePub doesn't track page numbers correctly, so please ignore the number written above.

salty-horse  Feb 21, 2009