📄 dosstart.s
字号:
// .word Exit_Done - nxtdev # 2 Build BPB// .word Exit_UC - nxtdev # 3 IOCtl in// .word Exit_Done - nxtdev # 4 Input// .word Exit_Busy - nxtdev # 5 Non-destructive input// .word Exit_Done - nxtdev # 6 Input status// .word Exit_Done - nxtdev # 7 Input flush// .word Exit_Done - nxtdev # 8 Output// .word Exit_Done - nxtdev # 9 Output with verify// .word Exit_Done - nxtdev #0Ah Output status// .word Exit_Done - nxtdev #0Bh Output flush// .word Exit_UC - nxtdev #0Ch IOCtl out// .word Exit_Done - nxtdev #0Dh Device open (3.0+)// .word Exit_Done - nxtdev #0Eh Device close (3.0+)// .word Exit_UC - nxtdev #0Fh Removable media (3.0+)// .word Exit_UC - nxtdev #10h Output till busy (3.0+)// .word Exit_UC - nxtdev #11h (Unused)// .word Exit_UC - nxtdev #12h (Unused)// .word Exit_UC - nxtdev #13h Generic IOCTL (3.2:B, 3.3+:B/C)// .word Exit_UC - nxtdev #14h (Unused)// .word Exit_UC - nxtdev #15h (Unused)// .word Exit_UC - nxtdev #16h (Unused)// .word Exit_UC - nxtdev #17h Get logical device (3.2+)// .word Exit_UC - nxtdev #18h Set logical device (3.2+)// .word Exit_UC - nxtdev #19h IOCTL query (5.0+)interrupt: pushfw cli cld pushaw pushw %ds #Save segment registers pushw %es movw %cs, %ax #Make DS point to us movw %ax, %ds lesw ReqHeader - nxtdev, %bx #Get ptr to request header in ES:BX movb %es:2(%bx), %al #Get command// cmpb $0x19, %al #Check if within range// ja Exit_UC # no: set unknown command bit and exit// shlb $1, %al # yes: make word index// xorb %ah, %ah// movw %ax, %di #Place it in index register// jmp *(cmdtab - nxtdev)(%di) # and jump to apropriate routine testb %al, %al jz Init//Exit_Busy:// orw $0x0200, %es:3(%bx)// jmp Exit_Done//Exit_UC: orw $0x8103, %es:3(%bx) #Set ERROR, DONE and UNKNOWN COMMANDexit: popw %es #Restore segment registers popw %ds popaw popfw lret #Return to callerInit:#if 0 /* Display CS and the original value at break address. */ movw %cs, %bp call display_word movw $0x0e0d, %ax int $0x10 movw $0x0e0a, %ax int $0x10 lesw ReqHeader - nxtdev, %bx #Get ptr to request header in ES:BX movl %es:14(%bx), %esi #Set zero break address movl %esi, %ebp shrl $16, %ebp call display_word movl %esi, %ebp call display_word movw $0x0e0d, %ax int $0x10 movw $0x0e0a, %ax int $0x10#endif#if 0 /* Show commandline (including driver name) */ movb $3, %ah #Read cursor position xorb %bh, %bh # for video page 0 int $0x10 #(BIOS) (Returned in dx) lesw ReqHeader - nxtdev, %bx #Get ptr to request header in ES:BX lesw %es:18(%bx), %bp #Get pointer to commandline in ES:BP movw %bp, %di #Get pointer in ES:DI too movb $0x0A, %al #Terminating character of commandline movw $2048, %cx #Search max 2048 bytes cld repnz scasb #Search for it movw %di, %cx #Get pointer to end of string subw %bp, %cx #Calculate length movw $0x1301, %ax #Write string in teletype mode movw $2, %bx # with attribute green int $0x10 #(BIOS)#endif#if 1 /* DS=CS */ lesw ReqHeader - nxtdev, %bx #Get ptr to request header in ES:BX ldsw %es:18(%bx), %si #Get pointer to commandline in DS:SI movw $0x0080, %di #Command line will be moved to here #as if it is in a PSP movw %cs, %ax addw $((start - nxtdev) >> 4), %ax movw %ax, %es cld xorw %ax, %ax stosb #store 0 at offset 0x0080, this is an #indicator for device driver than EXE /* DS:SI points to driver name */ movw $0xfff, %cx /* move at most 4095 bytes */ /* first, skip all blank characters. */1: lodsb cmpb $0x20, %al /* 0x20 is space bar */ je 1b cmpb $0x09, %al /* 0x09 is TAB */ je 1b decw %si /* secondly, skip the name of the driver. */1: lodsb cmpb $0x20, %al /* 0x20 is space bar */ ja 1b /* finally, copy the rest of the command line. */1: cmpb $0x0A, %al /* 0x0A is LF */ jne 2f movb $0x0D, %al /* 0x0D is CR */2: cmpb $0x0D, %al /* 0x0D is CR */ je 3f cmpb $0x09, %al /* 0x09 is the TAB key. */ jne 2f movb $0x20, %al2: stosb lodsb loop 1b3: movb $0x00, %al /* Ends in a NULL */ stosb /* the last char stored is NULL */#endif movw %cs, %ax movw %ax, %ds lesw ReqHeader - nxtdev, %bx #Get ptr to request header back orw $0x810C, %es:3(%bx) #Set ERROR and DONE bits # and OTHER ERROR code movb $0, %es:13(%bx) #Clear UNITS byte for CHAR device andw $0x7FFF, attr - nxtdev #Clear CHAR bit in device attrib eord xorw %ax, %ax xchgw %ax, %es:14(%bx) #Set zero break address /* MS-DOS will initialize the break address as XXXX:0000. */ testw %ax, %ax #Is it MS-DOS 5.0+ ? movw %cs, %ax xchgw %ax, %es:16(%bx) #Set break address segment jnz 1f #no, do not check the end address. /* yes, check the memory available for this device driver. */ movw %cs, %bx #the driver start segment cmpw %bx, %ax #Is the end address too low? jbe 1f #yes, do not check the end address. cmpw $0xe000, %ax #Is the end address too high? jae 1f #yes, do not check the end address. /* check if we have 64K room available at the end of the driver image. * This 64K space will be used for backup the HMA. Exit here if no * enough memory. And 12K room for VCPI page_info, and additional * 1K room for restoring EBDA from (nearly)bottom to (nearly)top of * the conventional memory. */ movw %cs, %bx #the driver start segment addw $((exe_sectors * 0x20) + 0x1000 + 0x0300 + 0x0040), %bx #0x1000 paragraphs = 64K (HMA_backup) #0x0300 paragraphs = 12K (page_info) #0x0040 paragraphs = 1K (EBDA) jc 2f #load too high, failure cmpw %bx, %ax jnb 1f #check passed, continue2: /* print error message. */ movb $3, %ah #Read cursor position xorb %bh, %bh # for video page 0 int $0x10 #(BIOS) (Returned in dx) movw $0x1301, %ax #Write string in teletype mode movb $3, %bl # with attribute cyan movw $(nomem_end - nomem), %cx # length of string movw $(nomem - nxtdev), %bp # start of string pushw %cs # in es:bp popw %es int $0x10 #(BIOS) jmp exit1: //jmp 2b#if 1 /* Because our stack will be changed, we must backup all registers. */ movw %cs, %ax //movw %ax, %ds # DS=CS// /* DS=CS=device driver start. Adjust the exit address. */// movw %ax, (device_driver_exit_cs - nxtdev) addw $((start - nxtdev) >> 4), %ax movw %ax, %es /* ES:0000 now points to START */ cld xorw %di, %di stosl /* EAX */ movl %ebx, %eax stosl /* EBX */ movl %ecx, %eax stosl /* ECX */ movl %edx, %eax stosl /* EDX */ movl %edi, %eax stosl /* EDI */ movl %esp, %eax stosl /* ESP */ movl %ebp, %eax stosl /* EBP */ movw %ss, %ax stosw /* SS */ movw %fs, %ax stosw /* FS */ movw %gs, %ax stosw /* GS */ pushfl popl %eax stosl /* EFLAGS */ movl %esi, %eax stosl /* ESI */ /* modify the stack */ cli movw %es, %ax /* ES:0000 now points to START */ movw %ax, %ds movw %ax, %ss movw $ABS_START(dos_stack), %sp /* far jump to _dos_start1. */ /* Note: DS=ES=CS tells _dos_start we are from device driver. */ pushw %es pushw $ABS_START(_dos_start1) lret /* if need be, we could come back here from _dos_start1. */device_driver_exit:// /* far jump to load CS *///// .byte 0xEA /* opcode for ljmp */// .word (device_driver_exit1 - nxtdev)// /* offset for destination *///device_driver_exit_cs:// .word 0 /* filled with driver CS */////device_driver_exit1: cli cld movw %cs, %ax movw %ax, %ds movw $(start - nxtdev), %si lodsl /* EAX */ lodsl /* EBX */ xchgl %eax, %ebx lodsl /* ECX */ xchgl %eax, %ecx lodsl /* EDX */ xchgl %eax, %edx lodsl /* EDI */ xchgl %eax, %edi lodsl /* ESP */ xchgl %eax, %esp lodsl /* EBP */ xchgl %eax, %ebp lodsw /* SS */ movw %ax, %ss lodsw /* FS */ movw %ax, %fs lodsw /* GS */ movw %ax, %gs /* SS:SP has been restored, so it is safe to use stack. */ lodsl /* EFLAGS */ pushl %eax popfl /* direction flag here is UPWARD as we saved it before. */ /* Another note: the direction flag does not matter, because * this is the last LODS instruction executed before we exit. */ lodsl /* ESI */ xchgl %eax, %esi jmp exit#endif#if 0display_word: /* routine for display hex value of BP */ xorw %bx, %bx movw %bp, %ax shrw $12, %ax cmpb $9, %al jbe 1f addb $7, %al1: addb $0x30, %al movb $0x0e, %ah int $0x10 movw %bp, %ax shrw $8, %ax andb $0x0f, %al cmpb $9, %al jbe 1f addb $7, %al1: addb $0x30, %al movb $0x0e, %ah int $0x10 movw %bp, %ax shrw $4, %ax andb $0x0f, %al cmpb $9, %al jbe 1f addb $7, %al1: addb $0x30, %al movb $0x0e, %ah int $0x10 movw %bp, %ax andb $0x0f, %al cmpb $9, %al jbe 1f addb $7, %al1: addb $0x30, %al movb $0x0e, %ah int $0x10 ret#endifnomem: .ascii "\r\nError: No enough memory to run GRUB.EXE with the DEVICE command in CONFIG.SYS\r\n"nomem_end:#-----------------------------------------------------------------------------# DOS device driver structure ends here#-----------------------------------------------------------------------------#undef ENTRY#define __ASSEMBLY__#define __KERNEL__#define __BIG_KERNEL__#define SVGA_MODE NORMAL_VGA /* stolen from linux-2.6.13.1/arch/i386/boot/bootsect.S *//* * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds * * modified by Drew Eckhardt * modified by Bruce Evans (bde) * modified by Chris Noe (May 1999) (as86 -> gas) * gutted by H. Peter Anvin (Jan 2003) * * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment * addresses must be multiplied by 16 to obtain their respective linear * addresses. To avoid confusion, linear addresses are written using leading * hex while segment addresses are written as segment:offset. * */#include <asm/boot.h>SETUPSECTS = 4 /* default nr of setup-sectors */BOOTSEG = 0x07C0 /* original address of boot-sector */INITSEG = DEF_INITSEG /* we move boot here - out of the way */SETUPSEG = DEF_SETUPSEG /* setup starts here */SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ /* to be loaded */ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */#ifndef SVGA_MODE#define SVGA_MODE ASK_VGA#endif#ifndef RAMDISK#define RAMDISK 0#endif#ifndef ROOT_RDONLY#define ROOT_RDONLY 1#endif//.code16//.text//.global _start//_start:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -