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

📄 syslinux.asm

📁 Windows上的精简Linux系统
💻 ASM
字号:
; -*- fundamental -*- (asm-mode sucks); $Id: syslinux.asm,v 1.16 2002/06/02 05:12:25 hpa Exp $; -----------------------------------------------------------------------;   ;   Copyright 1998-2001 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., 675 Mass Ave, Cambridge MA 02139,;   USA; either version 2 of the License, or (at your option) any later;   version; incorporated herein by reference.;; -----------------------------------------------------------------------;; syslinux.asm;;	DOS installer for SYSLINUX;			absolute 0pspInt20:		resw 1pspNextParagraph:	resw 1			resb 1		; reservedpspDispatcher:		resb 5pspTerminateVector:	resd 1pspControlCVector:	resd 1pspCritErrorVector:	resd 1			resw 11		; reservedpspEnvironment:		resw 1			resw 23		; reservedpspFCB_1:		resb 16pspFCB_2:		resb 16			resd 1		; reservedpspCommandLen:		resb 1pspCommandArg:		resb 127		section .text		org 0100h_start:				mov ax,3000h			; Get DOS version		int 21h		xchg al,ah		mov [DOSVersion],ax		cmp ax,0314h			; DOS 3.20 minimum		jae dosver_ok		mov dx,msg_ancient_err		jmp die		section .bss		alignb 2DOSVersion:	resw 1		section .text;; Scan command line for a drive letter followed by a colon;dosver_ok:		xor cx,cx		mov si,pspCommandArg		mov cl,[pspCommandLen]		cmdscan1:	jcxz bad_usage			; End of command line?		lodsb				; Load character		dec cx		cmp al,' '			; White space		jbe cmdscan1		cmp al,'-'		je scan_option		or al,020h			; -> lower case		cmp al,'a'			; Check for letter		jb bad_usage		cmp al,'z'		ja bad_usage		sub al,'a'			; Convert to zero-based index		mov [DriveNo],al		; Save away drive index		section .bssDriveNo:	resb 1		section .text;; Got the leading letter, now the next character must be a colon;got_letter:	jcxz bad_usage		lodsb		dec cx		cmp al,':'		jne bad_usage;; Got the colon; the rest better be whitespace;got_colon:	jcxz got_cmdline		lodsb		dec cx		cmp al,' '		jbe got_colon;; We end up here if the command line doesn't parse;bad_usage:	mov dx,msg_unfair		jmp die		section .datamsg_unfair:	db 'Usage: syslinux [-s] <drive>:', 0Dh, 0Ah, '$'		section .text;; Scan for options after a - sign.  The only recognized option right now; is -s.;scan_option:	jcxz bad_usage		lodsb		dec cx		cmp al,' '		jbe cmdscan1		or al,20h		cmp al,'s'		jne bad_usage		push si			; make_stupid doesn't save these		push cx		call make_stupid	; Enable stupid boot sector		pop cx		pop si		jmp short scan_option;; Parsed the command line OK.  Check that the drive parameters are acceptable;		struc DPBdpbDrive:	resb 1dpbUnit:	resb 1dpbSectorSize:	resw 1dpbClusterMask:	resb 1dpbClusterShift: resb 1dpbFirstFAT:	resw 1dpbFATCount:	resb 1dpbRootEntries:	resw 1dpbFirstSector:	resw 1dpbMaxCluster:	resw 1dpbFATSize:	resw 1dpbDirSector:	resw 1dpbDriverAddr:	resd 1dpbMedia:	resb 1dpbFirstAccess:	resb 1dpbNextDPB:	resd 1dpbNextFree:	resw 1dpbFreeCnt:	resw 1		endstrucgot_cmdline:		mov dl,[DriveNo]		inc dl				; 1-based		mov ah,32h		int 21h				; Get Drive Parameter Block				and al,al		jnz filesystem_error		cmp word [bx+dpbSectorSize],512	; Sector size = 512 required		jne sectorsize_error		cmp byte [bx+dpbClusterShift],5	; Max size = 16K = 2^5 sectors		jna drive_okhugeclust_error:		mov dx,msg_hugeclust_err		jmp diefilesystem_error:		mov dx,msg_filesystem_err		jmp doserrsectorsize_error:		mov dx,msg_sectorsize_err		jmp diedrive_ok:		push cs		pop ds;; Writing LDLINUX.SYS;		section .dataldlinux_sys_str:		db 'A:\LDLINUX.SYS', 0		section .textwrite_file:		; 0. Set the correct filename		mov al,[DriveNo]		add byte [ldlinux_sys_str],al		; 1. If the file exists, strip its attributes and delete		xor cx,cx			; Clear attributes		mov dx,ldlinux_sys_str		mov ax,4301h			; Set file attributes		int 21h		mov dx,ldlinux_sys_str		mov ah,41h			; Delete file		int 21h		; 2. Create LDLINUX.SYS and write data to it		mov dx,ldlinux_sys_str		xor cx,cx			; Normal file		mov ah,3Ch			; Create file		int 21h		jc .file_write_error		mov [FileHandle],ax		mov bx,ax		mov cx,ldlinux_size		mov dx,LDLinuxSYS		mov ah,40h			; Write data		int 21h		jc .file_write_error		cmp ax,ldlinux_size		je .no_file_write_error.file_write_error:		mov dx, msg_fwrite_err		jmp doserr.no_file_write_error:		mov bx,[FileHandle]		mov ah,3Eh			; Close file		int 21h		section .bssFileHandle:	resw 1		section .text		; 3. Set the readonly flag on LDLINUX.SYS		mov dx,ldlinux_sys_str		mov cx,1			; Read only		mov ax,4301h			; Set attributes		int 21h;; Now, if we're on a recent Windows system we need to lock the device.; This call should have no effect on plain DOS.;lock_drive:		cmp word [DOSVersion], 0700h	; Win9x/NT?		jb .plain_dos			; Plain DOS -> no locking		mov ax,440Dh			; Generic IOCTL		mov bl,[DriveNo]		inc bl				; 1-based		mov bh,1			; Lock level 1		mov cx,084Ah			; Lock logical volume		mov dx,01h			; Allow write mappings/allow new mappings		pusha		int 21h		jc .disk_lock_error_nocleanup		popa		xor dx,dx		inc bh				; Lock level 2		pusha		int 21h		jc .disk_lock_error		popa		inc bh				; Lock level 3		pusha		int 21h		jnc .done.disk_lock_error:		xor cx,cx		mov cl,bh		dec cx.lock_cleanup:		push cx		mov ax, 440Dh		mov bl,[DriveNo]		inc bl		mov cx,086Ah		int 21h		pop cx		loop .lock_cleanup.disk_lock_error_nocleanup:		popa		mov dx, msg_lock_err		jmp doserr.done:		popa.plain_dos:	; Plain DOS -> no locking;; Now read the old boot sector and copy the superblock.;		section .data		align 4, db 0DISKIO		equ $diStartSector:	dd 0				; Absolute sector 0diSectors:	dw 1				; One sectordiBuffer:	dw SectorBuffer			; Buffer offset		dw 0				; Buffer segment		section .textread_bootsect:		mov ax,cs			; Set DS <- CS		mov ds,ax		cmp word [DOSVersion],0400h	; DOS 4.00 has a new interface		jae .new.old:		mov bx,SectorBuffer		mov cx,1			; One sector		jmp short .common.new:		mov bx,DISKIO		mov [bx+8],ax			; Buffer segment		mov cx,-1.common:		xor dx,dx			; Absolute sector 0		mov al,[DriveNo]		int 25h				; DOS absolute disk read		pop ax				; Remove flags from stack		jc disk_read_error		mov si,SectorBuffer+11		; Offset of superblock		mov di,BootSector+11		mov cx,51			; Superblock = 51 bytes		rep movsb			; Copy the superblock		jmp short write_bootsectdisk_read_error:		mov dx,msg_read_err		jmp doserr;; Writing boot sector;write_bootsect:		cmp word [DOSVersion],0400h	; DOS 4.00 has a new interface		jae .new.old:		mov bx,BootSector		mov cx,1			; One sector		jmp short .common.new:		mov bx,DISKIO		mov word [bx+6],BootSector		mov cx,-1.common:		xor dx,dx			; Absolute sector 0		mov al,[DriveNo]		int 26h				; DOS absolute disk write		pop ax				; Remove flags from stack		jc disk_write_error;; Unlock the disk if we had to lock it;unlock_disk:		cmp word [DOSVersion], 0700h		jb .plain_dos		mov cx,	3			; Need to release lock 3 times.loop:		push cx		mov ax,440Dh			; Generic IOCTL		mov bl,[DriveNo]		inc bl				; 1-based drive number		mov cx,086Ah			; Unlock logical drive		int 21h		pop cx		loop .loop.plain_dos:	; Plain DOS -> no lockingall_done:	mov ax,4C00h			; Exit good status		int 21h;; Error routine jump;disk_write_error:		mov dx,msg_write_errdoserr:		push cs		pop ds		push dx				; Error message		push ax				; Error code		mov dx, msg_error_sp		mov ah,09h		int 21h		pop ax				mov cx,4		mov bx,hexdigits		mov si,ax.digit:		rol si,1		rol si,1		rol si,1		rol si,1		mov ax,si		and al,0Fh		xlatb		mov ah,02h			; Display character		mov dl,al		int 21h		loop .digit		mov dx,msg_colon		mov ah,09h		int 21h		jmp short die_common		section .datahexdigits:	db '0123456789ABCDEF'		section .textdie:		push cs		pop ds		push dx		mov dx, msg_error		mov ah,09h		int 21hdie_common:		pop dx				; Error message		mov ah,09h			; Write string		int 21h		mov ax,4C01h			; Exit error status		int 21h;; Patch the code to make it "stupid";make_stupid:		; Only access one sector at a time		mov word [LDLinuxSYS+PATCH_OFFSET],1		ret			section .datamsg_error_sp:		db 'ERROR $'msg_colon:		db ': $'msg_error:		db 'ERROR: $'msg_ancient_err:	db 'DOS version 3.20 or later required', 0Dh, 0Ah, '$'msg_filesystem_err:	db 'Filesystem not found on disk', 0Dh, 0Ah, '$'msg_sectorsize_err:	db 'Sector sizes other than 512 bytes not supported', 0Dh, 0Ah, '$'msg_hugeclust_err:	db 'Clusters larger than 16K not supported', 0Dh, 0Ah, '$'msg_read_err:		db 'Boot sector read failed', 0Dh, 0Ah, '$'msg_write_err:		db 'Boot sector write failed', 0Dh, 0Ah, '$'msg_fwrite_err:		db 'LDLINUX.SYS write failed', 0Dh, 0Ah, '$'msg_lock_err:		db 'Unable to lock drive for exclusive access', 0Dh, 0Ah, '$'		section .data		align 16, db 0BootSector:	incbin "ldlinux.bss"LDLinuxSYS:	incbin "ldlinux.sys"ldlinux_size:	equ $-LDLinuxSYS		section .bss		alignb 16SectorBuffer:	resb 512

⌨️ 快捷键说明

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