diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index a29ab64..5121f48 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -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 diff --git a/Cgroups/linux-cgroups-1.md b/Cgroups/linux-cgroups-1.md index 6d02d7c..d1505fa 100644 --- a/Cgroups/linux-cgroups-1.md +++ b/Cgroups/linux-cgroups-1.md @@ -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) diff --git a/Concepts/linux-cpu-4.md b/Concepts/linux-cpu-4.md index 161bbed..0b8e080 100644 --- a/Concepts/linux-cpu-4.md +++ b/Concepts/linux-cpu-4.md @@ -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) diff --git a/DataStructures/linux-datastructures-1.md b/DataStructures/linux-datastructures-1.md index 73ad55f..452169b 100644 --- a/DataStructures/linux-datastructures-1.md +++ b/DataStructures/linux-datastructures-1.md @@ -14,7 +14,7 @@ struct list_head { }; ``` -你可能注意到这和你以前见过的双向链表的实现方法是不同的。举个例子来说,在 [glib](http://www.gnu.org/software/libc/) 库里是这样实现的: +你可能注意到这和你以前见过的双向链表的实现方法是不同的。举个例子来说,在 [glib](https://www.gnu.org/software/libc/) 库里是这样实现的: ```C struct GList { diff --git a/DataStructures/linux-datastructures-3.md b/DataStructures/linux-datastructures-3.md index f6ae360..f4db326 100644 --- a/DataStructures/linux-datastructures-3.md +++ b/DataStructures/linux-datastructures-3.md @@ -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) \ No newline at end of file diff --git a/Initialization/linux-initialization-10.md b/Initialization/linux-initialization-10.md index 016f76c..5435d67 100644 --- a/Initialization/linux-initialization-10.md +++ b/Initialization/linux-initialization-10.md @@ -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) diff --git a/Interrupts/linux-interrupts-10.md b/Interrupts/linux-interrupts-10.md index 4d09eed..8fd8115 100644 --- a/Interrupts/linux-interrupts-10.md +++ b/Interrupts/linux-interrupts-10.md @@ -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/) diff --git a/Interrupts/linux-interrupts-3.md b/Interrupts/linux-interrupts-3.md index d358f2a..7529914 100644 --- a/Interrupts/linux-interrupts-3.md +++ b/Interrupts/linux-interrupts-3.md @@ -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) diff --git a/Interrupts/linux-interrupts-4.md b/Interrupts/linux-interrupts-4.md index 0aacd77..57e20f6 100644 --- a/Interrupts/linux-interrupts-4.md +++ b/Interrupts/linux-interrupts-4.md @@ -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) diff --git a/LINKS.md b/LINKS.md index 4f1d178..fe3deb0 100644 --- a/LINKS.md +++ b/LINKS.md @@ -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 ------------------------ diff --git a/Misc/linux-misc-1.md b/Misc/linux-misc-1.md index 514a96b..d6c7cd6 100644 --- a/Misc/linux-misc-1.md +++ b/Misc/linux-misc-1.md @@ -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) diff --git a/Misc/linux-misc-2.md b/Misc/linux-misc-2.md index 5ea6ea6..1b9d9d4 100644 --- a/Misc/linux-misc-2.md +++ b/Misc/linux-misc-2.md @@ -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) diff --git a/Misc/linux-misc-4.md b/Misc/linux-misc-4.md index 7e8bd9a..0fc5e11 100644 --- a/Misc/linux-misc-4.md +++ b/Misc/linux-misc-4.md @@ -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` 中。如果我们添加这个目标文件: diff --git a/README.md b/README.md index 7c6ff89..37b2400 100644 --- a/README.md +++ b/README.md @@ -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/) 许可证。 diff --git a/Scripts/validate_markdown_links.py b/Scripts/validate_markdown_links.py index 6abf5c5..c2ea296 100755 --- a/Scripts/validate_markdown_links.py +++ b/Scripts/validate_markdown_links.py @@ -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") diff --git a/SyncPrim/linux-sync-2.md b/SyncPrim/linux-sync-2.md index fded09a..78e791b 100644 --- a/SyncPrim/linux-sync-2.md +++ b/SyncPrim/linux-sync-2.md @@ -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) diff --git a/SysCall/linux-syscall-2.md b/SysCall/linux-syscall-2.md index 796f54f..88339bc 100644 --- a/SysCall/linux-syscall-2.md +++ b/SysCall/linux-syscall-2.md @@ -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) diff --git a/SysCall/linux-syscall-4.md b/SysCall/linux-syscall-4.md index 91076e1..50ffc5e 100644 --- a/SysCall/linux-syscall-4.md +++ b/SysCall/linux-syscall-4.md @@ -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: diff --git a/SysCall/linux-syscall-5.md b/SysCall/linux-syscall-5.md index ac8ff15..bae6eb5 100644 --- a/SysCall/linux-syscall-5.md +++ b/SysCall/linux-syscall-5.md @@ -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 @@ -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) \ No newline at end of file diff --git a/SysCall/linux-syscall-6.md b/SysCall/linux-syscall-6.md index 22bc452..008fdc8 100644 --- a/SysCall/linux-syscall-6.md +++ b/SysCall/linux-syscall-6.md @@ -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) diff --git a/TRANSLATION_STATUS.md b/TRANSLATION_STATUS.md index b5311a0..770d1e1 100644 --- a/TRANSLATION_STATUS.md +++ b/TRANSLATION_STATUS.md @@ -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)| ### 翻译认领规则 diff --git a/Timers/linux-timers-7.md b/Timers/linux-timers-7.md index 768ea21..e55a572 100644 --- a/Timers/linux-timers-7.md +++ b/Timers/linux-timers-7.md @@ -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;