Procházet zdrojové kódy

Normalize indentation in linux-bootstrap-2 to improve readability

Matthieu Tardy před 9 roky
rodič
revize
175b153379
1 změnil soubory, kde provedl 113 přidání a 113 odebrání
  1. 113 113
      Booting/linux-bootstrap-2.md

+ 113 - 113
Booting/linux-bootstrap-2.md

@@ -189,19 +189,19 @@ Note that it copies `hdr` with `memcpy` function which is defined in the [copy.S
 
 ```assembly
 GLOBAL(memcpy)
-	pushw	%si
-	pushw	%di
-	movw	%ax, %di
-	movw	%dx, %si
-	pushw	%cx
-	shrw	$2, %cx
-	rep; movsl
-	popw	%cx
-	andw	$3, %cx
-	rep; movsb
-	popw	%di
-	popw	%si
-	retl
+    pushw   %si
+    pushw   %di
+    movw    %ax, %di
+    movw    %dx, %si
+    pushw   %cx
+    shrw    $2, %cx
+    rep; movsl
+    popw    %cx
+    andw    $3, %cx
+    rep; movsb
+    popw    %di
+    popw    %si
+    retl
 ENDPROC(memcpy)
 ```
 
@@ -227,15 +227,15 @@ After `hdr` is copied into `boot_params.hdr`, the next step is console initializ
 
 It tries to find the `earlyprintk` option in the command line and if the search was successful, it parses the port address and baud rate of the serial port and initializes the serial port. Value of `earlyprintk` command line option can be one of these:
 
-	* serial,0x3f8,115200
-	* serial,ttyS0,115200
-	* ttyS0,115200
+* serial,0x3f8,115200
+* serial,ttyS0,115200
+* ttyS0,115200
 
 After serial port initialization we can see the first output:
 
 ```C
 if (cmdline_find_option_bool("debug"))
-		puts("early console in setup code\n");
+    puts("early console in setup code\n");
 ```
 
 The definition of `puts` is in [tty.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/tty.c). As we can see it prints character by character in a loop by calling the `putchar` function. Let's look into the `putchar` implementation:
@@ -243,13 +243,13 @@ The definition of `puts` is in [tty.c](https://github.com/torvalds/linux/blob/ma
 ```C
 void __attribute__((section(".inittext"))) putchar(int ch)
 {
-	if (ch == '\n')
-		putchar('\r');
+    if (ch == '\n')
+        putchar('\r');
 
-	bios_putchar(ch);
+    bios_putchar(ch);
 
-	if (early_serial_base != 0)
-		serial_putchar(ch);
+    if (early_serial_base != 0)
+        serial_putchar(ch);
 }
 ```
 
@@ -260,44 +260,44 @@ First of all, `putchar` checks for the `\n` symbol and if it is found, prints `\
 ```C
 static void __attribute__((section(".inittext"))) bios_putchar(int ch)
 {
-	struct biosregs ireg;
-
-	initregs(&ireg);
-	ireg.bx = 0x0007;
-	ireg.cx = 0x0001;
-	ireg.ah = 0x0e;
-	ireg.al = ch;
-	intcall(0x10, &ireg, NULL);
+    struct biosregs ireg;
+
+    initregs(&ireg);
+    ireg.bx = 0x0007;
+    ireg.cx = 0x0001;
+    ireg.ah = 0x0e;
+    ireg.al = ch;
+    intcall(0x10, &ireg, NULL);
 }
 ```
 
 Here `initregs` takes the `biosregs` structure and first fills `biosregs` with zeros using the `memset` function and then fills it with register values.
 
 ```C
-	memset(reg, 0, sizeof *reg);
-	reg->eflags |= X86_EFLAGS_CF;
-	reg->ds = ds();
-	reg->es = ds();
-	reg->fs = fs();
-	reg->gs = gs();
+    memset(reg, 0, sizeof *reg);
+    reg->eflags |= X86_EFLAGS_CF;
+    reg->ds = ds();
+    reg->es = ds();
+    reg->fs = fs();
+    reg->gs = gs();
 ```
 
 Let's look at the [memset](https://github.com/torvalds/linux/blob/master/arch/x86/boot/copy.S#L36) implementation:
 
 ```assembly
 GLOBAL(memset)
-	pushw	%di
-	movw	%ax, %di
-	movzbl	%dl, %eax
-	imull	$0x01010101,%eax
-	pushw	%cx
-	shrw	$2, %cx
-	rep; stosl
-	popw	%cx
-	andw	$3, %cx
-	rep; stosb
-	popw	%di
-	retl
+    pushw   %di
+    movw    %ax, %di
+    movzbl  %dl, %eax
+    imull   $0x01010101,%eax
+    pushw   %cx
+    shrw    $2, %cx
+    rep; stosl
+    popw    %cx
+    andw    $3, %cx
+    rep; stosb
+    popw    %di
+    retl
 ENDPROC(memset)
 ```
 
@@ -319,18 +319,18 @@ After the stack and bss section were prepared in [header.S](https://github.com/t
 First of all `init_heap` checks the [`CAN_USE_HEAP`](https://github.com/torvalds/linux/blob/master/arch/x86/include/uapi/asm/bootparam.h#L21) flag from the [`loadflags`](https://github.com/torvalds/linux/blob/master/arch/x86/boot/header.S#L321) in the kernel setup header and calculates the end of the stack if this flag was set:
 
 ```C
-	char *stack_end;
+    char *stack_end;
 
-	if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
-		asm("leal %P1(%%esp),%0"
-		    : "=r" (stack_end) : "i" (-STACK_SIZE));
+    if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
+        asm("leal %P1(%%esp),%0"
+            : "=r" (stack_end) : "i" (-STACK_SIZE));
 ```
 
 or in other words `stack_end = esp - STACK_SIZE`.
 
 Then there is the `heap_end` calculation:
 ```c
-	heap_end = (char *)((size_t)boot_params.hdr.heap_end_ptr + 0x200);
+    heap_end = (char *)((size_t)boot_params.hdr.heap_end_ptr + 0x200);
 ```
 which means `heap_end_ptr` or `_end` + `512`(`0x200h`). The last check is whether `heap_end` is greater than `stack_end`. If it is then `stack_end` is assigned to `heap_end` to make them equal.
 
@@ -344,10 +344,10 @@ The next step as we can see is cpu validation by `validate_cpu` from [arch/x86/b
 It calls the [`check_cpu`](https://github.com/torvalds/linux/blob/master/arch/x86/boot/cpucheck.c#L102) function and passes cpu level and required cpu level to it and checks that the kernel launches on the right cpu level.
 ```c
 check_cpu(&cpu_level, &req_level, &err_flags);
-	if (cpu_level < req_level) {
+if (cpu_level < req_level) {
     ...
-	return -1;
-	}
+    return -1;
+}
 ```
 `check_cpu` checks the cpu's flags, presence of [long mode](http://en.wikipedia.org/wiki/Long_mode) in case of x86_64(64-bit) CPU, checks the processor's vendor and makes preparation for certain vendors like turning off SSE+SSE2 for AMD if they are missing, etc.
 
@@ -359,11 +359,11 @@ The next step is memory detection by the `detect_memory` function. `detect_memor
 Let's look into the `detect_memory_e820` implementation from the [arch/x86/boot/memory.c](https://github.com/torvalds/linux/blob/master/arch/x86/boot/memory.c) source file. First of all, the `detect_memory_e820` function initializes the `biosregs` structure as we saw above and fills registers with special values for the `0xe820` call:
 
 ```assembly
-	initregs(&ireg);
-	ireg.ax  = 0xe820;
-	ireg.cx  = sizeof buf;
-	ireg.edx = SMAP;
-	ireg.di  = (size_t)&buf;
+    initregs(&ireg);
+    ireg.ax  = 0xe820;
+    ireg.cx  = sizeof buf;
+    ireg.edx = SMAP;
+    ireg.di  = (size_t)&buf;
 ```
 
 * `ax` contains the number of the function (0xe820 in our case)
@@ -375,8 +375,8 @@ Let's look into the `detect_memory_e820` implementation from the [arch/x86/boot/
 Next is a loop where data about the memory will be collected. It starts from the call of the `0x15` BIOS interrupt, which writes one line from the address allocation table. For getting the next line we need to call this interrupt again (which we do in the loop). Before the next call `ebx` must contain the value returned previously:
 
 ```C
-	intcall(0x15, &ireg, &oreg);
-	ireg.ebx = oreg.ebx;
+    intcall(0x15, &ireg, &oreg);
+    ireg.ebx = oreg.ebx;
 ```
 
 Ultimately, it does iterations in the loop to collect data from the address allocation table and writes this data into the `e820entry` array:
@@ -402,15 +402,15 @@ Keyboard initialization
 
 The next step is the initialization of the keyboard with the call of the [`keyboard_init()`](https://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c#L65) function. At first `keyboard_init` initializes registers using the `initregs` function and calling the [0x16](http://www.ctyme.com/intr/rb-1756.htm) interrupt for getting the keyboard status.
 ```c
-	initregs(&ireg);
-	ireg.ah = 0x02;		/* Get keyboard status */
-	intcall(0x16, &ireg, &oreg);
-	boot_params.kbd_status = oreg.al;
+    initregs(&ireg);
+    ireg.ah = 0x02;     /* Get keyboard status */
+    intcall(0x16, &ireg, &oreg);
+    boot_params.kbd_status = oreg.al;
 ```
 After this it calls [0x16](http://www.ctyme.com/intr/rb-1757.htm) again to set repeat rate and delay.
 ```c
-	ireg.ax = 0x0305;	/* Set keyboard repeat rate */
-	intcall(0x16, &ireg, NULL);
+    ireg.ax = 0x0305;   /* Set keyboard repeat rate */
+    intcall(0x16, &ireg, NULL);
 ```
 
 Querying
@@ -423,54 +423,54 @@ The [query_mca](https://github.com/torvalds/linux/blob/master/arch/x86/boot/mca.
 ```c
 int query_mca(void)
 {
-	struct biosregs ireg, oreg;
-	u16 len;
+    struct biosregs ireg, oreg;
+    u16 len;
 
-	initregs(&ireg);
-	ireg.ah = 0xc0;
-	intcall(0x15, &ireg, &oreg);
+    initregs(&ireg);
+    ireg.ah = 0xc0;
+    intcall(0x15, &ireg, &oreg);
 
-	if (oreg.eflags & X86_EFLAGS_CF)
-		return -1;	/* No MCA present */
+    if (oreg.eflags & X86_EFLAGS_CF)
+        return -1;  /* No MCA present */
 
-	set_fs(oreg.es);
-	len = rdfs16(oreg.bx);
+    set_fs(oreg.es);
+    len = rdfs16(oreg.bx);
 
-	if (len > sizeof(boot_params.sys_desc_table))
-		len = sizeof(boot_params.sys_desc_table);
+    if (len > sizeof(boot_params.sys_desc_table))
+        len = sizeof(boot_params.sys_desc_table);
 
-	copy_from_fs(&boot_params.sys_desc_table, oreg.bx, len);
-	return 0;
+    copy_from_fs(&boot_params.sys_desc_table, oreg.bx, len);
+    return 0;
 }
 ```
 
 It fills  the `ah` register with `0xc0` and calls the `0x15` BIOS interruption. After the interrupt execution it checks  the [carry flag](http://en.wikipedia.org/wiki/Carry_flag) and if it is set to 1, the BIOS doesn't support (**MCA**)[https://en.wikipedia.org/wiki/Micro_Channel_architecture]. If carry flag is set to 0, `ES:BX` will contain a pointer to the system information table, which looks like this:
 
 ```
-Offset	Size	Description	)
- 00h	WORD	number of bytes following
- 02h	BYTE	model (see #00515)
- 03h	BYTE	submodel (see #00515)
- 04h	BYTE	BIOS revision: 0 for first release, 1 for 2nd, etc.
- 05h	BYTE	feature byte 1 (see #00510)
- 06h	BYTE	feature byte 2 (see #00511)
- 07h	BYTE	feature byte 3 (see #00512)
- 08h	BYTE	feature byte 4 (see #00513)
- 09h	BYTE	feature byte 5 (see #00514)
+Offset  Size    Description
+ 00h    WORD    number of bytes following
+ 02h    BYTE    model (see #00515)
+ 03h    BYTE    submodel (see #00515)
+ 04h    BYTE    BIOS revision: 0 for first release, 1 for 2nd, etc.
+ 05h    BYTE    feature byte 1 (see #00510)
+ 06h    BYTE    feature byte 2 (see #00511)
+ 07h    BYTE    feature byte 3 (see #00512)
+ 08h    BYTE    feature byte 4 (see #00513)
+ 09h    BYTE    feature byte 5 (see #00514)
 ---AWARD BIOS---
- 0Ah  N BYTEs	AWARD copyright notice
+ 0Ah  N BYTEs   AWARD copyright notice
 ---Phoenix BIOS---
- 0Ah	BYTE	??? (00h)
- 0Bh	BYTE	major version
- 0Ch	BYTE	minor version (BCD)
- 0Dh  4 BYTEs	ASCIZ string "PTL" (Phoenix Technologies Ltd)
+ 0Ah    BYTE    ??? (00h)
+ 0Bh    BYTE    major version
+ 0Ch    BYTE    minor version (BCD)
+ 0Dh  4 BYTEs   ASCIZ string "PTL" (Phoenix Technologies Ltd)
 ---Quadram Quad386---
- 0Ah 17 BYTEs	ASCII signature string "Quadram Quad386XT"
+ 0Ah 17 BYTEs   ASCII signature string "Quadram Quad386XT"
 ---Toshiba (Satellite Pro 435CDS at least)---
- 0Ah  7 BYTEs	signature "TOSHIBA"
- 11h	BYTE	??? (8h)
- 12h	BYTE	??? (E7h) product ID??? (guess)
- 13h  3 BYTEs	"JPN"
+ 0Ah  7 BYTEs   signature "TOSHIBA"
+ 11h    BYTE    ??? (8h)
+ 12h    BYTE    ??? (E7h) product ID??? (guess)
+ 13h  3 BYTEs   "JPN"
  ```
 
 Next we call the `set_fs` routine and pass the value of the `es` register to it. The implementation of `set_fs` is pretty simple:
@@ -478,7 +478,7 @@ Next we call the `set_fs` routine and pass the value of the `es` register to it.
 ```c
 static inline void set_fs(u16 seg)
 {
-	asm volatile("movw %0,%%fs" : : "rm" (seg));
+    asm volatile("movw %0,%%fs" : : "rm" (seg));
 }
 ```
 
@@ -496,7 +496,7 @@ Note that `query_apm_bios` will be executed only if `CONFIG_APM` or `CONFIG_APM_
 
 ```C
 #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
-	query_apm_bios();
+    query_apm_bios();
 #endif
 ```
 
@@ -507,15 +507,15 @@ First of all it reads the [edd](https://github.com/torvalds/linux/blob/master/Do
 If EDD is enabled, `query_edd` goes over BIOS-supported hard disks and queries EDD information in the following loop:
 
 ```C
-	for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
-		if (!get_edd_info(devno, &ei) && boot_params.eddbuf_entries < EDDMAXNR) {
-			memcpy(edp, &ei, sizeof ei);
-			edp++;
-			boot_params.eddbuf_entries++;
-		}
-		...
-		...
-		...
+for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
+    if (!get_edd_info(devno, &ei) && boot_params.eddbuf_entries < EDDMAXNR) {
+        memcpy(edp, &ei, sizeof ei);
+        edp++;
+        boot_params.eddbuf_entries++;
+    }
+    ...
+    ...
+    ...
 ```
 
 where `0x80` is the first hard drive and the value of `EDD_MBR_SIG_MAX` macro is 16. It collects data into the array of [edd_info](https://github.com/torvalds/linux/blob/master/include/uapi/linux/edd.h#L172) structures. `get_edd_info` checks that EDD is present by invoking the `0x13` interrupt with `ah` as `0x41` and if EDD is present, `get_edd_info` again calls the `0x13` interrupt, but with `ah` as `0x48` and `si` containing the address of the buffer where EDD information will be stored.