Linux source code reading - system boot bootsect.s

xiaoxiao2021-03-05  24

System starts bootsect.s

General PC is started by the address FFFF: 0000 in memory (this address must be in ROM BI) when the power supply is in the power supply.

In the OS, the ROM BIOS is generally in Feoooh to FFFFFH), and the content here is a JUMP instruction, and JUMP to another location in the ROM BIOS, start executing a series of actions, including checking RAM, Keyboard, Display, hard disk, etc., these actions are performed by the system test code (POST, SYSTEM TEST CODE), with some of the differences in the production of BIOS vendors, but they are all different, readers can observe their own machines themselves. When booting, the inspection message displayed on the screen is displayed.

Immediately after the system test code, the control will transfer to the starter in the ROM (ROTSTRAP ROUTINE), which reads the zero zero zone on the disk into the memory (this is the general so-called Boot Sector, If you have been exposed to computer viruses, you will have heard its name), as for where to be read? - Absolute position 07c0: 0000 (ie 07c00H), this is the characteristics of the IBM series PC. And the boot sector of the Linux boot disk is Linux's bootsect program, that is, bootsect is the first program that is read in memory and executed. Now, we can start to see what the Bootsect has done.

first step

First, Bootsect moves it "yourself" from the absolute address 0x7C00 loaded by the ROM BIOS, 0x90000,

Then use a Jump Indirectly instruction to jump to the next line of JMPI, the next line of JMPI.

Movw $ bootseg,% AX # $ bootseg = 0x07c0

MOVW% AX,% DS

Movw $ INITSEG,% AX # $ INITSEG = DEF_INITSEG = 0x0x9000

MOVW% AX,% ES

MovW $ 256,% CX # 256word s == 512bytes

SubW% Si,% Si

SubW% di,% di

CLD

REP

Movsw

LJMP $ INITSEG, $ GO

Second step

Then, other Segment Registers include DS, ES, and SS, point to 0x9000, and CS

. In addition, SP and DX point to an emitted address (OFFSET), this address, etc., will be used to store disk parameters

DISK Para- Meter Table

Go: MoVW $ 0x4000-12,% DI # 0x4000 is an arbitrary value> =

# Length of bootsect length of

# setup room for stack;

# 12 is disk parm size.

MOVW% AX,% DS # Ax and es already contain initseg

MOVW% AX,% SS

MOVW% DI,% sp # put stack at initseg: 0x4000-12.sp = 0x94000-12, 12byte release disk parameter third step

Then use the BIOS interrupt service INT 13h function, reset the disk controller, so that the setup is issued

Will function. It is mainly to increase the number of read sectors, increase efficiency.

# Many Bios's Default Disk Parameter Tables WILL NOT Recognize

# Multi-Sector Reads Beyond The Maximum Sector Number Specified

# in The Default Diskette Parameter Tables - This May Mean 7

# Sectors in some case.

#

# Since Single Sector Reads Are Slow and Out of The Question,

# we must take care of this by Creating New Parameter Tables

# (for the first disk) in ram. We will set the maximum sector

# Count to 36 - The Most We will Encounter on AN ED 2.88.

#

# High doesn't hurt. Low does.

#

# Segments are as stock: DS = es = ss = cs = initseg, fs = 0,

# and gs unused.

MOVW% CX,% FS ​​# set fs to 0

MovW $ 0x78,% bx # fs: bx is parameter Table address, disk parameters have been read by BIOS this address, is the physical address 0x78

PushW% DS

LDSW% FS: (% bx),% si # ds: Si is source ds: Si == 0x0000: 0x78

MovB $ 6,% Cl # Copy 12 Bytes

Pushw% DI # di = 0x4000-12.

Rep # Don't Need CLD -> DONE ON LINE 66

Movsw #ds: Si - ÄES: DI

POPW% DI

POPW% DS

MOVB $ 36, 0x4 (% DI) # patch sector count, reset 36

MOVW% DI,% FS: (% BX)

MOVW% ES,% FS: 2 (% BX)

XORB% ah,% ah # reset fdc

XORB% DL,% DL

INT $ 0x13

the fourth step

After completing the reset disk controller, BootSect reads from the disk to the SETUP program next to Bootsect,

That is, setup.s, this read action is to use the BIOS interrupt service INT 13H. Setup's image

It is read to the memory absolute address 0x90200 specified by the program, which is close to Bootsect in memory.

s position. After reading in the memory, you will read the No. 2 function of INT 13H using the BIOS interrupt service INT 13H.

Parameters of the disk. XORW% DX,% DX # Drive 0, Head 0

MOVB $ 0x02,% Cl # Sector 2, Track 0

MovW $ 0x0200,% bx # address = 512, in initseg, 0x90200

Movb $ 0x02,% ah # service 2, "Read Sector (s)"

