Linux内核引导x86平台分析

本文详细分析了Linux内核在x86平台上引导的过程,包括如何处理引导信息、设置堆栈、初始化BSS段以及如何跳转到C代码执行主要的初始化任务。在引导过程中,检查了设置的签名,若不正确会显示错误信息并停止启动。
摘要由CSDN通过智能技术生成
标志位 */</font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#2040a0">bugger_off_msg</font>, <font color="4444FF">%</font><font color="#2040a0">si</font> <font color="#444444">/* 要打印信息的地址放到%si当中,为下面lodsb作准备 */</font>
<font color="#2040a0">msg_loop</font><font color="4444FF">:</font>
	<font color="#2040a0">lodsb</font>		<font color="#444444">/* 取字节字符串指令 ds:si Byte -> al */</font>
	<font color="#2040a0">andb</font>	<font color="4444FF">%</font><font color="#2040a0">al</font>, <font color="4444FF">%</font><font color="#2040a0">al</font><font color="#444444">/* 测试是否是字符串结尾 */</font>
	<font color="#2040a0">jz</font>	<font color="#2040a0">bs_die</font>  <font color="#444444">/* 是则跳到下面的bs_die执行 */</font>
	<font color="#2040a0">movb</font>	{1}lt;font color="#FF0000">0xe</font>, <font color="4444FF">%</font><font color="#2040a0">ah</font> <font color="#444444">/* 否则,执行BIOS 10H功能调用,调用号是14,十六进制的0xe */</font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#FF0000">7</font>, <font color="4444FF">%</font><font color="#2040a0">bx</font>   <font color="#444444">/* 要显示的字符位于al当中,调用号的作用是在当前光标处写字符 */</font>
	<strong>int</strong>	{1}lt;font color="#FF0000">0x10</font>	<font color="#444444">/* 这里执行调用 */</font>
	<font color="#2040a0">jmp</font>	<font color="#2040a0">msg_loop</font> <font color="#444444">/* 循环显示bugger_off_msg当中的所有字符 */</font>

<font color="#2040a0">bs_die</font><font color="4444FF">:</font> <font color="#444444">/* 提示错误的信息现实完毕了,然后到这里 */</font>
<font color="0000ff"><strong>	# Allow the user to press a key, then reboot</strong></font>
	<font color="#2040a0">xorw</font>	<font color="4444FF">%</font><font color="#2040a0">ax</font>, <font color="4444FF">%</font><font color="#2040a0">ax</font> <font color="#444444">/* 清%ax */</font>
	<strong>int</strong>	{1}lt;font color="#FF0000">0x16</font> <font color="#444444">/* BIOS 16H功能调用,键盘服务,等待用户输入 */</font>
	<strong>int</strong>	{1}lt;font color="#FF0000">0x19</font> <font color="#444444">/* BIOS 19H功能调用,重启系统 */</font>

<font color="0000ff"><strong>	# int 0x19 should never return.  In case it does anyway,</strong></font>
<font color="0000ff"><strong>	# invoke the BIOS reset code...</strong></font>
	<font color="#2040a0">ljmp</font>	{1}lt;font color="#FF0000">0xf000</font>,{1}lt;font color="#FF0000">0xfff0</font>

	.<font color="#2040a0">section</font> <font color="#008000">".bsdata"</font>, <font color="#008000">"a"</font> <font color="#444444">/* 链接时根据setup.ld,第二部分 */</font>
<font color="#2040a0">bugger_off_msg</font><font color="4444FF">:</font> <font color="#444444">/* 这是我们用来显示的提示字符串 */</font>
	.<font color="#2040a0">ascii</font>	<font color="#008000">"Direct booting from floppy is no longer supported.<font color="#77dd77">\r</font><font color="#77dd77">\n</font>"</font>
	.<font color="#2040a0">ascii</font>	<font color="#008000">"Please use a boot loader program instead.<font color="#77dd77">\r</font><font color="#77dd77">\n</font>"</font>
	.<font color="#2040a0">ascii</font>	<font color="#008000">"<font color="#77dd77">\n</font>"</font>
	.<font color="#2040a0">ascii</font>	<font color="#008000">"Remove disk and press any key to reboot . . .<font color="#77dd77">\r</font><font color="#77dd77">\n</font>"</font>
	.<font color="#2040a0">byte</font>	<font color="#FF0000">0</font>
