[SOLVED] CS #include threads/loader.h

$25

File Name: CS_#include_threads/loader.h.zip
File Size: 263.76 KB

5/5 - (1 vote)

#include threads/loader.h

#### Kernel loader.

#### This code should be stored in the first sector of a hard disk.
#### When the BIOS runs, it loads this code at physical address
#### 0x7c00-0x7e00 (512 bytes) and jumps to the beginning of it,
#### in real mode.The loader loads the kernel into memory and jumps
#### to its entry point, which is the start function in start.S.
####
#### The BIOS passes in the drive that the loader was read from as
#### DL, with floppy drives numbered 0x00, 0x01, and hard drives
#### numbered 0x80, 0x81, We want to support booting a kernel on
#### a different drive from the loader, so we dont take advantage of
#### this.

# Runs in real mode, which is a 16-bit segment.
.code16

# Set up segment registers.
# Set stack to grow downward from 60 kB (after boot, the kernel
# continues to use this stack for its initial thread).

sub %ax, %ax
mov %ax, %ds
mov %ax, %ss
mov $0xf000, %esp

# Configure serial port so we can report progress without connected VGA.
# See [IntrList] for details.
sub %dx, %dx# Serial port 0.
mov $0xe3, %al# 9600 bps, N-8-1.
# AH is already 0 (Initialize Port).
int $0x14# Destroys AX.

call puts
.string PiLo

#### Read the partition table on each system hard disk and scan for a
#### partition of type 0x20, which is the type that we use for a
#### Pintos kernel.
####
#### Read [Partitions] for a description of the partition table format
#### that we parse.
####
#### We print out status messages to show the disk and partition being
#### scanned, e.g. hda1234 as we scan four partitions on the first
#### hard disk.

mov $0x80, %dl# Hard disk 0.
read_mbr:
sub %ebx, %ebx# Sector 0.
mov $0x2000, %ax# Use 0x20000 for buffer.
mov %ax, %es
call read_sector
jc no_such_drive

# Print hd[a-z].
call puts
.string hd
mov %dl, %al
add $a 0x80, %al
call putc

# Check for MBR signatureif not present, its not a
# partitioned hard disk.
cmpw $0xaa55, %es:510
jne next_drive

mov $446, %si# Offset of partition table entry 1.
mov $1, %al
check_partition:
# Is it an unused partition?
cmpl $0, %es:(%si)
je next_partition

# Print [1-4].
call putc

# Is it a Pintos kernel partition?
cmpb $0x20, %es:4(%si)
jne next_partition

# Is it a bootable partition?
cmpb $0x80, %es:(%si)
je load_kernel

next_partition:
# No match for this partition, go on to the next one.
add $16, %si# Offset to next partition table entry.
inc %al
cmp $510, %si
jb check_partition

next_drive:
# No match on this drive, go on to the next one.
inc %dl
jnc read_mbr

no_such_drive:
no_boot_partition:
# Didnt find a Pintos kernel partition anywhere, give up.
call puts
.string rNot foundr

# Notify BIOS that boot failed.See [IntrList].
int $0x18

#### We found a kernel.The kernels drive is in DL.The partition
#### table entry for the kernels partition is at ES:SI.Our job now
#### is to read the kernel from disk and jump to its start address.

load_kernel:
call puts
.string rLoading

# Figure out number of sectors to read.A Pintos kernel is
# just an ELF format object, which doesnt have an
# easy-to-read field to identify its own size (see [ELF1]).
# But we limit Pintos kernels to 512 kB for other reasons, so
# its easy enough to just read the entire contents of the
# partition or 512 kB from disk, whichever is smaller.
mov %es:12(%si), %ecx# EBP = number of sectors
cmp $1024, %ecx# Cap size at 512 kB
jbe 1f
mov $1024, %cx
1:

mov %es:8(%si), %ebx# EBX = first sector
mov $0x2000, %ax# Start load address: 0x20000

