wslで、最小のカーネルをコンパイル その3

# 概要
wslで、kernel.elfのコンパイル、やってみた。
cで、書いてみた。

# 参考にしたページ

https://github.com/pritamzope/OS

# 手順

# cで、kernelを書く。

- 画面クリアして、「Hello world」を表示。

kernel.h

```
#ifndef KERNEL_H
#define KERNEL_H

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
#define VGA_ADDRESS 0xB8000
#define BUFSIZE 2200
uint16* vga_buffer;
#define NULL 0
enum vga_color {
    BLACK,
    BLUE,
    GREEN,
    CYAN,
    RED,
    MAGENTA,
    BROWN,
    GREY,
    DARK_GREY,
    BRIGHT_BLUE,
    BRIGHT_GREEN,
    BRIGHT_CYAN,
    BRIGHT_RED,
    BRIGHT_MAGENTA,
    YELLOW,
    WHITE,
};
#endif





```

kernel.c

```
#include "kernel.h"

uint16 vga_entry(unsigned char ch, uint8 fore_color, uint8 back_color) {
	uint16 ax = 0;
	uint8 ah = 0, al = 0;
	ah = back_color;
	ah <<= 4;
	ah |= fore_color;
	ax = ah;
	ax <<= 8;
	al = ch;
	ax |= al;
	return ax;
}
void clear_vga_buffer(uint16 ** buffer, uint8 fore_color, uint8 back_color) {
	uint32 i;
	for(i = 0; i < BUFSIZE; i++)
	{
		(*buffer)[i] = vga_entry(NULL, fore_color, back_color);
	}
}
void init_vga(uint8 fore_color, uint8 back_color) {
	vga_buffer = (uint16*)VGA_ADDRESS;
	clear_vga_buffer(&vga_buffer, fore_color, back_color);
}
void kernel_entry() {
	init_vga(WHITE, BLACK);
	vga_buffer[0] = vga_entry('H', WHITE, BLACK);
	vga_buffer[1] = vga_entry('e', WHITE, BLACK);
	vga_buffer[2] = vga_entry('l', WHITE, BLACK);
	vga_buffer[3] = vga_entry('l', WHITE, BLACK);
	vga_buffer[4] = vga_entry('o', WHITE, BLACK);
	vga_buffer[5] = vga_entry(' ', WHITE, BLACK);
	vga_buffer[6] = vga_entry('W', WHITE, BLACK);
	vga_buffer[7] = vga_entry('o', WHITE, BLACK);
	vga_buffer[8] = vga_entry('r', WHITE, BLACK);
	vga_buffer[9] = vga_entry('l', WHITE, BLACK);
	vga_buffer[10] = vga_entry('d', WHITE, BLACK);
}





```

# アセンブラを書く。
gas(nasmじゃない)
grubで、起動できるように、multiboot書く。

boot.S

```
.set MAGIC,    0x1BADB002
.set FLAGS,    0
.set CHECKSUM, -(MAGIC + FLAGS)

.section .multiboot
	.long MAGIC
	.long FLAGS
	.long CHECKSUM
stackBottom:
	.skip 1024
stackTop:

.section .text
.global _start
.type _start, @function
_start:
	mov 	$stackTop, %esp
	call 	kernel_entry
	cli
hltLoop:
	hlt
	jmp 	hltLoop
.size _start, . - _start





```

# リンカーを書く。

linker.ld

```

ENTRY(_start)

SECTIONS
{
	. = 1M;
	.text BLOCK(4K) : ALIGN(4K) {
		*(.multiboot)
		*(.text)
	}
	.rodata BLOCK(4K) : ALIGN(4K) {
		*(.rodata)
	}
	.data BLOCK(4K) : ALIGN(4K) {
		*(.data)
	}
	.bss BLOCK(4K) : ALIGN(4K) {
		*(COMMON)
		*(.bss)
	}
}



```

# Makefileを書く。
- elfを作る。