<font color="0000ff"><strong>	# Kernel attributes; used by setup.  This is part 1 of the</strong></font>
<font color="0000ff"><strong>	# header, from the old boot sector.</strong></font>
	.<font color="#2040a0">section</font> <font color="#008000">".header"</font>, <font color="#008000">"a"</font> <font color="#444444">/* 链接时根据setup.ld,第三部分,指定从497字节的位置开始*/</font>
	.<font color="#2040a0">globl</font>	<font color="#2040a0">hdr</font>
<font color="#2040a0">hdr</font><font color="4444FF">:</font>
<font color="#2040a0">setup_sects</font><font color="4444FF">:</font>	.<font color="#2040a0">byte</font> <font color="#FF0000">0</font>			<font color="#444444">/* Filled in by build.c */</font>
<font color="#2040a0">root_flags</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font> <font color="#2040a0">ROOT_RDONLY</font>
<font color="#2040a0">syssize</font><font color="4444FF">:</font>	.<strong>long</strong> <font color="#FF0000">0</font>			<font color="#444444">/* Filled in by build.c */</font>
<font color="#2040a0">ram_size</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font> <font color="#FF0000">0</font>			<font color="#444444">/* Obsolete */</font>
<font color="#2040a0">vid_mode</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font> <font color="#2040a0">SVGA_MODE</font>
<font color="#2040a0">root_dev</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font> <font color="#FF0000">0</font>			<font color="#444444">/* Filled in by build.c */</font>
<font color="#2040a0">boot_flag</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font> <font color="#FF0000">0xAA55</font>

<font color="0000ff"><strong>	# offset 512, entry point</strong></font>
	.<font color="#2040a0">globl</font>	<font color="#2040a0">_start</font> <font color="#444444">/* 此处才是正常启动的内核执行的第一条指令 */</font>
<font color="#2040a0">_start</font><font color="4444FF">:</font>
<font color="0000ff"><strong>		# Explicitly enter this as bytes, or the assembler</strong></font>
<font color="0000ff"><strong>		# tries to generate a 3-byte jump here, which causes</strong></font>
<font color="0000ff"><strong>		# everything else to push off to the wrong offset.</strong></font>
		.<font color="#2040a0">byte</font>	<font color="#FF0000">0xeb</font>		# <strong>short</strong> <font color="4444FF">(</font><font color="#FF0000">2</font><font color="4444FF">-</font><font color="#2040a0">byte</font><font color="4444FF">)</font> <font color="#2040a0">jump</font>
		.<font color="#2040a0">byte</font>	<font color="#2040a0">start_of_setup</font><font color="4444FF">-</font><font color="#FF0000">1f</font> <font color="#444444">/* 这里是一个跳转地址,直接到下面的start_of_setup执行 */</font>
<font color="#FF0000">1</font><font color="4444FF">:</font>
<font color="#444444">/* 从这里到下面结束都是kernel boot sector的一些描述数据 */</font>
<font color="0000ff"><strong>	# Part 2 of the header, from the old setup.S</strong></font>

		.<font color="#2040a0">ascii</font>	<font color="#008000">"HdrS"</font>		# <font color="#2040a0">header</font> <font color="#2040a0">signature</font>
		.<font color="#2040a0">word</font>	<font color="#FF0000">0x020a</font>		# <font color="#2040a0">header</font> <font color="#2040a0">version</font> <font color="#2040a0">number</font> <font color="4444FF">(</font><font color="4444FF">></font><font color="4444FF">=</font> <font color="#FF0000">0x0105</font><font color="4444FF">)</font>
<font color="0000ff"><strong>					# or else old loadlin-1.5 will fail)</strong></font>
		.<font color="#2040a0">globl</font> <font color="#2040a0">realmode_swtch</font>
<font color="#2040a0">realmode_swtch</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font>	<font color="#FF0000">0</font>, <font color="#FF0000">0</font>		# <font color="#2040a0">default_switch</font>, <font color="#2040a0">SETUPSEG</font>
<font color="#2040a0">start_sys_seg</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font>	<font color="#2040a0">SYSSEG</font>		# <font color="#2040a0">obsolete</font> <font color="#2040a0">and</font> <font color="#2040a0">meaningless</font>, <font color="#2040a0">but</font> <font color="#2040a0">just</font>
<font color="0000ff"><strong>					# in case something decided to <font color="#008000">"use"</font> it</strong></font>
		.<font color="#2040a0">word</font>	<font color="#2040a0">kernel_version</font><font color="4444FF">-</font><font color="#FF0000">512</font> # <font color="#2040a0">pointing</font> <font color="#2040a0">to</font> <font color="#2040a0">kernel</font> <font color="#2040a0">version</font> <font color="#2040a0">string</font>
<font color="0000ff"><strong>					# above section of header is compatible</strong></font>
<font color="0000ff"><strong>					# with loadlin-1.5 (header v1.5). Don't</strong></font>
<font color="0000ff"><strong>					# change it.</strong></font>

<font color="#2040a0">type_of_loader</font><font color="4444FF">:</font>	.<font color="#2040a0">byte</font>	<font color="#FF0000">0</font>		# <font color="#FF0000">0</font> <font color="#2040a0">means</font> <font color="#2040a0">ancient</font> <font color="#2040a0">bootloader</font>, <font color="#2040a0">newer</font>
<font color="0000ff"><strong>					# bootloaders know to change this.</strong></font>
<font color="0000ff"><strong>					# See Documentation/i386/boot.txt for</strong></font>
<font color="0000ff"><strong>					# assigned ids</strong></font>

<font color="0000ff"><strong># flags, unused bits must be zero (RFU) bit within loadflags</strong></font>
<font color="#2040a0">loadflags</font><font color="4444FF">:</font>
<font color="#2040a0">LOADED_HIGH</font>	<font color="4444FF">=</font> <font color="#FF0000">1</font>			# <font color="#2040a0">If</font> <font color="#2040a0">set</font>, <font color="#2040a0">the</font> <font color="#2040a0">kernel</font> <font color="#2040a0">is</font> <font color="#2040a0">loaded</font> <font color="#2040a0">high</font>
<font color="#2040a0">CAN_USE_HEAP</font>	<font color="4444FF">=</font> <font color="#FF0000">0x80</font>			# <font color="#2040a0">If</font> <font color="#2040a0">set</font>, <font color="#2040a0">the</font> <font color="#2040a0">loader</font> <font color="#2040a0">also</font> <font color="#2040a0">has</font> <font color="#2040a0">set</font>
<font color="0000ff"><strong>					# heap_end_ptr to tell how much</strong></font>
<font color="0000ff"><strong>					# space behind setup.S can be used for</strong></font>
<font color="0000ff"><strong>					# heap purposes.</strong></font>
<font color="0000ff"><strong>					# Only the loader knows what is free</strong></font>
		.<font color="#2040a0">byte</font>	<font color="#2040a0">LOADED_HIGH</font>

<font color="#2040a0">setup_move_size</font><font color="4444FF">:</font> .<font color="#2040a0">word</font>  <font color="#FF0000">0x8000</font>		# <font color="#2040a0">size</font> <font color="#2040a0">to</font> <font color="#2040a0">move</font>, <font color="#2040a0">when</font> <font color="#2040a0">setup</font> <font color="#2040a0">is</font> <font color="#2040a0">not</font>
<font color="0000ff"><strong>					# loaded at 0x90000. We will move setup</strong></font>
<font color="0000ff"><strong>					# to 0x90000 then just before jumping</strong></font>
<font color="0000ff"><strong>					# into the kernel. However, only the</strong></font>
<font color="0000ff"><strong>					# loader knows how much data behind</strong></font>
<font color="0000ff"><strong>					# us also needs to be loaded.</strong></font>

<font color="#2040a0">code32_start</font><font color="4444FF">:</font>				# <font color="#2040a0">here</font> <font color="#2040a0">loaders</font> <font color="#2040a0">can</font> <font color="#2040a0">put</font> <font color="#2040a0">a</font> <font color="#2040a0">different</font>
<font color="0000ff"><strong>					# start address for 32-bit code.</strong></font>
		.<strong>long</strong>	<font color="#FF0000">0x100000</font>	# <font color="#FF0000">0x100000</font> <font color="4444FF">=</font> <strong>default</strong> <strong>for</strong> <font color="#2040a0">big</font> <font color="#2040a0">kernel</font>