next_sector:
# Read one sector into memory.
mov %ax, %es# ES:0000 -> load address
call read_sector
jc read_failed

# Print . as progress indicator once every 16 sectors == 8 kB.
test $15, %bl
jnz 1f
call puts
.string .
1:

# Advance memory pointer and disk sector.
add $0x20, %ax
inc %bx
loop next_sector

call puts
.string r

#### Transfer control to the kernel that we loaded.We read the start
#### address out of the ELF header (see [ELF1]) and convert it from a
#### 32-bit linear address into a 16:16 segment:offset address for
#### real mode, then jump to the converted address.The 8086 doesnt
#### have an instruction to jump to an absolute segment:offset kept in
#### registers, so in fact we store the address in a temporary memory
#### location, then jump indirectly through that location.To save 4
#### bytes in the loader, we reuse 4 bytes of the loaders code for
#### this temporary pointer.

mov $0x2000, %ax
mov %ax, %es
mov %es:0x18, %dx
mov %dx, start
movw $0x2000, start + 2
ljmp *start

read_failed:
start:
# Disk sector read failed.
call puts
1:.string rBad readr

# Notify BIOS that boot failed.See [IntrList].
int $0x18

#### Print string subroutine.To save space in the loader, this
#### subroutine takes its null-terminated string argument from the
#### code stream just after the call, and then returns to the byte
#### just after the terminating null.This subroutine preserves all
#### general-purpose registers.

puts:xchg %si, %ss:(%esp)
push %ax
next_char:
mov %cs:(%si), %al
inc %si
test %al, %al
jz 1f
call putc
jmp next_char
1:pop %ax
xchg %si, %ss:(%esp)
ret

#### Character output subroutine.Prints the character in AL to the
#### VGA display and serial port 0, using BIOS services (see
#### [IntrList]).Preserves all general-purpose registers.
####
#### If called upon to output a carriage return, this subroutine
#### automatically supplies the following line feed.

putc:pusha

1:sub %bh, %bh# Page 0.
mov $0x0e, %ah# Teletype output service.
int $0x10

mov $0x01, %ah# Serial port output service.
sub %dx, %dx# Serial port 0.
2:int $0x14# Destroys AH.
test $0x80, %ah# Output timed out?
jz 3f
movw $0x9090, 2b# Turn int $0x14 above into NOPs.

3:
cmp $r, %al
jne popa_ret
mov $
, %al
jmp 1b

#### Sector read subroutine.Takes a drive number in DL (0x80 = hard
#### disk 0, 0x81 = hard disk 1, ) and a sector number in EBX, and
#### reads the specified sector into memory at ES:0000.Returns with
#### carry set on error, clear otherwise.Preserves all
#### general-purpose registers.

read_sector:
pusha
sub %ax, %ax
push %ax# LBA sector number [48:63]
push %ax# LBA sector number [32:47]
push %ebx# LBA sector number [0:31]
push %es# Buffer segment
push %ax# Buffer offset (always 0)
push $1# Number of sectors to read
push $16# Packet size
mov $0x42, %ah# Extended read
mov %sp, %si# DS:SI -> packet
int $0x13# Error code in CF
popa# Pop 16 bytes, preserve flags
popa_ret:
popa
ret# Error code still in CF

#### Command-line arguments and their count.
#### This is written by the `pintos utility and read by the kernel.
#### The loader itself does not do anything with the command line.
.org LOADER_ARG_CNT LOADER_BASE
.fill LOADER_ARG_CNT_LEN, 1, 0

.org LOADER_ARGS LOADER_BASE
.fill LOADER_ARGS_LEN, 1, 0

#### Partition table.
.org LOADER_PARTS LOADER_BASE
.fill LOADER_PARTS_LEN, 1, 0

#### Boot-sector signature for BIOS inspection.
.org LOADER_SIG LOADER_BASE
.word 0xaa55

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] CS #include threads/loader.h
$25