boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

catm.hex2 (6231B)


      1 ## Copyright (C) 2021 Andrius Štikonas
      2 ## This file is part of stage0.
      3 ##
      4 ## stage0 is free software: you can redistribute it and/or modify
      5 ## it under the terms of the GNU General Public License as published by
      6 ## the Free Software Foundation, either version 3 of the License, or
      7 ## (at your option) any later version.
      8 ##
      9 ## stage0 is distributed in the hope that it will be useful,
     10 ## but WITHOUT ANY WARRANTY# without even the implied warranty of
     11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 ## GNU General Public License for more details.
     13 ##
     14 ## You should have received a copy of the GNU General Public License
     15 ## along with stage0.  If not, see <http://www.gnu.org/licenses/>.
     16 
     17 
     18 ## ELF Header
     19 
     20 :ELF_base
     21 7F 45 4C 46        ## e_ident[EI_MAG0-3] ELF's magic number
     22 
     23 02                 ## e_ident[EI_CLASS] Indicating 64 bit
     24 01                 ## e_ident[EI_DATA] Indicating little endianness
     25 01                 ## e_ident[EI_VERSION] Indicating original elf
     26 
     27 03                 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
     28 00                 ## e_ident[EI_ABIVERSION] Set at 0 because none cares
     29 
     30 00 00 00 00 00 00 00 ## e_ident[EI_PAD]
     31 02 00              ## e_type Indicating Executable
     32 F3 00              ## e_machine Indicating RISC-V
     33 01 00 00 00        ## e_version Indicating original elf
     34 
     35 &_start 00 00 00 00 ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
     36 %ELF_program_headers>ELF_base 00 00 00 00 ## e_phoff Address of program header table
     37 00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
     38 
     39 00 00 00 00        ## e_flags
     40 40 00              ## e_ehsize Indicating our 64 Byte header
     41 
     42 38 00              ## e_phentsize size of a program header table
     43 01 00              ## e_phnum number of entries in program table
     44 
     45 00 00              ## e_shentsize size of a section header table
     46 00 00              ## e_shnum number of entries in section table
     47 
     48 00 00              ## e_shstrndx index of the section names
     49 
     50 ## Program Header
     51 :ELF_program_headers
     52 01 00 00 00             ## p_type
     53 07 00 00 00             ## ph_flags: PF-X|PF-W|PF-R = 7
     54 00 00 00 00 00 00 00 00 ## p_offset
     55 
     56 &ELF_base 00 00 00 00 ## p_vaddr
     57 &ELF_base 00 00 00 00 ## p_physaddr
     58 
     59 %ELF_end>ELF_base 00 00 00 00 ## p_filesz
     60 %ELF_end>ELF_base 00 00 00 00 ## p_memsz
     61 
     62 01 00 00 00 00 00 00 00 ## Required alignment
     63 
     64 :ELF_text
     65 
     66 ; Simply jump to _start
     67 ; Our main function
     68 :_start
     69 
     70 # Register use:
     71 # s1: output file descriptor
     72 # s2: buffer
     73 # s3: input file descriptor
     74 # s4: number of bytes read
     75 
     76 # Open output file and store the FD in s1
     77     # rd_a7 !56 addi                    ; sys_openat
     78     .80080000 .00008003 13000000
     79     # rd_a0 !-100 addi                  ; AT_FDCWD
     80     .00050000 .0000C0F9 13000000
     81     # rd_sp rs1_sp !16 addi             ; Prepare stack for reading output file
     82     .00010000 .00000100 .00000001 13000000
     83     # rd_a1 rs1_sp ld                   ; Output file (argument 1)
     84     .80050000 .00000100 03300000
     85     # rd_a2 !577 addi                   ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC
     86     .00060000 .00001024 13000000
     87     # rd_a3 !384 addi                   ; Prepare file as RW for owner only (600 in octal)
     88     .80060000 .00000018 13000000
     89     # ecall                             ; syscall
     90     73000000
     91     # rd_s1 rs1_a0 addi                 ; Save fd in for later
     92     .80040000 .00000500 13000000
     93 
     94     # Prepare heap memory
     95     # rd_a7 !214 addi                   ; sys_brk
     96     .80080000 .0000600D 13000000
     97     # rd_a0 addi                        ; Get current brk
     98     .00050000 13000000
     99     # ecall                             ; syscall
    100     73000000
    101     # rd_s2 rs1_a0 addi                 ; Set our malloc pointer
    102     .00090000 .00000500 13000000
    103 
    104     # rd_a1 ~0x100000 lui               ; a1=1MiB
    105     .80050000 .00001000 37000000
    106     # rd_a0 rs1_a0 rs2_a1 add           ; Allocate 1MiB
    107     .00050000 .00000500 .0000B000 33000000
    108     # ecall                             ; syscall
    109     73000000
    110 
    111 :core
    112     # rd_sp rs1_sp !8 addi              ; Move stack pointer to next input file
    113     .00010000 .00000100 .00008000 13000000
    114     # rd_a1 rs1_sp ld                   ; Get the input file name
    115     .80050000 .00000100 03300000
    116     # rs1_a1 @Done beq                  ; This was the last file, we are done
    117     .00800500 @Done 63000000
    118 
    119     # rd_a7 !56 addi                    ; sys_openat
    120     .80080000 .00008003 13000000
    121     # rd_a0 !-100 addi                  ; AT_FDCWD
    122     .00050000 .0000C0F9 13000000
    123     # rd_a2 addi                        ; read only
    124     .00060000 13000000
    125     # ecall                             ; syscall
    126     73000000
    127     # rd_s3 rs1_a0 addi                 ; protect input fd
    128     .80090000 .00000500 13000000
    129 
    130 :keep
    131     # rd_a7 !63 addi                    ; sys_read
    132     .80080000 .0000F003 13000000
    133     # rd_a0 rs1_s3 addi                 ; input fd
    134     .00050000 .00800900 13000000
    135     # rd_a1 rs1_s2 addi                 ; read into buffer
    136     .80050000 .00000900 13000000
    137     # rd_a2 ~0x100000 lui               ; a2=1MiB
    138     .00060000 .00001000 37000000
    139     # ecall                             ; syscall
    140     73000000
    141     # rd_s4 rs1_a0 addi                 ; actual number of bytes read
    142     .000A0000 .00000500 13000000
    143 
    144     # rd_a7 !64 addi                    ; sys_write
    145     .80080000 .00000004 13000000
    146     # rd_a0 rs1_s1 addi                 ; output fd
    147     .00050000 .00800400 13000000
    148     # rd_a1 rs1_s2 addi                 ; write from buffer
    149     .80050000 .00000900 13000000
    150     # rd_a2 rs1_s4 addi                 ; number of bytes to write
    151     .00060000 .00000A00 13000000
    152     # ecall                             ; syscall
    153     73000000
    154 
    155     # rd_a2 ~0x100000 lui               ; 1MiB
    156     .00060000 .00001000 37000000
    157     # rs1_s4 rs2_a2 @keep beq           ; keep looping if buffer was full
    158     .00000A00 .0000C000 @keep 63000000
    159     # $core jal                         ; otherwise move to next file
    160     $core 6F000000
    161 
    162 :Done
    163     # Terminate program with 0 return code
    164     # rd_a7 !93 addi                    ; sys_exit
    165     .80080000 .0000D005 13000000
    166     # rd_a0 addi                        ; Return code 0
    167     .00050000 13000000
    168     # ecall                             ; exit(0)
    169     73000000
    170 
    171 :ELF_end