home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / unix / bootlin4 / bootlin.asm next >
Encoding:
Assembly Source File  |  1992-06-28  |  9.7 KB  |  525 lines

  1.  
  2.         NAME    BootLinux
  3.  
  4. MainSeg        SEGMENT PUBLIC 'TEXT'
  5.         ASSUME cs:MainSeg, ds:MainSeg, es:MainSeg
  6.  
  7.         ORG 0100h        ; it is going to be a COM file
  8.  
  9. FileNameSize    EQU 80
  10. StackSize    EQU 2048
  11. PlusSize    EQU FileNameSize+StackSize
  12. PageLength    EQU 4000h        ; MUST be a power of 2
  13. KernelStart    EQU 1000h
  14. KernelEnd    EQU 9000h
  15. BootlinMove    EQU 9800h
  16.  
  17. JumpStart    PROC FAR
  18.         jmp near ptr start
  19. JumpStart    ENDP
  20.  
  21.         ASSUME cs:MainSeg, ds:NOTHING, es:NOTHING
  22. NewInt13    PROC FAR
  23. oldint        dd 0
  24. pageToMove    dw 0
  25. pageToClean    dw 0
  26.  
  27. newint:        cmp ax,1500h
  28.         je nobypass
  29.         jmp dword ptr cs:oldint
  30.  
  31. nobypass:    push bp
  32.         mov bp,sp
  33.         push word ptr [bp+6]
  34.         call dword ptr cs:oldint
  35.         pop bp
  36.         cli
  37.         pushf
  38.         push ds
  39.         push es
  40.         push si
  41.         push di
  42.         push ax
  43.         push bx
  44.         push cx
  45.         push dx
  46.  
  47.         mov si,cs:pageToMove
  48.         mov di,KernelStart
  49.         jmp short endmove
  50.  
  51. domove:        call near ptr MovePage
  52. endmove:    cmp si,KernelEnd
  53.         jne domove
  54.  
  55.         mov di,cs:pageToClean
  56.         jmp short endclean
  57.  
  58. doclean:    call near ptr CleanPage
  59.         mov di,dx
  60. endclean:    cmp di,KernelEnd
  61.         jne doclean
  62.  
  63.         pop dx
  64.         pop cx
  65.         pop bx
  66.         pop ax
  67.         pop di
  68.         pop si
  69.         pop es
  70.         pop ds
  71.         popf
  72.         ret 2
  73. NewInt13    ENDP
  74.  
  75.         ASSUME cs:MainSeg, ds:NOTHING, es:NOTHING
  76. CleanPage    PROC NEAR        ; di = segment of page to fill
  77.         push es
  78.         push ax
  79.         push cx
  80.         mov es,di
  81.         xor ax,ax
  82.         mov di,ax
  83.         mov cx,(PageLength SHR 1)
  84.         cld
  85.         rep stosw
  86.         mov di,es
  87.         lea dx,[di][PageLength SHR 4]
  88.         pop cx
  89.         pop ax
  90.         pop es
  91.         ret
  92. CleanPage    ENDP            ; returns di unchanged, dx on next page
  93.  
  94.         ASSUME cs:MainSeg, ds:NOTHING, es:NOTHING
  95. MovePage    PROC NEAR        ; moves page at si:0 to page at di:0
  96.         push ds
  97.         push es
  98.         push cx
  99.         mov ds,si
  100.         mov es,di
  101.         xor si,si
  102.         xor di,di
  103.         mov cx,(PageLength SHR 1)
  104.         cld
  105.         rep movsw
  106.         mov si,ds
  107.         mov di,es
  108.         add si,(PageLength SHR 4)
  109.         add di,(PageLength SHR 4)
  110.         pop cx
  111.         pop es
  112.         pop ds
  113.         ret
  114. MovePage    ENDP            ; returns di and si on next pages
  115.  
  116.         ASSUME cs:MainSeg, ds:MainSeg, es:MainSeg
  117. TheStart    PROC FAR
  118. start:
  119.         mov ah,9
  120.         lea dx,Copyright
  121.         int 21h
  122.  
  123.         lea bx,TheEnd
  124.         add bx,PlusSize        ; compute start of the new stack
  125.  
  126.         cli
  127.         push cs
  128.         pop ss
  129.         mov sp,bx
  130.         sti            ; sets the new stack
  131.  
  132.         mov cl,4
  133.         dec bx
  134.         shr bx,cl
  135.         inc bx
  136.         mov ax,ss
  137.         add ax,bx        ; compute the segment after the stack
  138.  
  139.         cmp ax,KernelStart    ; and check it doesn't overlap
  140.         jge moreComplicated
  141.         
  142.         call near ptr CleanMemory
  143.         call near ptr GetFileName    ; get filename from command line
  144.         mov ax,KernelEnd
  145.         call near ptr ReadLinux        ; loads kernel in memory
  146.         jmp short RunLinux
  147.  
  148. moreComplicated:
  149.         add ax,(PageLength SHR 4)
  150.         mov bx,ax
  151.         and ax,((PageLength-1) SHR 4)
  152.         xor bx,ax
  153.         sub bx,KernelStart
  154.         mov ax,KernelEnd
  155.         sub ax,bx
  156.         mov pageToMove,ax
  157.         push ax
  158.         mov ax,3513h
  159.         int 21h
  160.         mov word ptr [oldint],bx
  161.         mov word ptr [oldint+2],es
  162.         call near ptr GetFileName    ; get filename from command line
  163.         pop ax
  164.         call near ptr ReadLinux
  165.         mov pageToClean,ax
  166.         mov si,cs
  167.         mov di,BootlinMove
  168.         push ds
  169.         push di
  170.         call near ptr MovePage
  171.         pop ds
  172.         lea dx,newint
  173.         mov ax,2513h
  174.         int 21h
  175.         pop ds
  176.  
  177. RunLinux:
  178.         mov ax,9000h        ; and now, serious things begin !
  179.         mov ds,ax
  180.         mov bx,200h-4
  181.         mov ax,word ptr [bx]    ; fetch root device
  182.  
  183.         cmp ax,0        ; check for non NULL device number
  184.         jne DoIt
  185.  
  186.         push bx            ; the ROOT is not defined
  187.         push ds            ; so let's ask it !
  188.         push cs
  189.         pop ds
  190.  
  191.         mov ah,9
  192.         lea dx,RootMsg
  193.         int 21h
  194.  
  195. TheKey:        mov ah,0
  196.         int 16h
  197.         sub al,'1'
  198.         cmp al,'4'-'1'
  199.         jle DevNum        ; jump if '1'<=key<='4' ; al=0..3
  200.         sub al,'A'-'1'
  201.         cmp al,'a'-'A'        ; capitalization
  202.         jl DevAlp
  203.         sub al,'a'-'A'
  204. DevAlp:        cmp al,'H'-'A'
  205.         jg TheKey        ; pass if 'A'<=CAP(key)<='H' ; al=0..7
  206.         add al,'5'-'1'        ; translate al to 4..11
  207. DevNum:        add al,al
  208.         mov ah,0
  209.         lea bx,DeviceTable
  210.         add bx,ax
  211.         mov ax,word ptr [bx]    ; now we have the ROOT
  212.  
  213.         pop ds        ; so we save it (for posterity)
  214.         pop bx        ; in the bootsector
  215.         mov word ptr [bx],ax
  216.  
  217. DoIt:        cli
  218.         mov bx,9000h
  219.         mov ds,bx
  220.         mov es,bx
  221.         mov ss,bx
  222.         mov sp,4000h        ; the setup stack ; no space for
  223.         sti            ; disk param table, because no need
  224.  
  225.         mov bx,9020h         ; here I made a mistake last time
  226.         push bx
  227.         xor bx,bx
  228.         push bx
  229.         ret
  230. TheStart    ENDP
  231.  
  232.         ASSUME cs:MainSeg, ds:MainSeg, es:MainSeg
  233. ReadLinux    PROC NEAR
  234.         push ax
  235. TryAgain:
  236.         mov ax,03d00h        ; tries to open the specified file
  237.         lea dx,filename        ; in READ-ONLY mode
  238.         int 21h
  239.         jnc OpenIsOk
  240.  
  241.         lea dx,BadFileMsg    ; fail: print error msg and
  242.         mov ah,9
  243.         int 21h
  244.         call near ptr AskFileName    ; asks for another file name
  245.         jmp short TryAgain    ; and try again until it succeeds
  246.  
  247. OpenIsOk:    mov word ptr filehandle,ax    ; save file handle
  248.  
  249.         mov ah,9
  250.         lea dx,BootMsg
  251.         int 21h            ; bootsect load message
  252.  
  253.         mov di,9000h        ; target:= 9000:0
  254.         mov cx,200h        ; size:= 1 sector = 512 bytes
  255.         call near ptr sectread    ; reads boot sector
  256.         jne Image        ; fail => bad length
  257.  
  258.         call near ptr bootcheck    ; checks for 0AA55h at the end
  259.         jne BootError
  260.  
  261.         mov ah,9
  262.         lea dx,SetupMsg
  263.         int 21h            ; setup load message
  264.  
  265.         mov di,9020h        ; target:= 9000:200
  266.         mov cx,800h        ; size:= 4 sectors = 2K
  267.         call near ptr sectread    ; reads setup
  268.         jne Image        ; fail => bad length
  269.  
  270.         mov ah,9
  271.         lea dx,KernelMsg
  272.         int 21h            ; kernel load message
  273.  
  274.         pop di            ; start kernel loading at ????:0
  275.         mov cx,PageLength    ; read it by pages
  276.         mov si,KernelStart    ; virtual loading address
  277.         mov dx,di        ; saves start page for future compare
  278.  
  279. kernrd:        push dx
  280.         push si
  281.         cmp di,KernelEnd
  282.         jne readpage
  283.         mov di,si
  284. readpage:    call near ptr CleanPage
  285.         push dx
  286.         call near ptr sectread    ; reads the page
  287.  
  288.         pushf            ; save useful registers
  289.         push cx
  290.         mov ah,2
  291.         mov dl,'.'
  292.         int 21h            ; print one dot
  293.         pop cx
  294.         popf            ; and restore
  295.  
  296.         pop di
  297.         pop si
  298.         pop dx
  299.  
  300.         jnz close        ; if the whole page has been read,
  301.                     ; continue, else close file
  302.         add si,(PageLength SHR 4)
  303.         cmp si,dx
  304.         je NotEnoughMemory
  305.         jmp short kernrd
  306.  
  307. prnt:        push cs
  308.         pop ds
  309.         mov ah,9
  310.         int 21h
  311. bcl:        jmp short bcl
  312.  
  313. BootError:
  314.         lea dx,CheckMsg
  315.         jmp short prnt
  316.  
  317. NotEnoughMemory:
  318.         lea dx,MemoryMsg
  319.         jmp short prnt
  320.  
  321. Image:        lea dx,ImageMsg
  322.         jmp short prnt
  323.  
  324. Error:        lea dx,ErrorMsg
  325.         jmp short prnt
  326.  
  327. close:        push si
  328.         mov ah,3eh
  329.         mov bx,word ptr filehandle
  330.         int 21h            ; otherwise, close the file
  331.  
  332.         mov ah,9
  333.         lea dx,DoneMsg
  334.         int 21h            ; done message
  335.  
  336.         pop ax
  337.         add ax,(PageLength SHR 4)
  338.         ret
  339. ReadLinux    ENDP
  340.  
  341.         ASSUME ds:NOTHING
  342. sectread    PROC NEAR        ; tries to read cx bytes at di:0
  343.         push ds            ; returns ZF set if all bytes read
  344.         push bx
  345.         push cx
  346.         mov ds,di
  347.         mov bx,cs:word ptr filehandle
  348.         xor dx,dx
  349.         mov ah,03fh
  350.         int 21h
  351.         mov di,ds
  352.         pop cx
  353.         pop bx
  354.         pop ds
  355.         jc dumbError
  356.         cmp ax,cx
  357.         ret
  358. dumbError:    jmp Error
  359. sectread    ENDP
  360.  
  361. CleanMemory    PROC NEAR
  362.         push dx
  363.         push di
  364.         mov di,KernelStart
  365. goonclean:    call near ptr CleanPage
  366.         mov di,dx
  367.         cmp di,KernelEnd
  368.         jne goonclean
  369.         pop di
  370.         pop dx
  371. CleanMemory    ENDP
  372.  
  373.         ASSUME ds:NOTHING
  374. bootcheck    PROC NEAR
  375.         push ds
  376.         push bx
  377.         mov ax,9000h
  378.         mov ds,ax
  379.         mov bx,01FEh
  380.         mov ax,[bx]
  381.         pop bx
  382.         pop ds
  383.         cmp ax,0AA55h
  384.         ret
  385. bootcheck    ENDP
  386.  
  387.         ASSUME ds:MainSeg
  388. AskFileName    PROC NEAR
  389.         lea bx,filename
  390.         push bx
  391.         xor cx,cx
  392. checkEnd:    cmp byte ptr [bx],0
  393.         je proceed
  394.         cmp cx,FileNameSize-1
  395.         je proceed
  396.         inc cx
  397.         inc bx
  398.         jmp short checkEnd
  399. proceed:    mov byte ptr [bx],'$'
  400.         pop dx
  401.         mov ah,9
  402. int21call:    push bx
  403.         push cx
  404.         int 21h
  405.         pop cx
  406.         pop bx
  407. input:        call near ptr Inkey
  408.         cmp ax,127
  409.         jge input
  410.         cmp ax,8
  411.         je backspace
  412.         cmp ax,13
  413.         je return
  414.         cmp ax,31
  415.         jle input
  416.         cmp cx,FileNameSize-1
  417.         jge beep
  418.         mov byte ptr [bx],al
  419.         inc bx
  420.         inc cx
  421.         mov dl,al
  422. prchar:        mov ah,2
  423.         jmp short int21call
  424. beep:        mov dl,7
  425.         jmp short prchar
  426. backspace:    jcxz beep
  427.         dec bx
  428.         dec cx
  429.         push bx
  430.         push cx
  431.         mov ah,2
  432.         mov dl,8
  433.         int 21h
  434.         mov dl,' '
  435.         int 21h
  436.         pop cx
  437.         pop bx
  438.         mov dl,8
  439.         jmp short prchar
  440. return:        mov byte ptr [bx],0
  441.         mov ah,9
  442.         lea dx,SomeCrLfs
  443.         int 21h
  444.         ret
  445. AskFileName    ENDP
  446.  
  447. Inkey        PROC NEAR
  448.         push bx
  449.         push cx
  450.         mov ah,7
  451.         int 21h
  452.         mov ah,0
  453.         cmp al,0
  454.         jne endkey
  455.         mov ah,0bh
  456.         int 21h
  457.         mov ah,0
  458.         cmp al,0
  459.         je endkey
  460.         mov ah,7
  461.         int 21h
  462.         mov ah,1
  463. endkey:        pop cx
  464.         pop bx
  465.         ret
  466. Inkey        ENDP
  467.         
  468. GetFileName    PROC NEAR        ; copy first argument to filename
  469.         mov ax,cs
  470.         mov ds,ax
  471.         mov es,ax
  472.         mov si,0080h        ; start of command line parameters
  473.         lea di,filename
  474.         mov ch,0
  475.         mov cl,byte ptr [si]
  476.         inc si
  477.         cld
  478.         jcxz stoploop
  479. startloop:    lodsb
  480.         cmp al,' '
  481.         je endloop
  482.         stosb
  483. endloop:    loop startloop
  484. stoploop:    mov al,0        ; make it in ASCIIZ format
  485.         stosb
  486.         ret
  487. GetFileName    ENDP
  488.  
  489.  
  490. Copyright    db 13,25 dup (10)
  491.         db "BOOTLINUX v1.3 (C) 1992 F.COUTANT"
  492. SomeCrLfs    db 13,10,10,"$"
  493. BadFileMsg    db "Could not open Image file. Please enter new file name"
  494.         db 13,10,"or press Ctrl-Alt-Del to reboot:",13,10,"$"
  495. MemoryMsg    db "BootLinux is loaded too high in memory",13,10,"$"
  496. BootMsg        db "BootSector: ... $"
  497. CheckMsg    db "not a boot-disk image !$"
  498. SetupMsg    db "loaded",13,10,"LINUX Setup: ... $"
  499. KernelMsg    db "loaded",13,10,"LINUX Kernel: $"
  500. ImageMsg    db "bad image length$"
  501. ErrorMsg    db " error during read !$"
  502. DoneMsg        db " done",13,10,10,"$"
  503. RootMsg        db "ROOT device is not defined. Please choose it:",13,10,10
  504.         db "    [1] at0     [3] at1",13,10
  505.         db "    [2] ps0     [4] ps1",13,10,10
  506.         db "    [A] hda1    [E] hdb1",13,10
  507.         db "    [B] hda2    [F] hdb2",13,10
  508.         db "    [C] hda3    [G] hdb3",13,10
  509.         db "    [D] hda4    [H] hdb4",13,10,10,"$"
  510.  
  511. DeviceTable    dw 0208h, 021Ch, 0209h, 021Dh
  512.         dw 0301h, 0302h, 0303h, 0304h
  513.         dw 0341h, 0342h, 0343h, 0344h
  514.  
  515. filehandle    dw 0
  516. filename:
  517.  
  518. TheEnd        LABEL BYTE
  519.  
  520. MainSeg        ENDS
  521.  
  522.  
  523.         END MainSeg:JumpStart
  524.  
  525.