<font color="#2040a0">ramdisk_image</font><font color="4444FF">:</font>	.<strong>long</strong>	<font color="#FF0000">0</font>		# <font color="#2040a0">address</font> <font color="#2040a0">of</font> <font color="#2040a0">loaded</font> <font color="#2040a0">ramdisk</font> <font color="#2040a0">image</font>
<font color="0000ff"><strong>					# Here the loader puts the 32-bit</strong></font>
<font color="0000ff"><strong>					# address where it loaded the image.</strong></font>
<font color="0000ff"><strong>					# This only will be read by the kernel.</strong></font>

<font color="#2040a0">ramdisk_size</font><font color="4444FF">:</font>	.<strong>long</strong>	<font color="#FF0000">0</font>		# <font color="#2040a0">its</font> <font color="#2040a0">size</font> <font color="#2040a0">in</font> <font color="#2040a0">bytes</font>

<font color="#2040a0">bootsect_kludge</font><font color="4444FF">:</font>
		.<strong>long</strong>	<font color="#FF0000">0</font>		# <font color="#2040a0">obsolete</font>

<font color="#2040a0">heap_end_ptr</font><font color="4444FF">:</font>	.<font color="#2040a0">word</font>	<font color="#2040a0">_end</font><font color="4444FF">+</font><font color="#2040a0">STACK_SIZE</font><font color="4444FF">-</font><font color="#FF0000">512</font>
<font color="0000ff"><strong>					# (Header version 0x0201 or later)</strong></font>
<font color="0000ff"><strong>					# space from here (exclusive) down to</strong></font>
<font color="0000ff"><strong>					# end of setup code can be used by setup</strong></font>
<font color="0000ff"><strong>					# for local heap purposes.</strong></font>

<font color="#2040a0">ext_loader_ver</font><font color="4444FF">:</font>
		.<font color="#2040a0">byte</font>	<font color="#FF0000">0</font>		# <font color="#2040a0">Extended</font> <font color="#2040a0">boot</font> <font color="#2040a0">loader</font> <font color="#2040a0">version</font>
<font color="#2040a0">ext_loader_type</font><font color="4444FF">:</font>
		.<font color="#2040a0">byte</font>	<font color="#FF0000">0</font>		# <font color="#2040a0">Extended</font> <font color="#2040a0">boot</font> <font color="#2040a0">loader</font> <font color="#2040a0">type</font>

<font color="#2040a0">cmd_line_ptr</font><font color="4444FF">:</font>	.<strong>long</strong>	<font color="#FF0000">0</font>		# <font color="4444FF">(</font><font color="#2040a0">Header</font> <font color="#2040a0">version</font> <font color="#FF0000">0x0202</font> <font color="#2040a0">or</font> <font color="#2040a0">later</font><font color="4444FF">)</font>
<font color="0000ff"><strong>					# If nonzero, a 32-bit pointer</strong></font>
<font color="0000ff"><strong>					# to the kernel command line.</strong></font>
<font color="0000ff"><strong>					# The command line should be</strong></font>
<font color="0000ff"><strong>					# located between the start of</strong></font>
<font color="0000ff"><strong>					# setup and the end of low</strong></font>
<font color="0000ff"><strong>					# memory (0xa0000), or it may</strong></font>
<font color="0000ff"><strong>					# get overwritten before it</strong></font>
<font color="0000ff"><strong>					# gets read.  If this field is</strong></font>
<font color="0000ff"><strong>					# used, there is no longer</strong></font>
<font color="0000ff"><strong>					# anything magical about the</strong></font>
<font color="0000ff"><strong>					# 0x90000 segment; the setup</strong></font>
<font color="0000ff"><strong>					# can be located anywhere in</strong></font>
<font color="0000ff"><strong>					# low memory 0x10000 or higher.</strong></font>

<font color="#2040a0">ramdisk_max</font><font color="4444FF">:</font>	.<strong>long</strong> <font color="#FF0000">0x7fffffff</font>
<font color="0000ff"><strong>					# (Header version 0x0203 or later)</strong></font>
<font color="0000ff"><strong>					# The highest safe address for</strong></font>
<font color="0000ff"><strong>					# the contents of an initrd</strong></font>
<font color="0000ff"><strong>					# The current kernel allows up to 4 GB,</strong></font>
<font color="0000ff"><strong>					# but leave it at 2 GB to avoid</strong></font>
<font color="0000ff"><strong>					# possible bootloader bugs.</strong></font>

<font color="#2040a0">kernel_alignment</font><font color="4444FF">:</font>  .<strong>long</strong> <font color="#2040a0">CONFIG_PHYSICAL_ALIGN</font>	#<font color="#2040a0">physical</font> <font color="#2040a0">addr</font> <font color="#2040a0">alignment</font>
<font color="0000ff"><strong>						#required for protected mode</strong></font>
<font color="0000ff"><strong>						#kernel</strong></font>
<font color="0000ff"><strong>#ifdef CONFIG_RELOCATABLE</strong></font>
<font color="#2040a0">relocatable_kernel</font><font color="4444FF">:</font>    .<font color="#2040a0">byte</font> <font color="#FF0000">1</font>
<font color="0000ff"><strong>#else</strong></font>
<font color="#2040a0">relocatable_kernel</font><font color="4444FF">:</font>    .<font color="#2040a0">byte</font> <font color="#FF0000">0</font>
<font color="0000ff"><strong>#endif</strong></font>
<font color="#2040a0">min_alignment</font><font color="4444FF">:</font>		.<font color="#2040a0">byte</font> <font color="#2040a0">MIN_KERNEL_ALIGN_LG2</font>	# <font color="#2040a0">minimum</font> <font color="#2040a0">alignment</font>
<font color="#2040a0">pad3</font><font color="4444FF">:</font>			.<font color="#2040a0">word</font> <font color="#FF0000">0</font>

<font color="#2040a0">cmdline_size</font><font color="4444FF">:</font>   .<strong>long</strong>   <font color="#2040a0">COMMAND_LINE_SIZE</font><font color="4444FF">-</font><font color="#FF0000">1</font>     #<font color="#2040a0">length</font> <font color="#2040a0">of</font> <font color="#2040a0">the</font> <font color="#2040a0">command</font> <font color="#2040a0">line</font>,
<font color="0000ff"><strong>                                                #added with boot protocol</strong></font>
<font color="0000ff"><strong>                                                #version 2.06</strong></font>

<font color="#2040a0">hardware_subarch</font><font color="4444FF">:</font>	.<strong>long</strong> <font color="#FF0000">0</font>		# <font color="#2040a0">subarchitecture</font>, <font color="#2040a0">added</font> <font color="#2040a0">with</font> <font color="#FF0000">2.07</font>
<font color="0000ff"><strong>						# default to 0 for normal x86 PC</strong></font>

<font color="#2040a0">hardware_subarch_data</font><font color="4444FF">:</font>	.<font color="#2040a0">quad</font> <font color="#FF0000">0</font>

<font color="#2040a0">payload_offset</font><font color="4444FF">:</font>		.<strong>long</strong> <font color="#2040a0">ZO_input_data</font>
<font color="#2040a0">payload_length</font><font color="4444FF">:</font>		.<strong>long</strong> <font color="#2040a0">ZO_z_input_len</font>

<font color="#2040a0">setup_data</font><font color="4444FF">:</font>		.<font color="#2040a0">quad</font> <font color="#FF0000">0</font>			# <font color="#FF0000">64</font><font color="4444FF">-</font><font color="#2040a0">bit</font> <font color="#2040a0">physical</font> <font color="#2040a0">pointer</font> <font color="#2040a0">to</font>
<font color="0000ff"><strong>						# single linked list of</strong></font>
<font color="0000ff"><strong>						# struct setup_data</strong></font>

<font color="#2040a0">pref_address</font><font color="4444FF">:</font>		.<font color="#2040a0">quad</font> <font color="#2040a0">LOAD_PHYSICAL_ADDR</font>	# <font color="#2040a0">preferred</font> <font color="#2040a0">load</font> <font color="#2040a0">addr</font>

