123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- ;*
- ;* bios/imgrecv.asm
- ;* https://gitlab.com/bztsrc/imgrec
- ;*
- ;* Copyright (C) 2020 bzt (bztsrc@gitlab)
- ;*
- ;* Permission is hereby granted, free of charge, to any person
- ;* obtaining a copy of this software and associated documentation
- ;* files (the "Software"), to deal in the Software without
- ;* restriction, including without limitation the rights to use, copy,
- ;* modify, merge, publish, distribute, sublicense, and/or sell copies
- ;* of the Software, and to permit persons to whom the Software is
- ;* furnished to do so, subject to the following conditions:
- ;*
- ;* The above copyright notice and this permission notice shall be
- ;* included in all copies or substantial portions of the Software.
- ;*
- ;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- ;* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- ;* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- ;* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- ;* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- ;* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- ;* DEALINGS IN THE SOFTWARE.
- ;*
- LOAD_ADDR equ 1024*1024
- if ~defined OPTIONROM
- ORG 0600h
- USE16
- end if
- bootboot_record:
- if ~defined OPTIONROM
- jmp short .skipid
- nop
- .skipid:
- end if
- ;relocate our code to offset 0h:600h
- cli
- cld
- xor ax, ax
- mov ss, ax
- mov sp, 600h
- push ax
- pop es
- push cs
- pop ds
- ;find our position in memory.
- call .getaddr
- .getaddr: pop si
- sub si, .getaddr-bootboot_record
- mov di, sp
- ;clear data area 500h-600h
- sub di, 100h
- mov cx, 80h
- repnz stosw
- ;and copy ourselves to 600h
- mov cx, 100h
- repnz movsw
- ;have to clear ds, because cs is set to 7c0 when booted from El Torito
- push es
- pop ds
- jmp 0:.start
- .start:
- ;-----initialize serial port COM1,115200,8N1------
- mov ax, 0401h
- xor bx, bx
- mov cx, 030Bh
- xor dx, dx
- int 14h
- mov dx, 03fdh
- in al, dx
- cmp al, 0ffh
- jne .a20
- mov si, errstr
- @@: lodsb
- or al, al
- jz @b
- mov ah, byte 0Eh
- mov bx, word 11
- int 10h
- jmp @b
- @@: jmp @b
- ;-----enable A20-----
- .a20: mov ax, 2401h
- int 15h
- ;---- enable protmode ----
- lgdt [GDT_value]
- mov eax, cr0
- or al, 1
- mov cr0, eax
- jmp CODE_PROT:protmode_start
- USE32
- ; IN: al, character to send
- uart_send: mov ah, al
- mov dx, 3fdh
- @@: pause
- in al, dx
- and al, 20h
- jz @b
- sub dl, 5
- mov al, ah
- out dx, al
- ret
- ; IN: edi pointer to store the received char
- uart_getc: mov dx, 03fdh
- @@: pause
- in al, dx
- and al, 1
- jz @b
- sub dl, 5
- in al, dx
- stosb
- ret
- protmode_start:
- mov ax, DATA_PROT
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
- mov esp, 600h
- ;---- notify raspbootcom / USBImager to send the kernel ----
- again: mov al, 3
- call uart_send
- call uart_send
- call uart_send
- ;---- read the kernel's size ----
- mov edi, size
- call uart_getc
- call uart_getc
- call uart_getc
- call uart_getc
- mov ecx, dword [size]
- mov edi, LOAD_ADDR
- ;---- send negative or positive acknowledge ----
- cmp ecx, 32
- jb .se
- cmp ecx, 4*1024*1024
- jb .ok
- .se: mov al, 'S'
- call uart_send
- mov al, 'E'
- call uart_send
- jmp again
- .ok: mov ebx, edi
- mov al, 'O'
- call uart_send
- mov al, 'K'
- call uart_send
- ;---- read in the image ----
- @@: call uart_getc
- dec ecx
- jnz @b
- mov al, 0FFh ;disable PIC
- out 021h, al
- out 0A1h, al
- in al, 70h ;disable NMI
- or al, 80h
- out 70h, al
- ;---- get entry point ----
- cmp dword [ebx], 06D6F687Fh ; \x7fELF
- jne @f
- cmp byte [ebx+4], 2
- je .long
- mov ebx, dword [ebx+24]
- @@: jmp ebx
- .long: ;PML4
- mov edi, 01000h
- ;pointer to 2M PDPE (first 4G RAM identity mapped)
- mov dword [edi], 02003h
- ;2M PDPE
- mov edi, 02000h
- mov dword [edi], 03003h
- ;2M PDE
- mov edi, 03000h
- xor eax, eax
- mov al, 83h
- mov ecx, 512* 1;G RAM
- @@: stosd
- add edi, 4
- add eax, 2*1024*1024
- dec ecx
- jnz @b
- mov eax, 01000h
- mov cr3, eax
- mov ecx, 0C0000080h ;EFER MSR
- rdmsr
- or eax, 100h ;enable long mode
- wrmsr
- mov eax, cr0
- or eax, 0C0000001h
- mov cr0, eax ;enable paging with cache disabled
- mov eax, GDT64_table
- mov dword [GDT_value+2], eax
- lgdt [GDT_value] ;read 80 bit address
- jmp @f
- nop
- @@: jmp CODE_LONG:@f
- USE64
- @@: xor eax, eax ;load long mode segments
- mov ax, DATA_LONG
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov rbx, qword [ebx+24]
- jmp rbx
- size: dd 0
- errstr: db "No COM1?", 13, 10, 0
- align 16
- GDT_table: dd 0, 0 ;null descriptor
- DATA_PROT = $-GDT_table
- dd 0000FFFFh,008F9200h ;flat ds
- CODE_PROT = $-GDT_table
- dd 0000FFFFh,00CF9A00h ;32 bit prot mode ring0 cs
- GDT_value: dw $-GDT_table
- dd GDT_table
- GDT64_table:dd 0,0
- CODE_LONG = $-GDT_table
- dd 0000FFFFh,00809200h
- DATA_LONG = $-GDT_table
- dd 0000FFFFh,00209800h
- if ~defined OPTIONROM
- ;padding and magic
- db 01FEh-($-$$) dup 0
- db 55h,0AAh
- end if
|