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.
Version |
Location |
Description |
Submitted by |
Date submitted |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 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 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 |
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 |
59
PMD_SHIFT description |
In
PMD_SIZE (2PMD_SHIFT)
PMD_SHIFT represents power and should be in superscript.
|
Alexander Ruditsky |
Dec 27, 2011 |
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 |
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 |
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 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 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 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 |
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 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 |
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 |
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 |
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 |
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 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 |
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 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 |
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 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 |
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 |