---
# System prepended metadata

title: JOS Lab 1

---

# JOS Lab 1


3. 
    - The transition happens by a Ljump. (`boot.S:99 - ljmp    $PROT_MODE_CSEG, $protcseg`) The first instruction after the LJump (shown below) is the first instruction that is first exectued in 32-bit mode.
`movw    $PROT_MODE_DSEG, %ax`. 
        - Before the ljump, the processor was set to protected mode by modifying the %cr0 register. 
        - Ljump in protected mode behaves differently from when it is in a real mode. The code segment operand($PROT_MODE_CSEG, or equally 0x8, in this case) is interpreted as a code segment selector. Ljump will use the selector to grap segment descriptor from the global descriptor table. The grapped segment descriptor includes information about the segment, particulary the type of the segment, e.g. whether the segment is a code segment or a data segment, whether the segment is 16-bit or 32-bit. Ljump in our case will read the segment descriptor, and after figuring out that the segment is a 32-bit code segment, moves the processor to a 32-bit mode. 
        - https://wiki.osdev.org/Segment_Selector
        - https://wiki.osdev.org/Global_Descriptor_Table
        - https://shell-storm.org/x86doc/JMP.html
    - The last instruction executed in the bootloader is as below \
    `(main.c:65) 7dea:	jmp    *0x10018`
    - The first instruction executed in the kernel is as below \
    `(bootstrap.S:22) movl $multiboot_info, %eax`
    - Short answer: The bootloader finds out the location of the sectors to read using the information in file header and the program header table saved at the start of the disk.
        - The bootloader reads the first 8 sectors to load the file header and the program header table. The location of the file header is exactly at the beggining of the disk, so the bootloader can easily identify and read the file header. Using the file header, the bootloader finds out where and how long is the program header table, and read each entry one by one. Each entry contains the data about offset and number of sectors to read, and even where in the memory the data should be loaded.
        

5. `ljmp    $PROT_MODE_CSEG, $protcseg`에서. $protcseg가 잘못된 값으로 되어 있음.

6.
At the bootloader entrypoint.
```
(gdb) x/10x 0x100000
0x100000 <_head64>:     0x00000000      0x00000000      0x00000000      0x00000000
0x100010 <_head64+16>:  0x00000000      0x00000000      0x00000000      0x00000000
0x100020 <_head64+32>:  0x00000000      0x00000000
```
At the kernel entrypoint
```
(gdb) x/10x 0x100000
0x100000 <_head64>:     0x107000b8      0x66188900      0x047205c7      0x12340000
0x100010 <_head64+16>:  0x007c00bc      0x00cce800      0x20b80000      0x0f000000
0x100020 <_head64+32>:  0x00bfe022      0x31001020
```
It's different because the bootloader has loaded kernel into the address space. Since 0x100000 is the entrypoint of the kernel, the data loaded there will be the kernel codes to executed first, which will be the compiled output of kern/bootstrap.S.


7.
- The new mapping takes effect when the PG flag of the cr0 register is set to true; that is, after the codes below are executed.
`(kern/bootstrap.S:117) movl %eax,%cr0`
`(kern/bootstrap.S:121) movl %eax,%cr0`

- The GDT used in the kernel codes are as below

in bootstrap.S
```
gdt_64:
    SEG_NULL
    .quad  0x00af9a000000ffff            #64 bit CS
    .quad  0x00cf92000000ffff            #64 bit DS
```
in entry.S
```
kernel_64:
    SEG_NULL
    SEG64(STA_X|STA_R,0x0,0xffffffff)    #64 bit CS
    SEG64(STA_R|STA_W,0x0,0xffffffff)    #64 bit DS
    SEG64USER(STA_X|STA_R,0x0,0xffffffff) #64 bit USER CS
    SEG64USER(STA_R|STA_W,0x0,0xffffffff) # USER data
    .quad   0x0080890000000000  /* TS descriptor */ 
    .quad   0x0000000000000000 /* TS continued */
```
If you interpret the GDT in bootstrap.S according to https://wiki.osdev.org/Global_Descriptor_Table, the upper GDT entry is a 64-bit code segment, and the lower is a 32-bit data segment(contrary to the comment), both with base of 0 and limit of 0xffffffff.

All the segments cover all the memory space with base 0. This means that we will not be using memory segmentation and all the addresses will be interpreted and protected only by paging.



9.
Initialized here.
```
# entry.S:70
	# Set the stack pointer
	movabs	$(bootstacktop),%rax
	movq  %rax,%rsp

```
```
# entry.S:82
.data
###################################################################
# boot stack
###################################################################
	.p2align	PGSHIFT		# force page alignment
	.globl		bootstack
bootstack:
	.space		KSTKSIZE
	.globl		bootstacktop   
bootstacktop:

```
At the .data section of the kernel program, a memory of size KSTKSIZE is reserved for the stack. 
The stack pointer is initialized to point at the top end (where the address is highest).


10.

4 64-bit words