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

📄 ldlinux.asm

📁 这是Linux环境下的bootsyslinux-1.31版本
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		mov [CmdLinePtr],di		; Where to add rest of cmd		pop es                pop di                          ; DI -> KernelName		push di			mov si,VKernelBuf+vk_rname		mov cx,11		rep movsb		pop di		jmp short get_kernel;; kernel_corrupt: Called if the kernel file does not seem healthy;kernel_corrupt: mov si,err_notkernel                jmp abort_loadkernel_good:;; This is it!  We have a name (and location on the disk)... let's load; that sucker!!;; 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.; The boot sector and setup code together form exactly 5 sectors that; should be loaded at 9000:0.  The subsequent code should be loaded; at 1000:0.  For simplicity, we load the whole thing at 0F60:0, and; copy the latter stuff afterwards.;; NOTE: In the previous code I have avoided making any assumptions regarding; the size of a sector, in case this concept ever gets extended to other; media like CD-ROM (not that a CD-ROM would be bloody likely to use a FAT; filesystem, of course).  However, a "sector" when it comes to Linux booting; stuff means 512 bytes *no matter what*, so here I am using that piece; of knowledge.;; First check that our kernel is at least 64K and less than 8M (if it is; more than 8M, we need to change the logic for loading it anyway...);load_it:                cmp dx,80h			; 8 megs		ja kernel_corrupt		and dx,dx		jz 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		push ax		push dx		div word [ClustSize]		; # of clusters total		and dx,dx			; Round up		setnz dl		movzx dx,dl		add ax,dx                mov [KernelClust],ax		pop dx		pop ax		add ax,1023		adc dx,byte 0		mov bx,1024		div bx				; Get number of kilobytes		mov [KernelK],ax;; 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.;		mov dx,1			; 10000h		xor ax,ax		div word [ClustSize]		mov [ClustPerMoby],ax		; Clusters/64K;; 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 cx,[ClustPerMoby]		shr cx,1			; Half a moby		sub [KernelClust],cx		xor bx,bx                pop si                          ; Cluster pointer on stack		call getfssec		jc kernel_corrupt		; Failure in first 32K                cmp word [es:bs_bootsign],0AA55h		jne kernel_corrupt		; Boot sec signature missing		cmp byte [es:su_jump],0EBh	; Jump opcode		jne kernel_corrupt;; Get the BIOS' idea of what the size of high memory is;		push si				; Save our cluster pointer!		mov ah,88h		int 15h		cmp ax,14*1024			; Don't trust memory >15M		jna hms_ok		mov ax,14*1024hms_ok:		mov [HighMemSize],ax;; Construct the command line (append options have already been copied);		mov word [es:kern_cmd_magic],0A33Fh	; Command line magic no		mov word [es:kern_cmd_offset],cmd_line_here		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                mov si,[CmdOptPtr]              ; Options from user input		mov cx,(kern_cmd_len+3) >> 2		rep movsd;%ifdef debug                push ds                         ; DEBUG DEBUG DEBUG                push es                pop ds                mov si,offset cmd_line_here                call cwritestr                pop ds                mov si,offset crlf                call cwritestr%endif;; 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                mov byte [initrd_flag],0                push es                pop dsget_next_opt:   lodsb		and al,al		jz near 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                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		mov di,InitRD                push si                         ; mangle_dir mangles si                call mangle_name                ; Mangle ramdisk name                pop si		cmp byte [es:InitRD],' '	; Null filename?                seta byte [es:initrd_flag]	; Set flag if notnot_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,byte 4                mov eax,[si]                mov bx,-1                cmp eax, 'norm'                 ; vga=normal                je vc0                and eax,0ffffffh		; 3 bytes                mov bx,-2                cmp eax, 'ext'                  ; vga=ext                je vc0                mov 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,byte 4                call parseint		jc skip_this_opt		; Not an integer		shr ebx,10			; Convert to kilobytes                sub ebx,1024                    ; Don't count first meg		cmp ebx,14*1024			; Only trust < 15M point                jna memcmd_fair		mov bx,14*1024memcmd_fair:    mov [es:HighMemSize],bx		jmp short skip_this_optcmdline_end:                push cs                         ; Restore standard DS                pop ds;; Now check if we have a large kernel, which needs to be loaded high;		cmp dword [es:su_header],HEADER_ID	; New setup code ID		jne near old_kernel		; Old kernel, load low		cmp word [es:su_version],0200h	; Setup code version 2.0		jb near 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 cared;; 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],syslinux_id	; Show some ID		movzx ax,byte [es:bs_setupsecs]	; Variable # of setup sectors		mov [SetupSecs],ax;; Now see if we have an initial RAMdisk; if so, do requisite computation;                test byte [initrd_flag],1                jz nk_noinitrd                push es                         ; ES->real_mode_seg                push ds                pop es                          ; We need ES==DS                mov si,InitRD                mov di,InitRDCName                call unmangle_name              ; Create human-readable name                sub di,InitRDCName                mov [InitRDCNameLen],di                mov di,InitRD                call searchdir                  ; Look for it in directory                pop es		jz initrd_notthere		mov [initrd_ptr],si		; Save cluster pointer		mov [es:su_ramdisklen1],ax	; Ram disk length		mov [es:su_ramdisklen2],dx		div word [ClustSize]		and dx,dx			; Round up		setnz dl		movzx dx,dl		add ax,dx		mov [InitRDClust],ax		; Ramdisk clusters                mov eax,[es:su_ramdisklen]                shr eax,10                      ; Convert to kilobytes                mov dx,[HighMemSize]		; End of memory                add dx,1024                     ; Add "low" memory                sub dx,ax                       ; Subtract size of ramdisk                and dx,0ffc0h                   ; Round down to 64K boundary                shl dx,2                        ; Convert to 256-byte blocks                mov [InitRDat],dx		; Load address		call loadinitrd			; Load initial ramdisk;; About to load the kernel.  Print the kernel name and pick high or low.;nk_noinitrd:                mov si,KernelCName		; Print kernel name part of                call cwritestr                  ; "Loading" message                mov si,dotdot_msg		; Print dots                call cwritestr                test byte [es:su_loadflags],LOAD_HIGH ; Is high load flag set?                jnz high_kernel                 ; Yes, load high                jmp low_kernel                  ; No, load lowinitrd_notthere:                mov si,err_noinitrd                call writestr                mov si,InitRDCName                call writestr                mov si,crlf                jmp abort_load;; If we get here, we need to load kernel high;no_high_mem:    mov si,err_nohighmem		; Error routine                jmp abort_loadhigh_kernel:                mov ax,[HighMemSize]		cmp ax,[KernelK]		jb no_high_mem			; Not enough high memory;; Move the stuff beyond the setup code to high memory at 100000h;                mov bx,1                        ; 1 boot sector                add bl,[es:bs_setupsecs]	; Plus setup sectors                sbb bh,0                shl bx,1                        ; Convert to 256-byte blocks                mov ax,1080h                    ; 108000h = 1M + 32K                sub ax,bx                       ; Adjust pointer to 2nd block                mov [HiLoadAddr],ax                shl bx,8                        ; Convert to a byte address                mov cx,4000h                    ; Cheating!  Copy all 32K                mov di,1000h                    ; Copy to address 100000h                call upload                     ; Transfer to high memory;                push word xfer_buf_seg		; Segment 7000h is xfer buffer                pop eshigh_load_loop:                 mov si,dot_msg			; Progress report                call cwritestr                call abort_check                mov cx,[KernelClust]		cmp cx,[ClustPerMoby]		jna high_last_moby		mov cx,[ClustPerMoby]high_last_moby:		sub [KernelClust],cx		xor bx,bx			; Load at offset 0                pop si                          ; Restore cluster pointer                call getfssec                push si                         ; Save cluster pointer                pushf                           ; Save EOF                xor bx,bx                mov di,[HiLoadAddr]		; Destination address                mov cx,8000h                    ; Cheating - transfer 64K                call upload                     ; Transfer to high memory                popf                            ; Restore EOF                jc high_load_done               ; If EOF we are done                add word [HiLoadAddr],100h	; Point to next 64K                cmp word [KernelClust],byte 0	; Are we done?		jne high_load_loop		; Apparently nothigh_load_done:		pop si				; No longer needed		push word real_mode_seg		pop es		jmp load_done;; Load an older kernel.  Older kernels always have 4 setup sectors, can't have; initrd, and are always loaded low.;old_kernel:                test byte [initrd_flag],1	; Old kernel can't have initrd                jz load_old_kernel                mov si,err_oldkernel                jmp abort_loadload_old_kernel:		mov si,KernelCName		call cwritestr		mov si,dotdot_msg		call cwritestr		mov word [SetupSecs],4		; Always 4 setup sectors                ; An old kernel is always loaded low...low_kernel:;; Low kernel: check that it will fit as a low kernel,;             save the vkernel buffers into high memory in case we abort the;             load, then transfer the kernel to low memory;                cmp word [KernelK],512		; 512K maximum                jna low_kernel_ok                jmp kernel_corruptlow_kernel_ok:  push es                mov bx,vk_seg                mov es,bx                xor bx,bx                mov di,1000h                    ; 100000h                mov cx,8000h                    ; 64K                call upload                pop es                mov byte [VKernelsHigh],1	; VKernels now in high memory;; Transfer the already loaded protected-mode code down, then load the rest;                mov bx,1                        ; 1 boot sector                add bx,[SetupSecs]		; Plus setup sectors                shl bx,byte 5			; Convert to a paragraph number                push bx                         ; Save paragraph                add bx,real_mode_seg                push ds                         ; Save DS                mov ds,bx                mov ax,1000h                    ; New kernel start at...                mov es,ax                xor si,si                xor di,di                mov cx,2000h                    ; Cheating: copy 32K                rep movsd                       ; Copy down non-setup code                pop ds                pop bx                          ; Segment count of setup                mov ax,1800h                    ; Paragraph for moby 2 if                                                ; setup is 0K                sub ax,bx                       ; AX now = this moby segmentloadmoby:                mov si,dot_msg                call cwritestr                call abort_check                pop si                          ; Restore cluster pointer		mov cx,[KernelClust]		cmp cx,[ClustPerMoby]		jna last_moby		mov cx,[ClustPerMoby]last_moby:		sub [KernelClust],cx		xor bx,bx			; Load at zero                mov es,ax                       ; Segment address                push ax                         ; Save segment address                call getfssec                pop ax		jc load_done		cmp word [KernelClust],byte 0		jz load_done                push si                         ; Save cluster pointer                add ax,1000h                    ; Advance to next moby                jmp short loadmoby;; This is where both the high and low load routines end up after having; loaded;load_done:                mov ax,real_mode_seg                mov es,ax                mov si,dot_msg                call cwritestr;; If the default root device is set to FLOPPY (0000h), change to; /dev/fd0 (0200h);		cmp word [es:bs_rootdev],byte 0		jne root_not_floppy		mov word [es:bs_rootdev],0200hroot_not_floppy:;; Copy the disk table to high memory, then re-initialize the floppy; controller;		mov si,floppy_table		mov di,linux_fdctab		mov cx,3			; 12 bytes		push di		rep movsd		pop di		cli		mov [fdctab1],di		; Save new floppy tab pos		mov [fdctab2],es		sti		xor ax,ax		xor dx,dx		int 13h;

⌨️ 快捷键说明

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