<font color="0000ff"><strong>#define ZO_INIT_SIZE	(ZO__end - ZO_startup_32 + ZO_z_extract_offset)</strong></font>
<font color="0000ff"><strong>#define VO_INIT_SIZE	(VO__end - VO__text)</strong></font>
<font color="0000ff"><strong>#if ZO_INIT_SIZE > VO_INIT_SIZE</strong></font>
<font color="0000ff"><strong>#define INIT_SIZE ZO_INIT_SIZE</strong></font>
<font color="0000ff"><strong>#else</strong></font>
<font color="0000ff"><strong>#define INIT_SIZE VO_INIT_SIZE</strong></font>
<font color="0000ff"><strong>#endif</strong></font>
<font color="#2040a0">init_size</font><font color="4444FF">:</font>		.<strong>long</strong> <font color="#2040a0">INIT_SIZE</font>		# <font color="#2040a0">kernel</font> <font color="#2040a0">initialization</font> <font color="#2040a0">size</font>

<font color="0000ff"><strong># End of setup header #####################################################</strong></font>

	.<font color="#2040a0">section</font> <font color="#008000">".entrytext"</font>, <font color="#008000">"ax"</font> <font color="#444444">/* 链接时根据setup.ld,第四部分 */</font>
<font color="#2040a0">start_of_setup</font><font color="4444FF">:</font> <font color="#444444">/* 从上面跳到这里执行 */</font>
<font color="0000ff"><strong>#ifdef SAFE_RESET_DISK_CONTROLLER</strong></font>
<font color="0000ff"><strong># Reset the disk controller.</strong></font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#FF0000">0x0000</font>, <font color="4444FF">%</font><font color="#2040a0">ax</font>	<font color="#444444">/* 磁盘中断的调用号0 -> al,功能是磁盘分复位 */</font># <font color="#2040a0">Reset</font> <font color="#2040a0">disk</font> <font color="#2040a0">controller</font>
	<font color="#2040a0">movb</font>	{1}lt;font color="#FF0000">0x80</font>, <font color="4444FF">%</font><font color="#2040a0">dl</font>	<font color="#444444">/* 指定所有的驱动器 */</font>	# <font color="#2040a0">All</font> <font color="#2040a0">disks</font>
	<strong>int</strong>	{1}lt;font color="#FF0000">0x13</font>		<font color="#444444">/* 进入BIOS 13H,磁盘中断服务 */</font>
<font color="0000ff"><strong>#endif</strong></font>
<font color="0000ff"><strong># Force %es = %ds</strong></font>
	<font color="#2040a0">movw</font>	<font color="4444FF">%</font><font color="#2040a0">ds</font>, <font color="4444FF">%</font><font color="#2040a0">ax</font>
	<font color="#2040a0">movw</font>	<font color="4444FF">%</font><font color="#2040a0">ax</font>, <font color="4444FF">%</font><font color="#2040a0">es</font>
	<font color="#2040a0">cld</font>
<font color="0000ff"><strong># Apparently some ancient versions of LILO invoked the kernel with %ss != %ds,</strong></font>
<font color="0000ff"><strong># which happened to work by accident for the old code.  Recalculate the stack</strong></font>
<font color="0000ff"><strong># pointer if %ss is invalid.  Otherwise leave it alone, LOADLIN sets up the</strong></font>
<font color="0000ff"><strong># stack behind its own code, so we can't blindly put it directly past the heap.</strong></font>

	<font color="#2040a0">movw</font>	<font color="4444FF">%</font><font color="#2040a0">ss</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>	<font color="#444444">/* 一些引导程序并没有设置正确的堆栈,此处要初始化一个堆栈 */</font>
	<font color="#2040a0">cmpw</font>	<font color="4444FF">%</font><font color="#2040a0">ax</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>	# <font color="4444FF">%</font><font color="#2040a0">ds</font> <font color="4444FF">=</font><font color="4444FF">=</font> <font color="4444FF">%</font><font color="#2040a0">ss</font>? <font color="#444444">/* 上面执行当中%ax为%ds值,%dx为%ss值,然后比较是否相等 */</font>
	<font color="#2040a0">movw</font>	<font color="4444FF">%</font><font color="#2040a0">sp</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>
	<font color="#2040a0">je</font>	<font color="#FF0000">2f</font>		<font color="#444444">/* 如果相等,向前跳转到标号2处执行 */</font># <font color="4444FF">-</font><font color="4444FF">></font> <font color="#2040a0">assume</font> <font color="4444FF">%</font><font color="#2040a0">sp</font> <font color="#2040a0">is</font> <font color="#2040a0">reasonably</font> <font color="#2040a0">set</font>

<font color="0000ff"><strong>	# Invalid %ss, make up a new stack<font color="#444444"> /* 否则堆栈段和数据段不相等 */</font></strong></font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#2040a0">_end</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>	<font color="#444444">/* 这里_end是实模式代码的结束,_end之后就是stack/heap */</font>
	<font color="#2040a0">testb</font>	{1}lt;font color="#2040a0">CAN_USE_HEAP</font>, <font color="#2040a0">loadflags</font> <font color="#444444">/* 测试loadflags的某个位,是否使用heap */</font>
	<font color="#2040a0">jz</font>	<font color="#FF0000">1f</font>		<font color="#444444">/* 如果不使用,则向前到1标号处执行 */</font>
	<font color="#2040a0">movw</font>	<font color="#2040a0">heap_end_ptr</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font> <font color="#444444">/* 否则,在heap之后,再建立stack */</font>
<font color="#FF0000">1</font><font color="4444FF">:</font>	<font color="#2040a0">addw</font>	{1}lt;font color="#2040a0">STACK_SIZE</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font> <font color="#444444">/* %dx向上增长STACK_SIZE大小 */</font>
	<font color="#2040a0">jnc</font>	<font color="#FF0000">2f</font> <font color="#444444">/* 无进位转移到标号2处 */</font>
	<font color="#2040a0">xorw</font>	<font color="4444FF">%</font><font color="#2040a0">dx</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>	# <font color="#2040a0">Prevent</font> <font color="#2040a0">wraparound</font> <font color="#444444">/* 有进位,清零 */</font>

<font color="#FF0000">2</font><font color="4444FF">:</font>	# <font color="#2040a0">Now</font> <font color="4444FF">%</font><font color="#2040a0">dx</font> <font color="#2040a0">should</font> <font color="#2040a0">point</font> <font color="#2040a0">to</font> <font color="#2040a0">the</font> <font color="#2040a0">end</font> <font color="#2040a0">of</font> <font color="#2040a0">our</font> <font color="#2040a0">stack</font> <font color="#2040a0">space</font><font color="#444444">/* 通过上面的运算,%dx指向实模式堆栈的尾端 */</font>
	<font color="#2040a0">andw</font>	$~<font color="#FF0000">3</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>	<font color="#444444">/* 清%dx的低四位,四字节对齐 */</font># <font color="#2040a0">dword</font> <font color="#2040a0">align</font> <font color="4444FF">(</font><font color="#2040a0">might</font> <font color="#2040a0">as</font> <font color="#2040a0">well</font>...<font color="4444FF">)</font>
	<font color="#2040a0">jnz</font>	<font color="#FF0000">3f</font>		<font color="#444444">/* %dx指向正确堆栈结尾情况下,跳到3标号处执行 */</font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#FF0000">0xfffc</font>, <font color="4444FF">%</font><font color="#2040a0">dx</font>	# <font color="#2040a0">Make</font> <font color="#2040a0">sure</font> <font color="#2040a0">we</font>'<font color="#2040a0">re</font> <font color="#2040a0">not</font> <font color="#2040a0">zero</font>
<font color="#FF0000">3</font><font color="4444FF">:</font>	<font color="#2040a0">movw</font>	<font color="4444FF">%</font><font color="#2040a0">ax</font>, <font color="4444FF">%</font><font color="#2040a0">ss</font>
	<font color="#2040a0">movzwl</font>	<font color="4444FF">%</font><font color="#2040a0">dx</font>, <font color="4444FF">%</font><font color="#2040a0">esp</font>	<font color="#444444">/* 按零扩展数据传送,%esp的左边位用0填充 */</font># <font color="#2040a0">Clear</font> <font color="#2040a0">upper</font> <font color="#2040a0">half</font> <font color="#2040a0">of</font> <font color="4444FF">%</font><font color="#2040a0">esp</font>
	<font color="#2040a0">sti</font>			<font color="#444444">/* 到此,堆栈准备好,%esp指向正确的位置 */</font># <font color="#2040a0">Now</font> <font color="#2040a0">we</font> <font color="#2040a0">should</font> <font color="#2040a0">have</font> <font color="#2040a0">a</font> <font color="#2040a0">working</font> <font color="#2040a0">stack</font>

<font color="0000ff"><strong># We will have entered with %cs = %ds+0x20, normalize %cs so</strong></font>
<font color="0000ff"><strong># it is on par with the other segments.</strong></font>
	<font color="#2040a0">pushw</font>	<font color="4444FF">%</font><font color="#2040a0">ds</font>
	<font color="#2040a0">pushw</font>	{1}lt;font color="#FF0000">6f</font>
	<font color="#2040a0">lretw</font>
<font color="#FF0000">6</font><font color="4444FF">:</font>

<font color="0000ff"><strong># Check signature at end of setup</strong></font>
	<font color="#2040a0">cmpl</font>	{1}lt;font color="#FF0000">0x5a5aaa55</font>, <font color="#2040a0">setup_sig</font> <font color="#444444">/* 比较结尾签名是否正确 */</font>
	<font color="#2040a0">jne</font>	<font color="#2040a0">setup_bad</font>

<font color="0000ff"><strong># Zero the bss<font color="#444444"> /* 初始化bss段 */</font></strong></font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#2040a0">__bss_start</font>, <font color="4444FF">%</font><font color="#2040a0">di</font>
	<font color="#2040a0">movw</font>	{1}lt;font color="#2040a0">_end</font><font color="4444FF">+</font><font color="#FF0000">3</font>, <font color="4444FF">%</font><font color="#2040a0">cx</font>
	<font color="#2040a0">xorl</font>	<font color="4444FF">%</font><font color="#2040a0">eax</font>, <font color="4444FF">%</font><font color="#2040a0">eax</font>
	<font color="#2040a0">subw</font>	<font color="4444FF">%</font><font color="#2040a0">di</font>, <font color="4444FF">%</font><font color="#2040a0">cx</font>
	<font color="#2040a0">shrw</font>	{1}lt;font color="#FF0000">2</font>, <font color="4444FF">%</font><font color="#2040a0">cx</font>
	<font color="#2040a0">rep</font><font color="4444FF">;</font> <font color="#2040a0">stosl</font>

<font color="0000ff"><strong># Jump to C code (should not return)</strong></font>
	<font color="#2040a0">calll</font>	<font color="#2040a0">main</font> <font color="#444444">/* 长调用,在当前目录的main.c文件当中,main的原型是void main(void),无参数,无返回值 */</font>

<font color="0000ff"><strong># Setup corrupt somehow...</strong></font>
<font color="#2040a0">setup_bad</font><font color="4444FF">:</font>
	<font color="#2040a0">movl</font>	{1}lt;font color="#2040a0">setup_corrupt</font>, <font color="4444FF">%</font><font color="#2040a0">eax</font> <font color="#444444">/* 准备要显示的错误信息 */</font>
	<font color="#2040a0">calll</font>	<font color="#2040a0">puts</font> <font color="#444444">/* 调用puts显示信息 */</font>
<font color="0000ff"><strong>	# Fall through...</strong></font>

	.<font color="#2040a0">globl</font>	<font color="#2040a0">die</font>
	.<font color="#2040a0">type</font>	<font color="#2040a0">die</font>, @<font color="#2040a0">function</font>
<font color="#2040a0">die</font><font color="4444FF">:</font>
	<font color="#2040a0">hlt</font>		<font color="#444444">/* 停机,暂停后面指令的执行,暂时没有用上 */</font>
	<font color="#2040a0">jmp</font>	<font color="#2040a0">die</font>

	.<font color="#2040a0">size</font>	<font color="#2040a0">die</font>, .<font color="4444FF">-</font><font color="#2040a0">die</font>

	.<font color="#2040a0">section</font> <font color="#008000">".initdata"</font>, <font color="#008000">"a"</font> <font color="#444444">/* 另一个数据段,链接时根据setup.ld,第六部分 */</font>
<font color="#2040a0">setup_corrupt</font><font color="4444FF">:</font>
	.<font color="#2040a0">byte</font>	<font color="#FF0000">7</font>
	.<font color="#2040a0">string</font>	<font color="#008000">"No setup signature found...<font color="#77dd77">\n</font>"</font>

</pre>
<hr>
syntax highlighted by <a href="http://www.palfrader.org/code2html">Code2HTML</a>, v. 0.9.1
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值