Fix some minor invalid URLs

modify validate_markdown_links.py a little

Signed-off-by: Dongliang Mu <dzm91@hust.edu.cn>
This commit is contained in:
Dongliang Mu
2024-05-06 21:30:41 +08:00
parent 360a334779
commit d610e85e95
22 changed files with 61 additions and 61 deletions

View File

@@ -36,7 +36,7 @@
[@woodpenker](http://github.com/woodpenker)
[@tjm-1990](http://github.com/tjm-1990)
@tjm-1990
[@up2wing](https://github.com/up2wing)
@@ -48,4 +48,4 @@
[@Albertchamberlain](https://github.com/Albertchamberlain)
[@nannxnann](https://github.com/nannxnann)
@nannxnann

View File

@@ -435,7 +435,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = {
* [control groups](https://en.wikipedia.org/wiki/Cgroups)
* [PID](https://en.wikipedia.org/wiki/Process_identifier)
* [cpuset](http://man7.org/linux/man-pages/man7/cpuset.7.html)
* [cpuset](https://man7.org/linux/man-pages/man7/cpuset.7.html)
* [block devices](https://en.wikipedia.org/wiki/Device_file)
* [huge pages](https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt)
* [sysfs](https://en.wikipedia.org/wiki/Sysfs)

View File

@@ -331,7 +331,7 @@ static struct notifier_block tracepoint_module_nb = {
};
```
When one of the `MODULE_STATE_LIVE`, `MODULE_STATE_COMING` or `MODULE_STATE_GOING` events occurred. For example the `MODULE_STATE_LIVE` the `MODULE_STATE_COMING` notifications will be sent during execution of the [init_module](http://man7.org/linux/man-pages/man2/init_module.2.html) [system call](/SysCall/linux-syscall-1.md). Or for example `MODULE_STATE_GOING` will be sent during execution of the [delete_module](http://man7.org/linux/man-pages/man2/delete_module.2.html) `system call`:
When one of the `MODULE_STATE_LIVE`, `MODULE_STATE_COMING` or `MODULE_STATE_GOING` events occurred. For example the `MODULE_STATE_LIVE` the `MODULE_STATE_COMING` notifications will be sent during execution of the [init_module](https://man7.org/linux/man-pages/man2/init_module.2.html) [system call](/SysCall/linux-syscall-1.md). Or for example `MODULE_STATE_GOING` will be sent during execution of the [delete_module](https://man7.org/linux/man-pages/man2/delete_module.2.html) `system call`:
```C
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
@@ -364,6 +364,6 @@ Links
* [semaphore](/SyncPrim/linux-sync-3.md)
* [tracepoints](https://www.kernel.org/doc/Documentation/trace/tracepoints.txt)
* [system call](/SysCall/linux-syscall-1.md)
* [init_module system call](http://man7.org/linux/man-pages/man2/init_module.2.html)
* [delete_module](http://man7.org/linux/man-pages/man2/delete_module.2.html)
* [init_module system call](https://man7.org/linux/man-pages/man2/init_module.2.html)
* [delete_module](https://man7.org/linux/man-pages/man2/delete_module.2.html)
* [previous part](/Concepts/linux-cpu-3.md)

View File

@@ -14,7 +14,7 @@ struct list_head {
};
```
你可能注意到这和你以前见过的双向链表的实现方法是不同的。举个例子来说,在 [glib](http://www.gnu.org/software/libc/) 库里是这样实现的:
你可能注意到这和你以前见过的双向链表的实现方法是不同的。举个例子来说,在 [glib](https://www.gnu.org/software/libc/) 库里是这样实现的:
```C
struct GList {

View File

@@ -340,7 +340,7 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
(__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
```
正如我们可以看到的,它检查 `nbits` 是否为编译期已知常量,并且其值不超过 `BITS_PER_LONG``64`。如果位数目没有超过一个 `long` 变量的位数,我们可以仅仅设置为 0。在其他情况我们需要计算有多少个需要填充位数组的 `long` 变量并且使用 [memset](http://man7.org/linux/man-pages/man3/memset.3.html) 进行填充。
正如我们可以看到的,它检查 `nbits` 是否为编译期已知常量,并且其值不超过 `BITS_PER_LONG``64`。如果位数目没有超过一个 `long` 变量的位数,我们可以仅仅设置为 0。在其他情况我们需要计算有多少个需要填充位数组的 `long` 变量并且使用 [memset](https://man7.org/linux/man-pages/man3/memset.3.html) 进行填充。
`bitmap_fill` 函数的实现和 `biramp_zero` 函数很相似,除了我们需要在给定的位数组中填写 `0xff``0b11111111`
@@ -356,7 +356,7 @@ static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
}
```
除了 `bitmap_fill``bitmap_zero`[include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件也提供了和 `bitmap_zero` 很相似的 `bitmap_copy`,只是仅仅使用 [memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html) 而不是 [memset](http://man7.org/linux/man-pages/man3/memset.3.html) 这点差异而已。它也提供了位数组的按位操作,像 `bitmap_and`, `bitmap_or`, `bitamp_xor`等等。我们不会探讨这些函数的实现了,因为如果你理解了本部分的所有内容,这些函数的实现是很容易理解的。无论如何,如果你对这些函数是如何实现的感兴趣,你可以打开并研究 [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件。
除了 `bitmap_fill``bitmap_zero`[include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件也提供了和 `bitmap_zero` 很相似的 `bitmap_copy`,只是仅仅使用 [memcpy](https://man7.org/linux/man-pages/man3/memcpy.3.html) 而不是 [memset](https://man7.org/linux/man-pages/man3/memset.3.html) 这点差异而已。它也提供了位数组的按位操作,像 `bitmap_and`, `bitmap_or`, `bitamp_xor`等等。我们不会探讨这些函数的实现了,因为如果你理解了本部分的所有内容,这些函数的实现是很容易理解的。无论如何,如果你对这些函数是如何实现的感兴趣,你可以打开并研究 [include/linux/bitmap.h](https://github.com/torvalds/linux/blob/master/include/linux/bitmap.h) 头文件。
本部分到此为止。
@@ -381,8 +381,8 @@ static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
* [bt instruction](http://x86.renejeschke.de/html/file_module_x86_id_22.html)
* [sbb instruction](http://x86.renejeschke.de/html/file_module_x86_id_286.html)
* [btc instruction](http://x86.renejeschke.de/html/file_module_x86_id_23.html)
* [man memcpy](http://man7.org/linux/man-pages/man3/memcpy.3.html)
* [man memset](http://man7.org/linux/man-pages/man3/memset.3.html)
* [man memcpy](https://man7.org/linux/man-pages/man3/memcpy.3.html)
* [man memset](https://man7.org/linux/man-pages/man3/memset.3.html)
* [CF](https://en.wikipedia.org/wiki/FLAGS_register)
* [inline assembler](https://en.wikipedia.org/wiki/Inline_assembler)
* [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection)

View File

@@ -97,7 +97,7 @@ void arch_task_cache_init(void)
}
```
The `arch_task_cache_init` does initialization of the architecture-specific caches. In our case it is `x86_64`, so as we can see, the `arch_task_cache_init` allocates cache for the `task_xstate` which represents [FPU](http://en.wikipedia.org/wiki/Floating-point_unit) state and sets up offsets and sizes of all extended states in [xsave](http://www.felixcloutier.com/x86/XSAVES.html) area with the call of the `setup_xstate_comp` function. After the `arch_task_cache_init` we calculate default maximum number of threads with the:
The `arch_task_cache_init` does initialization of the architecture-specific caches. In our case it is `x86_64`, so as we can see, the `arch_task_cache_init` allocates cache for the `task_xstate` which represents [FPU](http://en.wikipedia.org/wiki/Floating-point_unit) state and sets up offsets and sizes of all extended states in [xsave](https://www.felixcloutier.com/x86/XSAVES.html) area with the call of the `setup_xstate_comp` function. After the `arch_task_cache_init` we calculate default maximum number of threads with the:
```C
set_max_threads(MAX_THREADS);
@@ -338,7 +338,7 @@ More about it will be in the chapter about scheduler. So for this moment the `st
wait_for_completion(&kthreadd_done);
```
After this we set `gfp_allowed_mask` to `__GFP_BITS_MASK` which means that system is already running, set allowed [cpus/mems](https://www.kernel.org/doc/Documentation/cgroups/cpusets.txt) to all CPUs and [NUMA](http://en.wikipedia.org/wiki/Non-uniform_memory_access) nodes with the `set_mems_allowed` function, allow `init` process to run on any CPU with the `set_cpus_allowed_ptr`, set pid for the `cad` or `Ctrl-Alt-Delete`, do preparation for booting of the other CPUs with the call of the `smp_prepare_cpus`, call early [initcalls](http://kernelnewbies.org/Documents/InitcallMechanism) with the `do_pre_smp_initcalls`, initialize `SMP` with the `smp_init` and initialize [lockup_detector](https://www.kernel.org/doc/Documentation/lockup-watchdogs.txt) with the call of the `lockup_detector_init` and initialize scheduler with the `sched_init_smp`.
After this we set `gfp_allowed_mask` to `__GFP_BITS_MASK` which means that system is already running, set allowed [cpus/mems](https://www.kernel.org/doc/Documentation/cgroups/cpusets.txt) to all CPUs and [NUMA](http://en.wikipedia.org/wiki/Non-uniform_memory_access) nodes with the `set_mems_allowed` function, allow `init` process to run on any CPU with the `set_cpus_allowed_ptr`, set pid for the `cad` or `Ctrl-Alt-Delete`, do preparation for booting of the other CPUs with the call of the `smp_prepare_cpus`, call early [initcalls](https://kernelnewbies.org/Documents/InitcallMechanism) with the `do_pre_smp_initcalls`, initialize `SMP` with the `smp_init` and initialize [lockup_detector](https://www.kernel.org/doc/Documentation/lockup-watchdogs.txt) with the call of the `lockup_detector_init` and initialize scheduler with the `sched_init_smp`.
After this we can see the call of the following functions - `do_basic_setup`. Before we will call the `do_basic_setup` function, our kernel already initialized for this moment. As comment says:
@@ -450,7 +450,7 @@ Links
--------------------------------------------------------------------------------
* [SLAB](http://en.wikipedia.org/wiki/Slab_allocation)
* [xsave](http://www.felixcloutier.com/x86/XSAVES.html)
* [xsave](https://www.felixcloutier.com/x86/XSAVES.html)
* [FPU](http://en.wikipedia.org/wiki/Floating-point_unit)
* [Documentation/security/credentials.txt](https://github.com/torvalds/linux/blob/master/Documentation/security/credentials.rst)
* [Documentation/x86/x86_64/mm](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/x86/x86_64/mm.txt)

View File

@@ -34,7 +34,7 @@ module_exit(serial21285_exit);
void cleanup_module(void) __attribute__((alias(#exitfn)));
```
并被 [initcall](http://kernelnewbies.org/Documents/InitcallMechanism) 函数调用:
并被 [initcall](https://kernelnewbies.org/Documents/InitcallMechanism) 函数调用:
* `early_initcall`
* `pure_initcall`
@@ -456,7 +456,7 @@ native_irq_return_iret:
* [StrongARM** SA-110/21285 评估板](http://netwinder.osuosl.org/pub/netwinder/docs/intel/datashts/27813501.pdf)
* [IRQ](https://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29)
* [模块](https://en.wikipedia.org/wiki/Loadable_kernel_module)
* [initcall](http://kernelnewbies.org/Documents/InitcallMechanism)
* [initcall](https://kernelnewbies.org/Documents/InitcallMechanism)
* [uart](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter)
* [ISA](https://en.wikipedia.org/wiki/Industry_Standard_Architecture)
* [内存管理](/MM/)

View File

@@ -214,7 +214,7 @@ But unfortunately this method does not give a 100% guarantee. As described in th
> stack but before we executed SWAPGS, then the only safe way to check
> for GS is the slower method: the RDMSR.
In other words for example `NMI` could happen inside the critical section of a [swapgs](http://www.felixcloutier.com/x86/SWAPGS.html) instruction. In this way we should check value of the `MSR_GS_BASE` [model specific register](https://en.wikipedia.org/wiki/Model-specific_register) which stores pointer to the start of per-cpu area. So to check if we did come from userspace or not, we should to check value of the `MSR_GS_BASE` model specific register and if it is negative we came from kernel space, in other way we came from userspace:
In other words for example `NMI` could happen inside the critical section of a [swapgs](https://www.felixcloutier.com/x86/SWAPGS.html) instruction. In this way we should check value of the `MSR_GS_BASE` [model specific register](https://en.wikipedia.org/wiki/Model-specific_register) which stores pointer to the start of per-cpu area. So to check if we did come from userspace or not, we should to check value of the `MSR_GS_BASE` model specific register and if it is negative we came from kernel space, in other way we came from userspace:
```assembly
movl $MSR_GS_BASE,%ecx
@@ -351,7 +351,7 @@ testb $3, CS+8(%rsp)
jz .Lerror_kernelspace
```
because we may have potentially fault if as described in documentation truncated `%RIP` was reported. Anyway, in both cases the [SWAPGS](http://www.felixcloutier.com/x86/SWAPGS.html) instruction will be executed and values from `MSR_KERNEL_GS_BASE` and `MSR_GS_BASE` will be swapped. From this moment the `%gs` register will point to the base address of kernel structures. So, the `SWAPGS` instruction is called and it was main point of the `error_entry` routing.
because we may have potentially fault if as described in documentation truncated `%RIP` was reported. Anyway, in both cases the [SWAPGS](https://www.felixcloutier.com/x86/SWAPGS.html) instruction will be executed and values from `MSR_KERNEL_GS_BASE` and `MSR_GS_BASE` will be swapped. From this moment the `%gs` register will point to the base address of kernel structures. So, the `SWAPGS` instruction is called and it was main point of the `error_entry` routing.
Now we can back to the `idtentry` macro. We may see following assembler code after the call of `error_entry`:
@@ -515,7 +515,7 @@ Links
* [CFI directives](https://sourceware.org/binutils/docs/as/CFI-directives.html)
* [IRQ](http://en.wikipedia.org/wiki/Interrupt_request_%28PC_architecture%29)
* [system call](http://en.wikipedia.org/wiki/System_call)
* [swapgs](http://www.felixcloutier.com/x86/SWAPGS.html)
* [swapgs](https://www.felixcloutier.com/x86/SWAPGS.html)
* [SIGTRAP](https://en.wikipedia.org/wiki/Unix_signal#SIGTRAP)
* [Per-CPU variables](https://0xax.gitbook.io/linux-insides/summary/concepts/linux-cpu-1)
* [kgdb](https://en.wikipedia.org/wiki/KGDB)

View File

@@ -150,7 +150,7 @@ if (kmemcheck_active(regs))
prefetchw(&mm->mmap_sem);
```
After this we can see the call of the `prefetchw` which executes instruction with the same [name](http://www.felixcloutier.com/x86/PREFETCHW.html) which fetches [X86_FEATURE_3DNOW](https://en.wikipedia.org/?title=3DNow!) to get exclusive [cache line](https://en.wikipedia.org/wiki/CPU_cache). The main purpose of prefetching is to hide the latency of a memory access. In the next step we check that we got page fault not in the kernel space with the following condition:
After this we can see the call of the `prefetchw` which executes instruction with the same [name](https://www.felixcloutier.com/x86/PREFETCHW.html) which fetches [X86_FEATURE_3DNOW](https://en.wikipedia.org/?title=3DNow!) to get exclusive [cache line](https://en.wikipedia.org/wiki/CPU_cache). The main purpose of prefetching is to hide the latency of a memory access. In the next step we check that we got page fault not in the kernel space with the following condition:
```C
if (unlikely(fault_in_kernel_space(address))) {
@@ -444,7 +444,7 @@ Links
* [RCU](https://en.wikipedia.org/wiki/Read-copy-update)
* [this_cpu_* operations](https://github.com/torvalds/linux/blob/16f73eb02d7e1765ccab3d2018e0bd98eb93d973/Documentation/this_cpu_ops.txt)
* [kmemcheck](https://www.kernel.org/doc/Documentation/kmemcheck.txt)
* [prefetchw](http://www.felixcloutier.com/x86/PREFETCHW.html)
* [prefetchw](https://www.felixcloutier.com/x86/PREFETCHW.html)
* [3DNow](https://en.wikipedia.org/?title=3DNow!)
* [CPU caches](https://en.wikipedia.org/wiki/CPU_cache)
* [VFS](https://en.wikipedia.org/wiki/Virtual_file_system)

View File

@@ -16,7 +16,7 @@ Linux 启动
------------------------
* [8250 UART Programming](http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming#UART_Registers)
* [Serial ports on OSDEV](http://wiki.osdev.org/Serial_Ports)
* [Serial ports on OSDEV](https://wiki.osdev.org/Serial_Ports)
VGA
------------------------

View File

@@ -485,5 +485,5 @@ Happy Hacking!
* [Linux kernel mail listing archive](https://lkml.org/)
* [Linux kernel coding style guide](https://github.com/torvalds/linux/blob/master/Documentation/CodingStyle)
* [How to Get Your Change Into the Linux Kernel](https://github.com/torvalds/linux/blob/master/Documentation/SubmittingPatches)
* [Linux Kernel Newbies](http://kernelnewbies.org/)
* [Linux Kernel Newbies](https://kernelnewbies.org/)
* [plain text](https://en.wikipedia.org/wiki/Plain_text)

View File

@@ -676,7 +676,7 @@ Kernel: arch/x86/boot/bzImage is ready (#5)
* [uname](https://en.wikipedia.org/wiki/Uname)
* [shell](https://en.wikipedia.org/wiki/Shell_%28computing%29)
* [Kbuild](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kbuild.txt)
* [binutils](http://www.gnu.org/software/binutils/)
* [binutils](https://www.gnu.org/software/binutils/)
* [gcc](https://gcc.gnu.org/)
* [Documentation](https://github.com/torvalds/linux/blob/master/Documentation/kbuild/makefiles.txt)
* [System.map](https://en.wikipedia.org/wiki/System.map)

View File

@@ -119,7 +119,7 @@ $ ./sum
x + y + z = 6
```
好的,直到现在所有事情看起来听挺好。你可能已经知道一个特殊的[系统调用](https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8)家族 - [exec*](http://man7.org/linux/man-pages/man3/execl.3.html) 系统调用。正如我们从帮助手册中读到的:
好的,直到现在所有事情看起来听挺好。你可能已经知道一个特殊的[系统调用](https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8)家族 - [exec*](https://man7.org/linux/man-pages/man3/execl.3.html) 系统调用。正如我们从帮助手册中读到的:
> The exec() family of functions replaces the current process image with a new process image.
@@ -368,7 +368,7 @@ $ readelf -e test | grep fini
[15] .fini PROGBITS 0000000000400504 00000504
```
这两个将被替换为二进制镜像的开始和结尾,包含分别被称为构造函数和析构函数的例程。这些例程的要点是在程序的真正代码执行之前,做一些初始化/终结,像全局变量如 [errno](http://man7.org/linux/man-pages/man3/errno.3.html) ,为系统例程分配和释放内存等等。
这两个将被替换为二进制镜像的开始和结尾,包含分别被称为构造函数和析构函数的例程。这些例程的要点是在程序的真正代码执行之前,做一些初始化/终结,像全局变量如 [errno](https://man7.org/linux/man-pages/man3/errno.3.html) ,为系统例程分配和释放内存等等。
你可能可以从这些函数的名字推测,这两个会在 `main` 函数之前和之后被调用。`.init``.fini` 段的定义在 `/lib64/crti.o` 中。如果我们添加这个目标文件:

View File

@@ -41,4 +41,4 @@
## 许可证
本项目使用 [BY-NC-SA Creative Commons](http://creativecommons.org/licenses/by-nc-sa/4.0/) 许可证。
本项目使用 [BY-NC-SA Creative Commons](https://creativecommons.org/licenses/by-nc-sa/4.0/) 许可证。

View File

@@ -17,7 +17,7 @@ def check_live_url(url):
result = False
try:
ret = urlopen(url, timeout=2)
ret = urlopen(url, timeout=5)
result = (ret.code == 200)
except HTTPError as e:
print(e, file=sys.stderr)
@@ -55,9 +55,9 @@ def main(path):
print("markdown file name: " + url)
continue
if check_live_url(url):
print(url)
print(url, ": Success")
else:
print(url, file=sys.stderr)
print(url, ": Failure")
if __name__ == '__main__':
@@ -65,4 +65,4 @@ if __name__ == '__main__':
if len(sys.argv) == 2:
main(sys.argv[1])
else:
print("Choose one path as argument one")
print("Choose one path as the argument")

View File

@@ -443,7 +443,7 @@ if (next)
prefetchw(next);
```
如果新节点被添加,我们从通过使用 [PREFETCHW](http://www.felixcloutier.com/x86/PREFETCHW.html) 指令指出下一个队列实体的内存中预先去除缓存线cache line。以优化为目的我们现在预先载入这个指针。我们只是改变了队列的头而这意味着有将要到来的 `MCS` 进行解锁操作并且下一个实体会被创建。
如果新节点被添加,我们从通过使用 [PREFETCHW](https://www.felixcloutier.com/x86/PREFETCHW.html) 指令指出下一个队列实体的内存中预先去除缓存线cache line。以优化为目的我们现在预先载入这个指针。我们只是改变了队列的头而这意味着有将要到来的 `MCS` 进行解锁操作并且下一个实体会被创建。
是的,从这个时刻我们在`队列`的头部。但是在我们有能力获取锁之前,我们需要至少等待两个事件:当前锁的拥有者释放锁和第二个线程处于`待定`位也获取锁:
@@ -478,6 +478,6 @@ smp_cond_acquire(!((val = atomic_read(&lock->val)) & _Q_LOCKED_PENDING_MASK));
* [CMPXCHG instruction](http://x86.renejeschke.de/html/file_module_x86_id_41.html)
* [LOCK instruction](http://x86.renejeschke.de/html/file_module_x86_id_159.html)
* [NOP instruction](https://en.wikipedia.org/wiki/NOP)
* [PREFETCHW instruction](http://www.felixcloutier.com/x86/PREFETCHW.html)
* [PREFETCHW instruction](https://www.felixcloutier.com/x86/PREFETCHW.html)
* [x86_64](https://en.wikipedia.org/wiki/X86-64)
* [Previous part](/SyncPrim/linux-sync-1.md)

View File

@@ -5,7 +5,7 @@ Linux 内核如何处理系统调用
--------------------------------------------------------------------------------
前一[小节](/SysCall/linux-syscall-1.md) 作为本章节的第一部分描述了 Linux 内核[system call](https://en.wikipedia.org/wiki/System_call) 概念。
前一节中提到通常系统调用处于内核处于操作系统层面。 前一节内容从用户空间的角度介绍,并且 [write](http://man7.org/linux/man-pages/man2/write.2.html)系统调用实现的一部分内容没有讨论。 在这一小节继续关注系统调用,在深入 Linux 内核之前,从一些理论开始。
前一节中提到通常系统调用处于内核处于操作系统层面。 前一节内容从用户空间的角度介绍,并且 [write](https://man7.org/linux/man-pages/man2/write.2.html)系统调用实现的一部分内容没有讨论。 在这一小节继续关注系统调用,在深入 Linux 内核之前,从一些理论开始。
程序中一个用户程序并不直接使用系统调用。 我们并未这样写 `Hello World`程序代码:
@@ -63,7 +63,7 @@ asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
typedef void (*sys_call_ptr_t)(void);
```
其次为 `sys_call_table` 数组中元素的初始化。 从上面的代码中可知,数组中所有元素包含指向 `sys_ni_syscall` 的系统调用处理器的指针。 `sys_ni_syscall` 函数为 “not-implemented” 系统调用。 首先,`sys_call_table` 的所有元素指向 “not-implemented” 系统调用。 这是正确的初始化方法,因为我们仅仅初始化指向系统调用处理器的指针的存储位置,稍后再做处理。 `sys_ni_syscall` 的结果比较简单,仅仅返回 [-errno](http://man7.org/linux/man-pages/man3/errno.3.html) 或者 `-ENOSYS` :
其次为 `sys_call_table` 数组中元素的初始化。 从上面的代码中可知,数组中所有元素包含指向 `sys_ni_syscall` 的系统调用处理器的指针。 `sys_ni_syscall` 函数为 “not-implemented” 系统调用。 首先,`sys_call_table` 的所有元素指向 “not-implemented” 系统调用。 这是正确的初始化方法,因为我们仅仅初始化指向系统调用处理器的指针的存储位置,稍后再做处理。 `sys_ni_syscall` 的结果比较简单,仅仅返回 [-errno](https://man7.org/linux/man-pages/man3/errno.3.html) 或者 `-ENOSYS` :
```C
asmlinkage long sys_ni_syscall(void)
@@ -383,13 +383,13 @@ Links
--------------------------------------------------------------------------------
* [system call](https://en.wikipedia.org/wiki/System_call)
* [write](http://man7.org/linux/man-pages/man2/write.2.html)
* [write](https://man7.org/linux/man-pages/man2/write.2.html)
* [C standard library](https://en.wikipedia.org/wiki/GNU_C_Library)
* [list of cpu architectures](https://en.wikipedia.org/wiki/List_of_CPU_architectures)
* [x86_64](https://en.wikipedia.org/wiki/X86-64)
* [kbuild](https://www.kernel.org/doc/Documentation/kbuild/makefiles.txt)
* [typedef](https://en.wikipedia.org/wiki/Typedef)
* [errno](http://man7.org/linux/man-pages/man3/errno.3.html)
* [errno](https://man7.org/linux/man-pages/man3/errno.3.html)
* [gcc](https://en.wikipedia.org/wiki/GNU_Compiler_Collection)
* [model specific register](https://en.wikipedia.org/wiki/Model-specific_register)
* [intel 2b manual](http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html)

View File

@@ -334,7 +334,7 @@ if (!elf_phdata)
goto out;
```
that describes [segments](https://en.wikipedia.org/wiki/Memory_segmentation). Read the `program interpreter` and libraries that linked with the our executable binary file from disk and load it to memory. The `program interpreter` specified in the `.interp` section of the executable file and as you can read in the part that describes [Linkers](https://0xax.gitbook.io/linux-insides/summary/misc/linux-misc-3) it is - `/lib64/ld-linux-x86-64.so.2` for the `x86_64`. It setups the stack and map `elf` binary into the correct location in memory. It maps the [bss](https://en.wikipedia.org/wiki/.bss) and the [brk](http://man7.org/linux/man-pages/man2/sbrk.2.html) sections and does many many other different things to prepare executable file to execute.
that describes [segments](https://en.wikipedia.org/wiki/Memory_segmentation). Read the `program interpreter` and libraries that linked with the our executable binary file from disk and load it to memory. The `program interpreter` specified in the `.interp` section of the executable file and as you can read in the part that describes [Linkers](https://0xax.gitbook.io/linux-insides/summary/misc/linux-misc-3) it is - `/lib64/ld-linux-x86-64.so.2` for the `x86_64`. It setups the stack and map `elf` binary into the correct location in memory. It maps the [bss](https://en.wikipedia.org/wiki/.bss) and the [brk](https://man7.org/linux/man-pages/man2/sbrk.2.html) sections and does many many other different things to prepare executable file to execute.
In the end of the execution of the `load_elf_binary` we call the `start_thread` function and pass three arguments to it:

View File

@@ -8,7 +8,7 @@
你觉得怎么样,我认为这些非常有趣耶,操作系统如何工作,我们的软件如何与(系统)交互呢。你或许了解,我们的程序通过特定的机制和内核进行交互,这个机制就是[系统调用](https://en.wikipedia.org/wiki/System_call)。因此,我决定去写一些系统调用的实现及其行为,比如我们每天会用到的 `read`,`write`,`open`,`close`,`dup` 等等。
我决定从 [open](http://man7.org/linux/man-pages/man2/open.2.html) 系统调用开始。如果你对 C 程序有了解,你应该知道在我们能对一个文件进行读写或执行其他操作前,我们需要使用 `open` 函数打开这个文件:
我决定从 [open](https://man7.org/linux/man-pages/man2/open.2.html) 系统调用开始。如果你对 C 程序有了解,你应该知道在我们能对一个文件进行读写或执行其他操作前,我们需要使用 `open` 函数打开这个文件:
```C
#include <fcntl.h>
@@ -42,7 +42,7 @@ $ sudo ls /proc/1/fd/
1 11 13 15 19 20 22 24 26 28 3 31 33 35 37 39 40 42 44 46 48 5 51 54 57 59 60 62 65 7 9
```
我并不打算在这篇文章中以用户空间的视角来描述更多 `open` 例程细节,会更多地从内核的角度来分析。如果你不是很熟悉 `open` 函数,你可以在 [man 手册](http://man7.org/linux/man-pages/man2/open.2.html)获取更多信息。
我并不打算在这篇文章中以用户空间的视角来描述更多 `open` 例程细节,会更多地从内核的角度来分析。如果你不是很熟悉 `open` 函数,你可以在 [man 手册](https://man7.org/linux/man-pages/man2/open.2.html)获取更多信息。
开始吧!
@@ -80,7 +80,7 @@ if (force_o_largefile())
flags |= O_LARGEFILE;
```
这里可以看到如果 `force_o_largefile()` 返回 true传递给 `open` 系统调用的 flags 参数会加上了 `O_LARGEFILE` 标志。`O_LARGEFILE` 是什么?阅读 `open(2)` [man 手册](http://man7.org/linux/man-pages/man2/open.2.html) 可以了解到:
这里可以看到如果 `force_o_largefile()` 返回 true传递给 `open` 系统调用的 flags 参数会加上了 `O_LARGEFILE` 标志。`O_LARGEFILE` 是什么?阅读 `open(2)` [man 手册](https://man7.org/linux/man-pages/man2/open.2.html) 可以了解到:
> O_LARGEFILE
>
@@ -214,9 +214,9 @@ else
> if neither O_CREAT nor O_TMPFILE is specified, then mode is ignored.
在其他情况下,如果 `O_CREAT``O_TMPFILE` 标志被传递,我们可以把这个转换为一个规则文件因为 `opendir`(http://man7.org/linux/man-pages/man3/opendir.3.html) 系统调用会创建一个目录。
在其他情况下,如果 `O_CREAT``O_TMPFILE` 标志被传递,我们可以把这个转换为一个规则文件因为 `opendir`(https://man7.org/linux/man-pages/man3/opendir.3.html) 系统调用会创建一个目录。
在接下来的步骤,我们检查一个文件是否被 [fanotify](http://man7.org/linux/man-pages/man7/fanotify.7.html)打开过并且没有 `O_CLOSEXEC` 标志:
在接下来的步骤,我们检查一个文件是否被 [fanotify](https://man7.org/linux/man-pages/man7/fanotify.7.html)打开过并且没有 `O_CLOSEXEC` 标志:
```C
flags &= ~FMODE_NONOTIFY & ~O_CLOEXEC;
@@ -383,27 +383,27 @@ if (unlikely(filp == ERR_PTR(-ESTALE)))
总结
--------------------------------------------------------------------------------
Linux 内核中关于不同系统调用的实现的第五部分已经完成了。如果你有任何问题, 可通过 twitter 或邮箱与我联系,[@0xAX](https://twitter.com/0xAX)/[email](mailto:anotherworldofworld@gmail.com), 或者提交一个 [issue](https://github.com/0xAX/linux-internals/issues/new). 在接下来的部分, 我们将继续深究 Linux 内核中的系统调用并且看看 [read](http://man7.org/linux/man-pages/man2/read.2.html) 系统调用的实现。
Linux 内核中关于不同系统调用的实现的第五部分已经完成了。如果你有任何问题, 可通过 twitter 或邮箱与我联系,[@0xAX](https://twitter.com/0xAX)/[email](mailto:anotherworldofworld@gmail.com), 或者提交一个 [issue](https://github.com/0xAX/linux-insides/issues/new). 在接下来的部分, 我们将继续深究 Linux 内核中的系统调用并且看看 [read](https://man7.org/linux/man-pages/man2/read.2.html) 系统调用的实现。
**请谅解英语不是我的母语,对于任何不恰当的表述我深感抱歉。如果你发现任何错误,请在 [linux-insides](https://github.com/0xAX/linux-internals) 给我发 PR 。**
**请谅解英语不是我的母语,对于任何不恰当的表述我深感抱歉。如果你发现任何错误,请在 [linux-insides](https://github.com/0xAX/linux-insides) 给我发 PR 。**
参考链接
--------------------------------------------------------------------------------
* [system call](https://en.wikipedia.org/wiki/System_call)
* [open](http://man7.org/linux/man-pages/man2/open.2.html)
* [open](https://man7.org/linux/man-pages/man2/open.2.html)
* [file descriptor](https://en.wikipedia.org/wiki/File_descriptor)
* [proc](https://en.wikipedia.org/wiki/Procfs)
* [GNU C Library Reference Manual](https://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Position-Primitive)
* [IA-64](https://en.wikipedia.org/wiki/IA-64)
* [x86_64](https://en.wikipedia.org/wiki/X86-64)
* [opendir](http://man7.org/linux/man-pages/man3/opendir.3.html)
* [fanotify](http://man7.org/linux/man-pages/man7/fanotify.7.html)
* [opendir](https://man7.org/linux/man-pages/man3/opendir.3.html)
* [fanotify](https://man7.org/linux/man-pages/man7/fanotify.7.html)
* [fork](https://en.wikipedia.org/wiki/Fork_\(system_call\))
* [execve](https://en.wikipedia.org/wiki/Exec_\(system_call\))
* [symlink](https://en.wikipedia.org/wiki/Symbolic_link)
* [audit](https://linux.die.net/man/8/auditd)
* [inode](https://en.wikipedia.org/wiki/Inode)
* [RCU](https://www.kernel.org/doc/Documentation/RCU/whatisRCU.txt)
* [read](http://man7.org/linux/man-pages/man2/read.2.html)
* [read](https://man7.org/linux/man-pages/man2/read.2.html)
* [previous part](/SysCall/linux-syscall-4.md)

View File

@@ -83,15 +83,15 @@ Now let's look at list of available resources:
| RLIMIT_FSIZE | the maximum size of files that a process may create |
| RLIMIT_DATA | the maximum size of the process's data segment |
| RLIMIT_STACK | the maximum size of the process stack in bytes |
| RLIMIT_CORE | the maximum size of a [core](http://man7.org/linux/man-pages/man5/core.5.html) file. |
| RLIMIT_CORE | the maximum size of a [core](https://man7.org/linux/man-pages/man5/core.5.html) file. |
| RLIMIT_RSS | the number of bytes that can be allocated for a process in RAM |
| RLIMIT_NPROC | the maximum number of processes that can be created by a user |
| RLIMIT_NOFILE | the maximum number of a file descriptor that can be opened by a process |
| RLIMIT_MEMLOCK | the maximum number of bytes of memory that may be locked into RAM by [mlock](http://man7.org/linux/man-pages/man2/mlock.2.html).|
| RLIMIT_MEMLOCK | the maximum number of bytes of memory that may be locked into RAM by [mlock](https://man7.org/linux/man-pages/man2/mlock.2.html).|
| RLIMIT_AS | the maximum size of virtual memory in bytes. |
| RLIMIT_LOCKS | the maximum number [flock](https://linux.die.net/man/1/flock) and locking related [fcntl](http://man7.org/linux/man-pages/man2/fcntl.2.html) calls|
| RLIMIT_SIGPENDING | maximum number of [signals](http://man7.org/linux/man-pages/man7/signal.7.html) that may be queued for a user of the calling process|
| RLIMIT_MSGQUEUE | the number of bytes that can be allocated for [POSIX message queues](http://man7.org/linux/man-pages/man7/mq_overview.7.html) |
| RLIMIT_LOCKS | the maximum number [flock](https://linux.die.net/man/1/flock) and locking related [fcntl](https://man7.org/linux/man-pages/man2/fcntl.2.html) calls|
| RLIMIT_SIGPENDING | maximum number of [signals](https://man7.org/linux/man-pages/man7/signal.7.html) that may be queued for a user of the calling process|
| RLIMIT_MSGQUEUE | the number of bytes that can be allocated for [POSIX message queues](https://man7.org/linux/man-pages/man7/mq_overview.7.html) |
| RLIMIT_NICE | the maximum [nice](https://linux.die.net/man/1/nice) value that can be set by a process |
| RLIMIT_RTPRIO | maximum real-time priority value |
| RLIMIT_RTTIME | maximum number of microseconds that a process may be scheduled under real-time scheduling policy without making blocking system call|
@@ -207,9 +207,9 @@ That's all.
Conclusion
--------------------------------------------------------------------------------
This is the end of the second part that describes implementation of the system calls in the Linux kernel. If you have questions or suggestions, ping me on Twitter [0xAX](https://twitter.com/0xAX), drop me an [email](mailto:anotherworldofworld@gmail.com), or just create an [issue](https://github.com/0xAX/linux-internals/issues/new).
This is the end of the second part that describes implementation of the system calls in the Linux kernel. If you have questions or suggestions, ping me on Twitter [0xAX](https://twitter.com/0xAX), drop me an [email](mailto:anotherworldofworld@gmail.com), or just create an [issue](https://github.com/0xAX/linux-insides/issues/new).
**Please note that English is not my first language and I am really sorry for any inconvenience. If you find any mistakes please send me PR to [linux-insides](https://github.com/0xAX/linux-internals).**
**Please note that English is not my first language and I am really sorry for any inconvenience. If you find any mistakes please send me PR to [linux-insides](https://github.com/0xAX/linux-insides).**
Links
--------------------------------------------------------------------------------
@@ -218,4 +218,4 @@ Links
* [PID](https://en.wikipedia.org/wiki/Process_identifier)
* [ulimit](https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-ulimit)
* [strace](https://linux.die.net/man/1/strace)
* [POSIX message queues](http://man7.org/linux/man-pages/man7/mq_overview.7.html)
* [POSIX message queues](https://man7.org/linux/man-pages/man7/mq_overview.7.html)

View File

@@ -17,7 +17,7 @@
|├ [2.1](Initialization/linux-initialization-1.md)|[@dontpanic92](https://github.com/dontpanic92)|更新至[4401750766f7](https://github.com/0xAX/linux-insides/commit/4401750766f7150dcd16f579026f5554541a6ab9)|
|├ [2.2](Initialization/linux-initialization-2.md)|[@dontpanic92](https://github.com/dontpanic92)|更新至[4401750766f7](https://github.com/0xAX/linux-insides/commit/4401750766f7150dcd16f579026f5554541a6ab9)|
|├ [2.3](Initialization/linux-initialization-3.md)|[@dontpanic92](https://github.com/dontpanic92)|更新至[4401750766f7](https://github.com/0xAX/linux-insides/commit/4401750766f7150dcd16f579026f5554541a6ab9)|
|├ [2.4](Initialization/linux-initialization-4.md)|[@bjwrkj](https://github.com/bjwrkj)|已完成|
|├ [2.4](Initialization/linux-initialization-4.md)|@bjwrkj|已完成|
|├ [2.5](Initialization/linux-initialization-5.md)|[@NeoCui](https://github.com/NeoCui)|更新至[cf32dc6c81ab](https://github.com/0xAX/linux-insides/commit/cf32dc6c81abce567af330c480afc3d58678443d)|
|├ [2.6](Initialization/linux-initialization-6.md)|[@kele1997](https://github.com/kele1997)|更新至[e896e56c867](https://github.com/0xAX/linux-insides/commit/e896e56c867876397ef78da58d5e2a31b2e690b6)|
|├ [2.7](Initialization/linux-initialization-7.md)||未开始|
@@ -58,7 +58,7 @@
|├ [6.1](SyncPrim/linux-sync-1.md)|[@keltoy](https://github.com/keltoy)|已完成|
|├ [6.2](SyncPrim/linux-sync-2.md)|[@keltoy](https://github.com/keltoy)|已完成|
|├ [6.3](SyncPrim/linux-sync-3.md)|[@huxq](https://github.com/huxq)|已完成|
|├ [6.4](SyncPrim/linux-sync-4.md)|[@nannxnann](https://github.com/nannxnann)|更新至[c4b17d17a085](https://github.com/0xAX/linux-insides/commit/c4b17d17a085608e8de6e310797d8e81927aed8d)|
|├ [6.4](SyncPrim/linux-sync-4.md)|@nannxnann|更新至[c4b17d17a085](https://github.com/0xAX/linux-insides/commit/c4b17d17a085608e8de6e310797d8e81927aed8d)|
|├ [6.5](SyncPrim/linux-sync-5.md)||未开始|
|└ [6.6](SyncPrim/linux-sync-6.md)||未开始|
| 7. [Memory management](MM)||未开始|
@@ -95,7 +95,7 @@
|└ [14.1](KernelStructures/linux-kernelstructure-1.md)|[@woodpenker](https://github.com/woodpenker)|更新至[4521637d9cb7](https://github.com/0xAX/linux-insides/commit/4521637d9cb76e5d4e4dc951758b264a68504927)|
| 15. [Cgroups](Cgroups)||已完成|
|├ [15.0](Cgroups/README.md)|[@mudongliang](https://github.com/mudongliang)|更新至[90f50c2ac5a1](https://github.com/0xAX/linux-insides/commit/90f50c2ac5a197da044e5091c631dd43e811ca4f)|
|└ [15.1](Cgroups/linux-cgroups-1.md)|[@tjm-1990](https://github.com/tjm-1990)|更新至[b420e581fe3c](https://github.com/0xAX/linux-insides/commit/b420e581fe3cfee64d9c65103740d4fd98127b6f)|
|└ [15.1](Cgroups/linux-cgroups-1.md)|@tjm-1990|更新至[b420e581fe3c](https://github.com/0xAX/linux-insides/commit/b420e581fe3cfee64d9c65103740d4fd98127b6f)|
### 翻译认领规则

View File

@@ -284,7 +284,7 @@ end of sleep
and the second line after five seconds.
The `nanosleep` is not located in the `vDSO` area like the `gettimeofday` and the `clock_gettime` functions. So, let's look how the `real` system call which is located in the kernel space will be called by the standard library. The implementation of the `nanosleep` system call will be called with the help of the [syscall](http://www.felixcloutier.com/x86/SYSCALL.html) instruction. Before the execution of the `syscall` instruction, parameters of the system call must be put in processor [registers](https://en.wikipedia.org/wiki/Processor_register) according to order which is described in the [System V Application Binary Interface](http://www.x86-64.org/documentation/abi.pdf) or in other words:
The `nanosleep` is not located in the `vDSO` area like the `gettimeofday` and the `clock_gettime` functions. So, let's look how the `real` system call which is located in the kernel space will be called by the standard library. The implementation of the `nanosleep` system call will be called with the help of the [syscall](https://www.felixcloutier.com/x86/SYSCALL.html) instruction. Before the execution of the `syscall` instruction, parameters of the system call must be put in processor [registers](https://en.wikipedia.org/wiki/Processor_register) according to order which is described in the [System V Application Binary Interface](http://www.x86-64.org/documentation/abi.pdf) or in other words:
* `rdi` - first parameter;
* `rsi` - second parameter;