Makefile
```

all: kernel1.elf
kernel1.elf: kernel.o boot.o
	ld -m elf_i386 -T linker.ld kernel.o boot.o -o kernel1.elf -nostdlib
kernel.o: kernel.c
	gcc -m32 -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
boot.o: boot.S
	as --32 boot.S -o boot.o
clean:
	$(rm) boot.o kernel.o kernel1.elf





```

# makeする。
- kernel1.elfが、できる。

# 確認する。

```
$ readelf -a kernel1.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x100511
  Start of program headers:          52 (bytes into file)
  Start of section headers:          6240 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         4
  Size of section headers:           40 (bytes)
  Number of section headers:         10
  Section header string table index: 9

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00100000 001000 00051f 00  AX  0   0 4096
  [ 2] .text.__x86.get_p PROGBITS        0010051f 00151f 000004 00  AX  0   0  1
  [ 3] .eh_frame         PROGBITS        00100524 001524 00007c 00   A  0   0  4
  [ 4] .got.plt          PROGBITS        001005a0 0015a0 00000c 04  WA  0   0  4
  [ 5] .bss              NOBITS          00101000 002000 000004 00  WA  0   0 4096
  [ 6] .comment          PROGBITS        00000000 0015ac 000029 01  MS  0   0  1
  [ 7] .symtab           SYMTAB          00000000 0015d8 000180 10      8  17  4
  [ 8] .strtab           STRTAB          00000000 001758 0000a7 00      0   0  1
  [ 9] .shstrtab         STRTAB          00000000 0017ff 00005e 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x00100000 0x00100000 0x005a0 0x005a0 R E 0x1000
  LOAD           0x0015a0 0x001005a0 0x00101000 0x0000c 0x0000c RW  0x1000
  LOAD           0x002000 0x00101000 0x00102000 0x00000 0x00004 RW  0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10

 Section to Segment mapping:
  Segment Sections...
   00     .text .text.__x86.get_pc_thunk.ax .eh_frame
   01     .got.plt
   02     .bss
   03

There is no dynamic section in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type Intel 80386 is not currently supported.

Symbol table '.symtab' contains 24 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00100000     0 SECTION LOCAL  DEFAULT    1
     2: 0010051f     0 SECTION LOCAL  DEFAULT    2
     3: 00100524     0 SECTION LOCAL  DEFAULT    3
     4: 001005a0     0 SECTION LOCAL  DEFAULT    4
     5: 00101000     0 SECTION LOCAL  DEFAULT    5
     6: 00000000     0 SECTION LOCAL  DEFAULT    6
     7: 00000000     0 FILE    LOCAL  DEFAULT  ABS boot.o
     8: 1badb002     0 NOTYPE  LOCAL  DEFAULT  ABS MAGIC
     9: 00000000     0 NOTYPE  LOCAL  DEFAULT  ABS FLAGS
    10: e4524ffe     0 NOTYPE  LOCAL  DEFAULT  ABS CHECKSUM
    11: 0010000c     0 NOTYPE  LOCAL  DEFAULT    1 stackBottom
    12: 0010040c     0 NOTYPE  LOCAL  DEFAULT    1 stackTop
    13: 0010051c     0 NOTYPE  LOCAL  DEFAULT    1 hltLoop
    14: 00000000     0 FILE    LOCAL  DEFAULT  ABS kernel.c
    15: 00000000     0 FILE    LOCAL  DEFAULT  ABS
    16: 001005a0     0 OBJECT  LOCAL  DEFAULT    4 _GLOBAL_OFFSET_TABLE_
    17: 00100460    63 FUNC    GLOBAL DEFAULT    1 init_vga
    18: 00100430    44 FUNC    GLOBAL DEFAULT    1 clear_vga_buffer
    19: 00101000     4 OBJECT  GLOBAL DEFAULT    5 vga_buffer
    20: 0010051f     0 FUNC    GLOBAL HIDDEN     2 __x86.get_pc_thunk.ax
    21: 001004a0   113 FUNC    GLOBAL DEFAULT    1 kernel_entry
    22: 00100511    14 FUNC    GLOBAL DEFAULT    1 _start
    23: 00100410    23 FUNC    GLOBAL DEFAULT    1 vga_entry

No version information found in this file.


```

以上。