⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boot.s

📁 linux-0.01 学习linux编程的好
💻 S
字号:
||	boot.s|| boot.s is loaded at 0x7c00 by the bios-startup routines, and moves itself| out of the way to address 0x90000, and jumps there.|| It then loads the system at 0x10000, using BIOS interrupts. Thereafter| it disables all interrupts, moves the system down to 0x0000, changes| to protected mode, and calls the start of system. System then must| RE-initialize the protected mode in it's own tables, and enable| interrupts as needed.|| NOTE! currently system is at most 8*65536 bytes long. This should be no| problem, even in the future. I want to keep it simple. This 512 kB| kernel size should be enough - in fact more would mean we'd have to move| not just these start-up routines, but also do something about the cache-| memory (block IO devices). The area left over in the lower 640 kB is meant| for these. No other memory is assumed to be "physical", ie all memory| over 1Mb is demand-paging. All addresses under 1Mb are guaranteed to match| their physical addresses.|| NOTE1 abouve is no longer valid in it's entirety. cache-memory is allocated| above the 1Mb mark as well as below. Otherwise it is mainly correct.|| NOTE 2! The boot disk type must be set at compile-time, by setting| the following equ. Having the boot-up procedure hunt for the right| disk type is severe brain-damage.| The loader has been made as simple as possible (had to, to get it| in 512 bytes with the code to move to protected mode), and continuos| read errors will result in a unbreakable loop. Reboot by hand. It| loads pretty fast by getting whole sectors at a time whenever possible.| 1.44Mb disks:sectors = 18| 1.2Mb disks:| sectors = 15| 720kB disks:| sectors = 9.globl begtext, begdata, begbss, endtext, enddata, endbss.textbegtext:.databegdata:.bssbegbss:.textBOOTSEG = 0x07c0INITSEG = 0x9000SYSSEG  = 0x1000			| system loaded at 0x10000 (65536).ENDSEG	= SYSSEG + SYSSIZEentry startstart:	mov	ax,#BOOTSEG	mov	ds,ax	mov	ax,#INITSEG	mov	es,ax	mov	cx,#256	sub	si,si	sub	di,di	rep	movw	jmpi	go,INITSEGgo:	mov	ax,cs	mov	ds,ax	mov	es,ax	mov	ss,ax	mov	sp,#0x400		| arbitrary value >>512	mov	ah,#0x03	| read cursor pos	xor	bh,bh	int	0x10		mov	cx,#24	mov	bx,#0x0007	| page 0, attribute 7 (normal)	mov	bp,#msg1	mov	ax,#0x1301	| write string, move cursor	int	0x10| ok, we've written the message, now| we want to load the system (at 0x10000)	mov	ax,#SYSSEG	mov	es,ax		| segment of 0x010000	call	read_it	call	kill_motor| if the read went well we get current cursor position ans save it for| posterity.	mov	ah,#0x03	| read cursor pos	xor	bh,bh	int	0x10		| save it in known place, con_init fetches	mov	[510],dx	| it from 0x90510.		| now we want to move to protected mode ...	cli			| no interrupts allowed !| first we move the system to it's rightful place	mov	ax,#0x0000	cld			| 'direction'=0, movs moves forwarddo_move:	mov	es,ax		| destination segment	add	ax,#0x1000	cmp	ax,#0x9000	jz	end_move	mov	ds,ax		| source segment	sub	di,di	sub	si,si	mov 	cx,#0x8000	rep	movsw	j	do_move| then we load the segment descriptorsend_move:	mov	ax,cs		| right, forgot this at first. didn't work :-)	mov	ds,ax	lidt	idt_48		| load idt with 0,0	lgdt	gdt_48		| load gdt with whatever appropriate| that was painless, now we enable A20	call	empty_8042	mov	al,#0xD1		| command write	out	#0x64,al	call	empty_8042	mov	al,#0xDF		| A20 on	out	#0x60,al	call	empty_8042| well, that went ok, I hope. Now we have to reprogram the interrupts :-(| we put them right after the intel-reserved hardware interrupts, at| int 0x20-0x2F. There they won't mess up anything. Sadly IBM really| messed this up with the original PC, and they haven't been able to| rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,| which is used for the internal hardware interrupts as well. We just| have to reprogram the 8259's, and it isn't fun.	mov	al,#0x11		| initialization sequence	out	#0x20,al		| send it to 8259A-1	.word	0x00eb,0x00eb		| jmp $+2, jmp $+2	out	#0xA0,al		| and to 8259A-2	.word	0x00eb,0x00eb	mov	al,#0x20		| start of hardware int's (0x20)	out	#0x21,al	.word	0x00eb,0x00eb	mov	al,#0x28		| start of hardware int's 2 (0x28)	out	#0xA1,al	.word	0x00eb,0x00eb	mov	al,#0x04		| 8259-1 is master	out	#0x21,al	.word	0x00eb,0x00eb	mov	al,#0x02		| 8259-2 is slave	out	#0xA1,al	.word	0x00eb,0x00eb	mov	al,#0x01		| 8086 mode for both	out	#0x21,al	.word	0x00eb,0x00eb	out	#0xA1,al	.word	0x00eb,0x00eb	mov	al,#0xFF		| mask off all interrupts for now	out	#0x21,al	.word	0x00eb,0x00eb	out	#0xA1,al| well, that certainly wasn't fun :-(. Hopefully it works, and we don't| need no steenking BIOS anyway (except for the initial loading :-).| The BIOS-routine wants lots of unnecessary data, and it's less| "interesting" anyway. This is how REAL programmers do it.|| Well, now's the time to actually move into protected mode. To make| things as simple as possible, we do no register set-up or anything,| we let the gnu-compiled 32-bit programs do that. We just jump to| absolute address 0x00000, in 32-bit protected mode.	mov	ax,#0x0001	| protected mode (PE) bit	lmsw	ax		| This is it!	jmpi	0,8		| jmp offset 0 of segment 8 (cs)| This routine checks that the keyboard command queue is empty| No timeout is used - if this hangs there is something wrong with| the machine, and we probably couldn't proceed anyway.empty_8042:	.word	0x00eb,0x00eb	in	al,#0x64	| 8042 status port	test	al,#2		| is input buffer full?	jnz	empty_8042	| yes - loop	ret| This routine loads the system at address 0x10000, making sure| no 64kB boundaries are crossed. We try to load it as fast as| possible, loading whole tracks whenever we can.|| in:	es - starting address segment (normally 0x1000)|| This routine has to be recompiled to fit another drive type,| just change the "sectors" variable at the start of the file| (originally 18, for a 1.44Mb drive)|sread:	.word 1			| sectors read of current trackhead:	.word 0			| current headtrack:	.word 0			| current trackread_it:	mov ax,es	test ax,#0x0fffdie:	jne die			| es must be at 64kB boundary	xor bx,bx		| bx is starting address within segmentrp_read:	mov ax,es	cmp ax,#ENDSEG		| have we loaded all yet?	jb ok1_read	retok1_read:	mov ax,#sectors	sub ax,sread	mov cx,ax	shl cx,#9	add cx,bx	jnc ok2_read	je ok2_read	xor ax,ax	sub ax,bx	shr ax,#9ok2_read:	call read_track	mov cx,ax	add ax,sread	cmp ax,#sectors	jne ok3_read	mov ax,#1	sub ax,head	jne ok4_read	inc trackok4_read:	mov head,ax	xor ax,axok3_read:	mov sread,ax	shl cx,#9	add bx,cx	jnc rp_read	mov ax,es	add ax,#0x1000	mov es,ax	xor bx,bx	jmp rp_readread_track:	push ax	push bx	push cx	push dx	mov dx,track	mov cx,sread	inc cx	mov ch,dl	mov dx,head	mov dh,dl	mov dl,#0	and dx,#0x0100	mov ah,#2	int 0x13	jc bad_rt	pop dx	pop cx	pop bx	pop ax	retbad_rt:	mov ax,#0	mov dx,#0	int 0x13	pop dx	pop cx	pop bx	pop ax	jmp read_track/* * This procedure turns off the floppy drive motor, so * that we enter the kernel in a known state, and * don't have to worry about it later. */kill_motor:	push dx	mov dx,#0x3f2	mov al,#0	outb	pop dx	retgdt:	.word	0,0,0,0		| dummy	.word	0x07FF		| 8Mb - limit=2047 (2048*4096=8Mb)	.word	0x0000		| base address=0	.word	0x9A00		| code read/exec	.word	0x00C0		| granularity=4096, 386	.word	0x07FF		| 8Mb - limit=2047 (2048*4096=8Mb)	.word	0x0000		| base address=0	.word	0x9200		| data read/write	.word	0x00C0		| granularity=4096, 386idt_48:	.word	0			| idt limit=0	.word	0,0			| idt base=0Lgdt_48:	.word	0x800		| gdt limit=2048, 256 GDT entries	.word	gdt,0x9		| gdt base = 0X9xxxx	msg1:	.byte 13,10	.ascii "Loading system ..."	.byte 13,10,13,10.textendtext:.dataenddata:.bssendbss:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -