📄 second.s
字号:
lea si,(bx+MAX_IMAGE_NAME+1) ! get a pointer to the password string mov bx,#msg_pw ! display a prompt call saypwagain:xor cl,cl ! CL counts characters after a mismatchpwloop: push cx ! get a key mov cx,#pwtime call getkey pop cx cmp al,#13 ! CR ? je pwcr ! yes -> handle it cmp al,#21 ! ^U ? je pwdell ! yes -> erase line cmp al,#24 ! ^X je pwdell cmp al,#8 ! BS ? je pwdelch ! yes -> erase one character cmp al,#127 ! DEL je pwdelch ja pwloop ! ignore other non-printable characters cmp al,#32 jb pwloop or cl,cl ! counting bad input ? jnz pwbad ! yes -> do it cmp al,(si) ! correct input ? je pwgood ! yes -> go onpwbad: inc cl ! count error jnz pwgood ! no overflow -> go on dec cl ! adjust it jmp pwcr ! terminate inputpwgood: inc si ! good character -> go on jmp pwlooppwdell: pop si ! reset the pointer push si add si,#MAX_IMAGE_NAME+1 jmp pwagain ! get password againpwdelch:pop bx ! at the beginning of the line ? push bx add bx,#MAX_IMAGE_NAME+1 cmp si,bx je pwloop ! yes -> ignore it dec si ! remove one character sub cl,#1 jnc pwloop ! no underflow -> go on inc cl ! adjust it jmp pwloop ! next characterpwtime: pop cx ! drop CX ... mov cl,#1 ! ... and failpwcr: call crlf pop bx ! restore the image descriptor or cl,cl ! no errors ? jnz pwfail ! no -> fail cmp byte ptr (si),#0 ! at end ? je doboot ! yes -> continue booting#endif /* CRC_PASSWORDS */pwfail: mov bx,#msg_pf ! display an error message call say br iloop ! get next input! Boot the image BX points todoboot: mov byte ptr prechr,#61 ! switch to equal sign push bx ! save image descr mov bx,#msg_l ! say hi call say pop bx ! display the image name push bx call say pop si#ifndef INITRD_LATE add si,#id_rd_size ! point at ramdisk size long! take care of the RAM disk first#ifdef LCF_M386 xor eax,eax mov (rdbeg),eax ! clear address lodsd mov (rdszl),eax ! set rdszl+rdszh add eax,#4095 ! round up & shr eax,#12 ! convert to pages xchg bx,ax ! copy to BX#else xor ax,ax mov word ptr (rdbeg),ax ! clear address mov word ptr (rdbeg+2),ax lodsw ! number of bytes to load (low word) mov dx,ax mov (rdszl),ax lodsw ! high word mov (rdszh),ax xchg ax,dx ! convert to pages add ax,#4095 adc dx,#0 mov bx,#4096 div bx mov bx,ax#endif lodsw ! address of the first map sector xchg cx,ax lodsw xchg dx,ax lodsb or bx,bx ! no RAM disk ? jz noramd ! yes -> skip it 1 push si ! save SI, ES, and BX (RD size) push es push bx mov bx,[map] ! load the first map sector call sread mov moff,#0#ifdef DEBUG mov bx,#stepa call say#endif#ifdef HIGHMEM_MAX pop bx call rd_setup#else mov ah,#0x88 ! okay, compute load address now int 0x15 ! get amount of memory ... cmp word ptr memlim,#0 ! limit set by user ? je noulim ! no -> continue mov ax,memlim ! use user limit (minus 1M already)noulim: cmp ax,#14*1024 ! more than 15 MB ? jbe no16mb ! no -> go ahead#if 1 cmp ax,#63*1024 ! more than 64Mb ? ja no16mb#endif mov ax,#14*1024 ! avoid the memory hole at 15M-16M ! (kernel can still use "high" memory)no16mb: shr ax,2 ! round to pages pop bx ! subtract RAM disk size sub ax,bx jnc rdokay ! panic if not enough space;;; cmp ax,#128 ! we probably need more than 512 kB for the cmp ax,#256 ! we probably need more than 1M for the ja rdokay ! kernel to be useful ... mov bx,#msg_rd ! complain call say br restrt ! ... and restart if we canrdokay:#if 1 add ax,#256 ! start is at first MB ... mov bx,ax ! copy to BX shl ax,#4 ! *16 shr bx,#12 ! hi 4 bits mov (rdbeg+1),ax ! ... and remember that for patching setup mov (gdt+0x1b),ax ! set up GDT mov (rdbeg+3),bl ! store hi part of address mov (gdt+0x1f),bl ! store hi part of address#else and eax,#0xFFFF ; clear hi part of eax add eax,#256 ; start is at first MB, add 256 pages shl eax,#4 ; convert to address / 256 mov (rdbeg+1),ax ; save address mov (gdt+0x1b),ax shr eax,#16 ; get hi part of EAX mov (rdbeg+3),al ; store hi part of address mov (gdt+0x1f),al ; store hi byte#endif#endif push #0 ! ES=0 is our secret code to load via GDT pop es mov bx,#gdt call lfile ! load it pop es ! restore ES and SI pop sinoramd:#else /* defined(INITRD_LATE) */ push si add si,#id_start ! form address#endif /* ifndef INITRD_LATE */ ; Now load the kernel sectors xor ax,ax mov word ptr (gdt+0x1b),ax ! set GDT to "load low" mov byte ptr (gdt+0x1f),al mov moff,ax ! map is not loaded yet lodsw ! address of the first map sector xchg cx,ax lodsw xchg dx,ax lodsb#if 0 push ax ; save count in AL lodsw ! get the start page shl ax,4 ! *16 mov (gdt+0x1b),ax ! set up GDT pop ax ; restore count in AL#endif push si ! save SI#ifdef DEBUG push ax ; mov bx,#step0 call say pop ax ;#endif mov bx,[map] ! load the first map sector call sread#ifdef DEBUG mov bx,#step0b call say#endif mov bx,#DFLCMD ! load the default command line BEG_FS SEG_FS mov cx,par1_dflcmd+SSDIFF SEG_FS mov dx,par1_dflcmd+2+SSDIFF SEG_FS mov al,par1_dflcmd+4+SSDIFF END_FS call cread push word ptr (DFLCMD) ! push magic number mov bx,#DFLCMD ! load the fallback sector call load1 pop ax ! valid magic number ?#ifndef LCF_READONLY cmp ax,#DC_MAGIC je dclok ! yes -> can write cmp ax,#DC_MGOFF jne nofbck ! invalid -> must not writedclok: mov bx,#DFLCMD ! fallback data present ? cmp word ptr (bx),#DC_MAGIC jne nofbck ! no -> go on call cmd_write ! write out the command linenofbck:#endif#ifdef DEBUG mov bx,#step1 call say#endif mov bx,#DFLCMD ! load the options sector call load1 mov si,cmdbeg ! copy non-options part of command line mov di,#PARMLINEcpnocl: cmp si,options ! at beginning of options ? je cpnodn ! yes -> go on movsb ! copy one byte jmp cpnocl ! next onecpnodn: mov si,#DFLCMD ! constant options ? cmp byte ptr (si),#0 je nocopt ! no -> go on mov al,#32 ! add a space stosbcpcodsp:#ifndef LCF_M386 cmp word ptr (si),#0x656d ! "mem=" ? jne vsknb ! no -> skip to next blank cmp word ptr (si+2),#0x3d6d#else cmp dword ptr (si),#0x3d6d656d ! "mem="#endif jne cpnotmem call getmem ! get the user-provided memory limitcpnotmem: lodsb ! fetch next byte cmp al,#32 ! space ? je cpcodsp ! yes -> discard itcpcolp: or al,al ! NUL ? jz cpcodn ! yes -> done stosb ! store byte cmp al,#32 ! a space ? je cpcodsp ! yes -> discard next lodsb ! get next byte jmp cpcolpcpcodn: seg es cmp byte ptr (di-1),#32 ! last was space ? jne nocopt ! no -> go on dec di ! discard itnocopt: mov si,options ! append variable optionscpvalp: lodsb ! copy one byte stosb or al,al ! NUL ? jnz cpvalp ! no -> go on#ifdef DEBUG mov bx,#step2 call say#endif#ifdef VAR_LOAD mov es,[initseg] ! load the original boot sector#else push #INITSEG ! load the original boot sector pop es#endif xor bx,bx ! load now call load1 pop si ! restore SI lodsw ! get flags bit map xchg bx,ax ! move to BX lodsw ! copy parameters ... VGA mode ... (done) cmp word ptr vgaovr,#VGA_NOCOVR ! VGA mode not overridden on ! command line ? je vganorm ! no -> go on mov ax,vgaovr ! use that value jmp vgasetvganorm:test bx,#FLAG_VGA jz novgavgaset: seg es mov 506,ax ! magic offset in the boot sectornovga: push bx ! use flags (BX) later test bx,#FLAG_LOCK ! ... lock target ? jnz lockit ! yup -> do it cmp byte ptr dolock,#0 ! did user ask to lock new target ? je nolock ! no -> go onlockit:#ifndef LCF_READONLY mov bx,#lkwbuf ! save the command line#ifdef LOCK_BSS mov word (bx),#DC_MAGIC ;#endif push es push si push ds ; pop es ; call cmd_write ; write out the command line pop si pop es#endifnolock:#ifdef DEBUG mov bx,#step3 call say#endif xor cx,cx#ifdef LCF_VARSETUP seg es mov cl,VSS_NUM or cx,cx jnz lsetup#endif mov cl,#SETUPSECS ! default is to load four sectorslsetup: #ifdef VAR_LOAD mov es,[setupseg] ! load the setup codes#else push #SETUPSEG ! load the setup (might meet EOF in the pop es ! process of loading the boot sector of an ! other operating system)#endif#ifdef MEMORY_CHECK mov ax,cx ! number of sectors to AX shl ax,5 ! convert to paragraphs (9-4) mov bx,es add bx,ax add bx,#STACK>>4 ! allow for stack space in paragraphs mov ax,cs ! cmp bx,ax jbe enough_mem mov bx,#msg_mem ! we are very short on memory call sayenough_mem:#endif xor bx,bx ! other operating system)lsloop: push cx call loadopt pop cx loop lsloop#ifdef DEBUG mov bx,#step4 call say#endif pop bx ! get flags test bx,#FLAG_MODKRN ! "modern" kernel ? jz loadlow ! no -> avoid all patching and such seg es ! set loader version mov byte ptr (16),#LOADER_VERSION test bx,#FLAG_LOADHI ! load kernel high jz nohigh seg es mov ax,word ptr (20+1) ; get start address 00 1000 00 mov (gdt+0x1b),ax seg es mov al,byte ptr (20+3) ; get hi-byte of address mov (gdt+0x1f),alnohigh: seg es ! version >= 1 ? cmp word ptr (6),#NEW_HDR_VERSION jbe noheap ! no -> do not patch heap mov ax,cs#ifdef VAR_LOAD sub ax,[initseg] ! find no. of paragraphs available#endif shl ax,4 add ax,#SLA_SIZE_DYN seg es mov word ptr (36),ax seg es ! patch flags or byte ptr (17),#LFLAG_USE_HEAPnoheap:#ifndef INITRD_LATE#ifdef LCF_M386 cmp dword ptr (rdbeg),#0#else cmp byte ptr (rdbeg+3),#0 ! initial RAM disk? jne setrdp cmp word ptr (rdbeg+1),#0 ! initial RAM disk ?#endif je nordpt ! no -> no need to patch header for thatsetrdp:#if DEBUG_NEW push dword (rdbeg) ! print RAM disk address mov bx,#msg_rd2 call say call dout call crlf#endif#ifdef LCF_M386 mov eax,(rdbeg) ! get RAM disk start address seg es mov (24),eax ! store in header mov eax,rdszl seg es mov (28),eax ! set RAM disk size#else mov ax,(rdbeg) ! store RAM disk start address seg es mov (24),ax mov ax,(rdbeg+2) seg es mov (26),ax mov ax,rdszl ! RAM disk size seg es mov (28),ax mov ax,rdszh seg es mov (30),ax#endifnordpt: #endif /* ifndef INITRD_LATE */#ifdef INITRD_LATE pop si ! restore pointer to DESCR to load push [gdt+0x1b] mov al,[gdt+0x1f] push ax call load_initrd ! load the initrd & patch header pop ax mov [gdt+0x1f],al pop bx mov [gdt+0x1b],bx cbw or ax,bx ! load low ?#else#if 1 cmp word ptr (gdt+0x1b),#0 ! load low ?#else mov al,(gdt+0x1f) cbw or ax,(gdt+0x1b) ! load low ?#endif#endif /* ifdef INITRD_LATE */ je loadlow ! yes -> do it xor ax,ax ! GDT is already set up ... mov es,ax mov bx,#gdt#if DEBUG_NEW push bx mov bx,#msg_high call say pop bx#endif call lfile ! load the system ... jmp launch2 ! ... and run itloadlow:#if DEBUG_NEW push bx mov bx,#msg_low call say pop bx#endif call loadfile ! load the systemlaunch2: jmp launch ! go !loadfile: push #SYSSEG ! load a file at SYSSEG:0000 pop es xor bx,bxlfile: call load jmp lfile! Load one sector. Issue an error at EOF.load1: call loadit ! load the sector mov bx,#msg_eof ! we only get here at EOF call say br restrtloadit: call load ! load it pop ax ! drop return address of load1 ret! Load one sector. Start the system at EOF.loadopt:call loadit ! load the sector jmp launch ! go! Load one sequence of sectors. Leave outer function at EOF.load: push es ! save ES:BX push bxlfetch: mov si,moff ! get map offset mov bx,[map] mov cx,(bx+si) ! get address mov dx,(bx+si+2) mov al,(bx+si+4) or cx,cx ! at EOF ? jnz noteof ! no -> go on or dx,dx jnz noteof pop bx ! restore ES:BX pop es pop ax ! pop return address ret ! return to outer functionnoteof: add si,#sa_size ! increment pointer mov moff,si cmp si,#SECTOR_SIZE - sa_size + 1 ! page end ?#ifndef LCF_M386 bcs doload ! no -> load it#else jb near doload#endif mov moff,#0 ! reset pointer push cs ! adjust ES pop es mov bl,hinib ; this might get clobbered push bx ; so save it mov bx,[map] ! load map page call sread pop ax ; restore the hi-nibble mov hinib,al ; mov al,#0x2e ! print a dot call display jmp lfetch ! try again! Start the kernellaunch:#ifdef MENU call menu_exit ! make the menu area vanish#endif call crlf ! display a CRLF mov dx,#0x3f2 ! stop the floppy motor xor al,al outb xor ax,ax ! reset the FDC mov dl,al int 0x13#ifdef VAR_LOAD mov es,[initseg] ! adjust segment registers#else push #INITSEG ! adjust segment registers pop es#endif mov di,#PARMLINE ! set parameter line offset mov ax,cs ! find where we are loaded#ifdef VAR_LOAD sub ax,[initseg] ! find no. of paragraphs available#endif shl ax,4 ! convert para. to bytes add di,ax#ifndef LCF_M386 seg es cmp word ptr CL_HEADER_ID,#0x6448 ! "Hd" jne mbchain seg es cmp word ptr CL_HEADER_ID+2,#0x5372 ! "rS"#else seg es cmp dword ptr CL_HEADER_ID,#0x53726448 ! "HdrS" (reversed)#endif je chkver ! go check header versionmbchain:! it must be the chain loader#ifdef LCF_BDATA BEG_FS SEG_FS ! suppress BIOS data collection or byte ptr par1_prompt+SSDIFF,#FLAG_NOBD ; suppress BIOS data collection END_FS#endif ! ES:DI will point at param line (chain.b)#if DEBUG_NEW mov bx,#nohdrs call say jmp cl_wait#else br start_setup2#endifchkver: mov bh,[gdt+0x1f] ! check for kernel/initrd conflict shl ebx,#8 mov bx,[gdt+0x1b] ! form kernel final load address shl ebx,#8 mov eax,[rdbeg] ! initrd beg address (0 if none) or eax,eax jz no_overwrite sub eax,ebx jae no_overwrite mov bx,#msg_confl br zzno_overwrite:#if DEBUG_NEW mov bx,#hdr1 call say seg es mov ax,CL_HDRS_VERSION call wout mov bx,#hdr2 call say#endif seg es cmp word ptr CL_HDRS_VERSION,#NEW_VERSION ! check for ! new cmdline protocol jb protocol201! and now the new protocol mov ax,es ! form long address#ifndef LCF_M386 xor dx,dx ! in DX:AX mov cx,#4chkver11: shl ax,1 rcl dx,1 loop chkver11 add ax,di ! add in offset adc dx,#0 seg es mov CL_POINTER,ax ! set the long, absolute pointer seg es mov CL_POINTER+2,dx#if DEBUG_NEW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -