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

📄 runkernel.inc

📁 linux内核
💻 INC
📖 第 1 页 / 共 2 页
字号:
;; $Id$;; -----------------------------------------------------------------------;;   ;;   Copyright 1994-2005 H. Peter Anvin - All Rights Reserved;;;;   This program is free software; you can redistribute it and/or modify;;   it under the terms of the GNU General Public License as published by;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,;;   Boston MA 02111-1307, USA; either version 2 of the License, or;;   (at your option) any later version; incorporated herein by reference.;;;; -----------------------------------------------------------------------;;;; runkernel.inc;; ;; Common code for running a Linux kernel;;;; Hook macros, that may or may not be defined;%ifndef HAVE_SPECIAL_APPEND%macro SPECIAL_APPEND 0%endmacro%endif%ifndef HAVE_UNLOAD_PREP%macro UNLOAD_PREP 0%endmacro%endif;; A Linux kernel consists of three parts: boot sector, setup code, and; kernel code.	The boot sector is never executed when using an external; booting utility, but it contains some status bytes that are necessary.;; First check that our kernel is at least 1K and less than 8M (if it is; more than 8M, we need to change the logic for loading it anyway...);; We used to require the kernel to be 64K or larger, but it has gotten; popular to use the Linux kernel format for other things, which may; not be so large.;is_linux_kernel:                cmp dx,80h			; 8 megs		ja kernel_corrupt		and dx,dx		jnz kernel_sane		cmp ax,1024			; Bootsect + 1 setup sect		jb kernel_corruptkernel_sane:	push ax		push dx		push si		mov si,loading_msg                call cwritestr;; Now start transferring the kernel;		push word real_mode_seg		pop es		movzx eax,ax			; Fix this by using a 32-bit		shl edx,16			; register for the kernel size		or eax,edx		mov [KernelSize],eax		add eax,SECTOR_SIZE-1		shr eax,SECTOR_SHIFT                mov [KernelSects],eax		; Total sectors in kernel;; Now, if we transfer these straight, we'll hit 64K boundaries.	 Hence we; have to see if we're loading more than 64K, and if so, load it step by; step.;;; Start by loading the bootsector/setup code, to see if we need to; do something funky.  It should fit in the first 32K (loading 64K won't; work since we might have funny stuff up near the end of memory).; If we have larger than 32K clusters, yes, we're hosed.;		call abort_check		; Check for abort key		mov ecx,8000h >> SECTOR_SHIFT	; Half a moby (32K)		cmp ecx,[KernelSects]		jna .normalkernel		mov ecx,[KernelSects].normalkernel:		sub [KernelSects],ecx		xor bx,bx                pop si                          ; Cluster pointer on stack		call getfssec                cmp word [es:bs_bootsign],0AA55h		jne kernel_corrupt		; Boot sec signature missing;; Save the cluster pointer for later...;		push si;; Get the BIOS' idea of what the size of high memory is.;		call highmemsize;; Construct the command line (append options have already been copied);construct_cmdline:		mov di,[CmdLinePtr]                mov si,boot_image        	; BOOT_IMAGE=                mov cx,boot_image_len                rep movsb                mov si,KernelCName       	; Unmangled kernel name                mov cx,[KernelCNameLen]                rep movsb                mov al,' '                      ; Space                stosb		SPECIAL_APPEND			; Module-specific hook                mov si,[CmdOptPtr]              ; Options from user input		call strcpy;; Scan through the command line for anything that looks like we might be; interested in.  The original version of this code automatically assumed; the first option was BOOT_IMAGE=, but that is no longer certain.;		mov si,cmd_line_here		xor ax,ax                mov [InitRDPtr],ax		; No initrd= option (yet)                push es				; Set DS <- real_mode_seg                pop dsget_next_opt:   lodsb		and al,al		jz cmdline_end		cmp al,' '		jbe get_next_opt		dec si                mov eax,[si]                cmp eax,'vga='		je is_vga_cmd                cmp eax,'mem='		je is_mem_cmd%if IS_PXELINUX		cmp eax,'keep'			; Is it "keeppxe"?		jne .notkeep		cmp dword [si+3],'ppxe'		jne .notkeep		cmp byte [si+7],' '		; Must be whitespace or EOS		ja .notkeep		or byte [cs:KeepPXE],1.notkeep:%endif                push es                         ; Save ES -> real_mode_seg                push cs                pop es                          ; Set ES <- normal DS                mov di,initrd_cmd		mov cx,initrd_cmd_len		repe cmpsb                jne .not_initrd		cmp al,' '		jbe .noramdisk		mov [cs:InitRDPtr],si		jmp .not_initrd.noramdisk:		xor ax,ax		mov [cs:InitRDPtr],ax.not_initrd:	pop es                          ; Restore ES -> real_mode_segskip_this_opt:  lodsb                           ; Load from command line                cmp al,' '                ja skip_this_opt                dec si                jmp short get_next_optis_vga_cmd:                add si,4                mov eax,[si-1]                mov bx,-1                cmp eax,'=nor'			; vga=normal                je vc0		dec bx				; bx <- -2                cmp eax,'=ext'			; vga=ext                je vc0                dec bx				; bx <- -3                cmp eax,'=ask'			; vga=ask                je vc0                call parseint                   ; vga=<number>		jc skip_this_opt		; Not an integervc0:		mov [bs_vidmode],bx		; Set video mode		jmp short skip_this_optis_mem_cmd:                add si,4                call parseint		jc skip_this_opt		; Not an integer%if HIGHMEM_SLOP != 0		sub ebx,HIGHMEM_SLOP%endif		mov [cs:HighMemSize],ebx		jmp short skip_this_optcmdline_end:                push cs                         ; Restore standard DS                pop ds		sub si,cmd_line_here		mov [CmdLineLen],si		; Length including final null;; Now check if we have a large kernel, which needs to be loaded high;		mov dword [RamdiskMax], HIGHMEM_MAX	; Default initrd limit		cmp dword [es:su_header],HEADER_ID	; New setup code ID		jne old_kernel		; Old kernel, load low		cmp word [es:su_version],0200h	; Setup code version 2.0		jb old_kernel		; Old kernel, load low                cmp word [es:su_version],0201h	; Version 2.01+?                jb new_kernel                   ; If 2.00, skip this step                mov word [es:su_heapend],linux_stack	; Set up the heap                or byte [es:su_loadflags],80h	; Let the kernel know we care		cmp word [es:su_version],0203h	; Version 2.03+?		jb new_kernel			; Not 2.03+		mov eax,[es:su_ramdisk_max]		mov [RamdiskMax],eax		; Set the ramdisk limit;; We definitely have a new-style kernel.  Let the kernel know who we are,; and that we are clueful;new_kernel:		mov byte [es:su_loader],my_id	; Show some ID		movzx ax,byte [es:bs_setupsecs]	; Variable # of setup sectors		mov [SetupSecs],ax		xor eax,eax		mov [es:su_ramdisklen],eax	; No initrd loaded yet;; About to load the kernel.  This is a modern kernel, so use the boot flags; we were provided.;                mov al,[es:su_loadflags]		mov [LoadFlags],al;; Load the kernel.  We always load it at 100000h even if we're supposed to; load it "low"; for a "low" load we copy it down to low memory right before; jumping to it.;read_kernel:                mov si,KernelCName		; Print kernel name part of                call cwritestr                  ; "Loading" message                mov si,dotdot_msg		; Print dots                call cwritestr                mov eax,[HighMemSize]		sub eax,100000h			; Load address		cmp eax,[KernelSize]		jb no_high_mem		; Not enough high memory;; Move the stuff beyond the setup code to high memory at 100000h;		movzx esi,word [SetupSecs]	; Setup sectors		inc si				; plus 1 boot sector                shl si,9			; Convert to bytes                mov ecx,8000h			; 32K		sub ecx,esi			; Number of bytes to copy		push ecx		add esi,(real_mode_seg << 4)	; Pointer to source                mov edi,100000h                 ; Copy to address 100000h                call bcopy			; Transfer to high memory		; On exit EDI -> where to load the rest                mov si,dot_msg			; Progress report                call cwritestr                call abort_check		pop ecx				; Number of bytes in the initial portion		pop si				; Restore file handle/cluster pointer		mov eax,[KernelSize]		sub eax,8000h			; Amount of kernel not yet loaded		jbe high_load_done		; Zero left (tiny kernel)		xor dx,dx			; No padding needed		call load_high			; Copy the filehigh_load_done:		mov [KernelEnd],edi                mov ax,real_mode_seg		; Set to real mode seg                mov es,ax                mov si,dot_msg                call cwritestr;; Now see if we have an initial RAMdisk; if so, do requisite computation; We know we have a new kernel; the old_kernel code already will have objected; if we tried to load initrd using an old kernel;load_initrd:                cmp word [InitRDPtr],0                jz nk_noinitrd		call parse_load_initrdnk_noinitrd:;; Abandon hope, ye that enter here!  We do no longer permit aborts.;                call abort_check        	; Last chance!!		mov si,ready_msg		call cwritestr		call vgaclearmode		; We can't trust ourselves after this		UNLOAD_PREP			; Module-specific hook;; Now, if we were supposed to load "low", copy the kernel down to 10000h; and the real mode stuff to 90000h.  We assume that all bzImage kernels are; capable of starting their setup from a different address.;		mov ax,real_mode_seg

⌨️ 快捷键说明

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