Movb setup_sects,% Al # (Assume All on Head 0, TRACK 0) setup_sects = 4, the number of sectors read

INT $ 0x13 # read it, setup.s is located in memory physical address 0x90200,

JNC OK_LOAD_SETUP # OK - Continue

# 读 读 错 错 处理 处理

PushW% AX # DUMP ERROR CODE error handling, AX gets error code

Call Print_nl

MOVW% SP,% BP

Call Print_HEX

POPW% AX

JMP load_setup

OK_LOAD_SETUP:

# Get Disk Drive Parameters, Specification Number of Sectors / Track.

# It seems what there is no bios call to get the number of subjectors.

# Guess 36 Sectors if Sector 36 Can Be Read, 18 Sectors IF Sector 18

# can be read, 15 if Sector 15 Can Be Read. OtherWise Guess 9.

Movw $ Diskszes,% si # Table of Sizes To try defines data Disksizes: .bete 36, 18, 15, 9 at the end of the file

Probe_loop:

Lodsb # (al) <- ((si)), (Si) <- (si) 1

CBTW # Extend to Word, Al-> AX

MOVW% AX, Sectors #sectors: .word 0

CMPW $ DISKSIZES 4,% Si

Jae Got_sectors #jae is not lower, or higher than or equal to, or the inlet bit is 0 Transfer IF All Else Fails, TRY 9. It is 36, 18, 15, and 9 test, jumps to Got_sectors

XCHGW% CX,% AX # cx = TRACK AND SECTOR

XORW% DX,% DX # Drive 0, Head 0

XORB% BL,% BL

Movb setup_sects,% BH

IncB% BH

SHLB% BH # Address After Setup (ES = CS)

MovW $ 0x0201,% AX # Service 2, 1 Sector

INT $ 0x13

JC Probe_loop # try next value, is from 0 head, 0 tracks, read sections 36, 18, 15, can see if it is successful, if successful jumps to Got_sectors, otherwise, then test the next number. Read the content to the memory behind setup.s, these sectors have no significance, just to test SECTORS / TRACK.

the fifth step

Come, you have to read the real Linux kernel, that is, you can see "V" in the root of Linux

"Mlinuz". Before reading, you will call the BIOS interrupt service INT 10h, read the cursor position,

After calling the BIOS interrupt service INT 10h, the string "loading" is output on the screen.

Strings will be seen first in Boot Linux, I believe everyone should feel familiar.

Got_sectors:

Movw $ INITSEG,% AX

MOVW% AX,% ES # set up es

MovB $ 0x03,% ah # read cursor POS

XORB% BH,% BH

INT $ 0x10 # call 10 interrupt, function 3, read the position of the cursor

MoVW $ 9,% CX

MoVW $ 0x0007,% BX # Page 0, Attribute 7 (Normal)

MOVW $ MSG1,% BP

MovW $ 0x1301,% AX # Write String, Move Cursor

INT $ 0x10 # tell the user we're loading .. Prints the contents of MSG1 at the cursor, MSG1 = 'load ... ..';

Movw $ sysseg,% AX # OK, We've Written The Message, Now, $ Sysseg = 0x1000

MOVW% AX,% ES # we want to load system (at 0x10000)

Call read_it # reads VMLinux to 0x10000, the size is 0x7f00, will read the fastest speed, the method is to read a complete track with the SECTORS / TRACK tested in front.

Call Kill_Motor

Call Print_nl

Sixth step

The next thing is to check the root device, followed by the beginning of the way, using Indirect Jump

Jump to SETUP part you have just read

#After That We Check Which root-device to use. If the device is

# Defined (! = 0), Nothing is Done and the Given Device IS Used.

# ErWise, One of / DEV / FD0H2880 (2,32) OR / DEV / PS0 (2,28) OR / DEV / AT0 (2, 8)

# depending on the number of researchors we pretend to know we have.

Movw root_dev,% AX

ORW% AX,% AX

JNE root_defined

Movw Sectors,% BX

MoVW $ 0x0208,% AX # / dev / ps0 - 1.2MB

CMPW $ 15,% BX

JE root_defined

MOVB $ 0x1c,% Al # / DEV / PS0 - 1.44MB

CMPW $ 18,% BX

JE root_defined

MOVB $ 0X20,% Al # / dev / fd0h2880 - 2.88MB

CMPW $ 36,% BX

JE root_defined

MOVB $ 0,% Al # / dev / fd0 - Autodtect

root_defined:

MOVW% AX, root_dev

#After That (Everything loaded), We jump to the setup-routine

# loading Directly After the bootblock:

LJMP $ setupseg, $ 0 #jmp to 0x90200

转载请注明原文地址:https://www.9cbs.com/read-37196.html

New Post(0)