boot2

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

hex1.hex0 (18971B)


      1 ## Copyright (C) 2017 Jeremiah Orians
      2 ## Copyright (C) 2020 Sanne Wouda
      3 ## This file is part of stage0.
      4 ##
      5 ## stage0 is free software: you can redistribute it and/or modify
      6 ## it under the terms of the GNU General Public License as published by
      7 ## the Free Software Foundation, either version 3 of the License, or
      8 ## (at your option) any later version.
      9 ##
     10 ## stage0 is distributed in the hope that it will be useful,
     11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 ## GNU General Public License for more details.
     14 ##
     15 ## You should have received a copy of the GNU General Public License
     16 ## along with stage0.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 ## ELF Header
     19 
     20 #:ELF_base
     21 
     22 7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number
     23 
     24 02                             # e_ident[EI_CLASS] Indicating 64 bit
     25 01                             # e_ident[EI_DATA] Indicating little endianness
     26 01                             # e_ident[EI_VERSION] Indicating original elf
     27 
     28 03                             # e_ident[EI_OSABI] Set at 0 because none cares
     29 00                             # e_ident[EI_ABIVERSION] See above
     30 
     31 00 00 00 00 00 00 00           # e_ident[EI_PAD]
     32 02 00                          # e_type Indicating Executable
     33 B7 00                          # e_machine Indicating AArch64
     34 01 00 00 00                    # e_version Indicating original elf
     35 
     36 78 00 60 00 00 00 00 00          # e_entry Address of the entry point
     37 40 00 00 00 00 00 00 00 # e_phoff Address of program header table
     38 00 00 00 00 00 00 00 00 # e_shoff Address of section header table
     39 
     40 00 00 00 00                    # e_flags
     41 40 00                          # e_ehsize Indicating our 64 Byte header
     42 
     43 38 00                          # e_phentsize size of a program header table
     44 01 00                          # e_phnum number of entries in program table
     45 
     46 00 00                          # e_shentsize size of a section header table
     47 00 00                          # e_shnum number of entries in section table
     48 
     49 00 00                          # e_shstrndx index of the section names
     50 
     51 ## Program Header
     52 #:ELF_program_headers
     53 01 00 00 00                   # ph_type: PT-LOAD = 1
     54 07 00 00 00                   # ph_flags: PF-X|PF-W|PF-R = 7
     55 00 00 00 00 00 00 00 00                   # ph_offset
     56 00 00 60 00 00 00 00 00                     # ph_vaddr
     57 00 00 60 00 00 00 00 00                     # ph_physaddr
     58 3D 04 00 00 00 00 00 00             # ph_filesz
     59 3D 04 00 00 00 00 00 00             # ph_memsz
     60 01 00 00 00 00 00 00 00                   # ph_align
     61 
     62 #:ELF_text
     63 
     64 # Where the ELF Header is going to hit
     65 # Simply jump to _start
     66 # Our main function
     67 #:_start
     68     E10B40F9                    ; LDR_X1_[SP,16]              # Get the actual input name
     69     600C8092                    ; SET_X0_TO_FCNTL_H_AT_FDCWD  # AT_FDCWD, relative to current working directory
     70     020080D2                    ; SET_X2_TO_0                 # Prepare file as read only
     71     080780D2                    ; SET_X8_TO_SYS_OPENAT        # The syscall number for openat(), aarch64 has no open()
     72     010000D4                    ; SYSCALL                     # Open file!
     73     E90300AA                    ; SET_X9_FROM_X0              # Preserve the file pointer we were given
     74 
     75     E10F40F9                    ; LDR_X1_[SP,24]              # Get the output name
     76     600C8092                    ; SET_X0_TO_FCNTL_H_AT_FDCWD  # AT_FDCWD, relative to current working directory
     77     224880D2                    ; SET_X2_TO_577               # Prepare file as O_WRONLY|O_CREAT|O_TRUNC
     78     033880D2                    ; SET_X3_TO_448               # Prepare file as RWX for owner only (700 in octal)
     79     080780D2                    ; SET_X8_TO_SYS_OPENAT        # The syscall number for openat(), aarch64 has no open()
     80     010000D4                    ; SYSCALL                     # Open file!
     81     EA0300AA                    ; SET_X10_FROM_X0             # Preserve the file pointer we were given
     82 
     83     0F008092                    ; SET_X15_TO_MINUS_1          # Our flag for byte processing
     84     0E0080D2                    ; SET_X14_TO_0                # temp storage for the sum
     85     0D0CA0D2                    ; SET_X13_TO_0x600000         # Our starting IP
     86     0D0000 94                   ; ^~First_pass CALL           # Process it
     87 
     88     # rewind input file
     89     E00309AA                    ; SET_X0_FROM_X9              # Using our input file
     90     010080D2                    ; SET_X1_TO_0                 # Offset
     91     020080D2                    ; SET_X2_TO_0                 # Whence SEEK_SET
     92     C80780D2                    ; SET_X8_TO_SYS_LSEEK         # lseek
     93     010000D4                    ; SYSCALL
     94 
     95     0F008092                    ; SET_X15_TO_MINUS_1          # Our flag for byte processing
     96     0E0080D2                    ; SET_X14_TO_0                # temp storage for the sum
     97     0D0CA0D2                    ; SET_X13_TO_0x600000         # Our starting IP
     98     2E0000 94                   ; ^~Second_pass CALL          # Process it
     99 
    100     # program competed Successfully
    101     000080D2                    ; SET_X0_TO_0                 # All is well
    102     A80B80D2                    ; SET_X8_TO_SYS_EXIT          # put the exit syscall number in x8
    103     010000D4                    ; SYSCALL
    104 
    105 #:First_pass
    106     FE0F1FF8                    ; PUSH_LR                     # push lr
    107 
    108 #:First_pass_loop
    109     880000 94                   ; ^~Read_byte CALL
    110 
    111     # Deal with EOF
    112     1F1000B1                    ; CMP_X0_TO_MINUS_4
    113     41000054                    ; SKIP_INST_NE
    114     240000 14                   ; ^~First_pass_done BRANCH
    115 
    116     # Check for :
    117     1FE800F1                    ; CMP_X0_TO_58
    118     40000054                    ; SKIP_INST_EQ
    119     020000 14                   ; ^~First_pass_0 BRANCH
    120 
    121     # Deal with label
    122     A10000 94                   ; ^~StoreLabel CALL
    123 
    124 #:First_pass_0
    125     # Check for $
    126     1F9000F1                        ; CMP_X0_TO_36
    127     41000054                        ; SKIP_INST_NE
    128     140000 14                       ; ^~First_pass_abs16pointer BRANCH
    129 
    130     # Check for ~
    131     1FF801F1                        ; CMP_X0_TO_126
    132     41000054                        ; SKIP_INST_NE
    133     140000 14                       ; ^~First_pass_rel24pointer BRANCH
    134 
    135     # Check for &
    136     1F9800F1                        ; CMP_X0_TO_38
    137     41000054                        ; SKIP_INST_NE
    138     140000 14                       ; ^~First_pass_abs32pointer BRANCH
    139 
    140     # Deal with everything else
    141     4A0000 94                   ; ^~hex CALL                  # Process our char
    142 
    143     # Deal with EOF
    144     1F1000B1                    ; CMP_X0_TO_MINUS_4
    145     41000054                    ; SKIP_INST_NE
    146     130000 14                   ; ^~First_pass_done BRANCH
    147 
    148     # deal with -1 values
    149     1F0000F1                    ; CMP_X0_TO_0
    150     4A000054                    ; SKIP_INST_GE
    151     E9FFFF 17                   ; ^~First_pass_loop RBRANCH
    152 
    153     # deal with toggle
    154     FF0100F1                    ; CMP_X15_TO_0
    155     41000054                    ; SKIP_INST_NE
    156     020000 14                   ; ^~First_pass_1 BRANCH
    157     AD050091                    ; ADD_X13_1                   # Increment IP
    158 
    159 #:First_pass_1
    160     EF032FAA                    ; NOT_X15                     # Flip toggle
    161     E3FFFF 17                   ; ^~First_pass_loop RBRANCH
    162 
    163 #:First_pass_abs16pointer
    164     # Deal with 16-bit Pointer to label
    165     6A0000 94                   ; ^~Read_byte CALL            # Drop the char
    166     AD090091                    ; ADD_X13_2                   # Increment IP
    167     E0FFFF 17                   ; ^~First_pass_loop RBRANCH    # Loop again
    168 
    169 #:First_pass_rel24pointer
    170     # Deal with 24-bit Pointer to label
    171     670000 94                   ; ^~Read_byte CALL            # Drop the char
    172     AD0D0091                    ; ADD_X13_3                   # Increment IP
    173     DDFFFF 17                   ; ^~First_pass_loop RBRANCH    # Loop again
    174 
    175 #:First_pass_abs32pointer
    176     # Deal with 32-bit Pointer to label
    177     640000 94                   ; ^~Read_byte CALL            # Drop the char
    178     AD110091                    ; ADD_X13_4                   # Increment IP
    179     DAFFFF17                    ; ^~First_pass_loop RBRANCH    # Loop again
    180 
    181 #:First_pass_done
    182     FE0741F8                    ; POP_LR
    183     C0035FD6                    ; RETURN
    184 
    185 #:Second_pass
    186     FE0F1FF8                    ; PUSH_LR                     # push lr
    187 
    188 #:Second_pass_loop
    189     5E0000 94                   ; ^~Read_byte CALL
    190 
    191     # Deal with EOF
    192     1F1000B1                    ; CMP_X0_TO_MINUS_4
    193     41000054                    ; SKIP_INST_NE
    194     2C0000 14                   ; ^~Second_pass_done BRANCH
    195 
    196     # Simply drop the label
    197     1FE800F1                    ; CMP_X0_TO_58
    198     40000054                    ; SKIP_INST_EQ
    199     030000 14                   ; ^~Second_pass_0 BRANCH
    200     570000 94                   ; ^~Read_byte CALL
    201     F8FFFF 17                   ; ^~Second_pass_loop RBRANCH
    202 
    203 #:Second_pass_0
    204     # Check for $
    205     1F9000F1                        ; CMP_X0_TO_36
    206     41000054                        ; SKIP_INST_NE
    207     140000 14                       ; ^~Second_pass_abs16pointer BRANCH
    208 
    209     # Check for ~, assume preceded by ^
    210     1FF801F1                        ; CMP_X0_TO_126
    211     41000054                        ; SKIP_INST_NE
    212     130000 14                       ; ^~Second_pass_rel24pointer BRANCH
    213 
    214     # Check for $
    215     1F9800F1                        ; CMP_X0_TO_38
    216     41000054                        ; SKIP_INST_NE
    217     120000 14                       ; ^~Second_pass_abs32pointer BRANCH
    218 
    219     # Deal with everything else
    220     1F0000 94                   ; ^~hex CALL                  # Process our char
    221 
    222     # Deal with EOF
    223     1F1000B1                    ; CMP_X0_TO_MINUS_4
    224     41000054                    ; SKIP_INST_NE
    225     1A0000 14                   ; ^~Second_pass_done BRANCH
    226 
    227     # deal with -1 values
    228     1F0000F1                    ; CMP_X0_TO_0
    229     4A000054                    ; SKIP_INST_GE
    230     E8FFFF 17                   ; ^~Second_pass_loop RBRANCH
    231 
    232     # deal with toggle
    233     FF0100F1                    ; CMP_X15_TO_0
    234     41000054                    ; SKIP_INST_NE
    235     0A0000 14                   ; ^~print BRANCH
    236 
    237     # process first byte of pair
    238     EE0300AA                    ; SET_X14_FROM_X0
    239     0F0080D2                    ; SET_X15_TO_0
    240     E2FFFF 17                   ; ^~Second_pass_loop RBRANCH
    241 
    242 #:Second_pass_abs16pointer
    243     640000 94                   ; ^~StoreAbs16Pointer CALL
    244     E0FFFF 17                   ; ^~Second_pass_loop RBRANCH
    245 
    246 #:Second_pass_rel24pointer
    247     6E0000 94                   ; ^~StoreRel24Pointer CALL
    248     DEFFFF 17                   ; ^~Second_pass_loop RBRANCH
    249 
    250 #:Second_pass_abs32pointer
    251     7A0000 94                   ; ^~StoreAbs32Pointer CALL
    252     DCFFFF 17                   ; ^~Second_pass_loop RBRANCH
    253 
    254 # process second byte of pair
    255 #:print
    256     # update the sum and store in output
    257     00100E8B                    ; ADD_X0_X0_X14_LSL_4
    258     41000018                    ; LOAD_W1_AHEAD
    259     02000014                    ; SKIP_32_DATA
    260     3C04 6000                   ; &table
    261     20000039                    ; STR_BYTE_W0_[X1]
    262 
    263     # flip the toggle
    264     0F008092                    ; SET_X15_TO_MINUS_1
    265 
    266     # print our first Hex
    267     220080D2                    ; SET_X2_TO_1                 # set the size of chars we want
    268     430000 94                   ; ^~print_chars CALL
    269 
    270     AD050091                    ; ADD_X13_1                   # Increment IP
    271     D2FFFF 17                   ; ^~Second_pass_loop RBRANCH
    272 
    273 #:Second_pass_done
    274     FE0741F8                    ; POP_LR                      # pop lr
    275     C0035FD6                    ; RETURN
    276 
    277 #:hex
    278     # deal with EOF
    279     1F1000B1                	; CMP_X0_TO_MINUS_4
    280     41000054                	; SKIP_INST_NE
    281     2A0000 14                	; ^~EOF BRANCH
    282 
    283     # Purge Comment Lines (#)
    284     1F8C00F1                	; CMP_X0_TO_35
    285     41000054                	; SKIP_INST_NE
    286     170000 14      	            ; ^~purge_comment BRANCH
    287 
    288     # Purge Comment Lines (;)
    289     1FEC00F1                	; CMP_X0_TO_59
    290     41000054                	; SKIP_INST_NE
    291     140000 14      	            ; ^~purge_comment BRANCH
    292 
    293     # deal all ascii less than 0
    294     1FC000F1                	; CMP_X0_TO_48
    295     4A000054                	; SKIP_INST_GE
    296     1F0000 14        	        ; ^~ascii_other BRANCH
    297 
    298     # deal with 0-9
    299     1FE800F1                	; CMP_X0_TO_58
    300     4A000054                	; SKIP_INST_GE
    301     160000 14          	        ; ^~ascii_num BRANCH
    302 
    303     # deal with all ascii less than A
    304     1F0401F1                	; CMP_X0_TO_65
    305     4A000054                	; SKIP_INST_GE
    306     190000 14        	        ; ^~ascii_other BRANCH
    307 
    308     # deal with A-F
    309     1F1C01F1                	; CMP_X0_TO_71
    310     4A000054                	; SKIP_INST_GE
    311     140000 14         	        ; ^~ascii_high BRANCH
    312 
    313     # deal with all ascii less than a
    314     1F8401F1                	; CMP_X0_TO_97
    315     4A000054                	; SKIP_INST_GE
    316     130000 14        	        ; ^~ascii_other BRANCH
    317 
    318     # deal with a-f
    319     1F9C01F1                	; CMP_X0_TO_103
    320     4A000054                	; SKIP_INST_GE
    321     0C0000 14          	        ; ^~ascii_low BRANCH
    322 
    323     # The rest that remains needs to be ignored
    324     0F0000 14        	        ; ^~ascii_other BRANCH
    325 
    326 #:purge_comment
    327     FE0F1FF8                    ; PUSH_LR                     # push lr
    328 
    329 #:loop0
    330     # Read a byte
    331     100000 94                   ; ^~Read_byte CALL
    332 
    333     # Loop if not LF
    334     1F2800F1                    ; CMP_X0_TO_10
    335     40000054                    ; SKIP_INST_EQ
    336     FDFFFF 17                   ; ^~loop0 RBRANCH
    337 
    338     # Otherwise return -1
    339     00008092                    ; SET_X0_TO_MINUS_1
    340 
    341     FE0741F8                    ; POP_LR                      # pop lr
    342     C0035FD6                    ; RETURN
    343 
    344 #:ascii_num
    345     00C000D1                    ; SUB_X0_48
    346     C0035FD6                    ; RETURN
    347 
    348 #:ascii_low
    349     005C01D1                    ; SUB_X0_87
    350     C0035FD6                    ; RETURN
    351 
    352 #:ascii_high
    353     00DC00D1                    ; SUB_X0_55
    354     C0035FD6                    ; RETURN
    355 
    356 #:ascii_other
    357     00008092                    ; SET_X0_TO_MINUS_1
    358     C0035FD6                    ; RETURN
    359 
    360 #:EOF
    361     C0035FD6                    ; RETURN
    362 
    363 #:Read_byte
    364     # Attempt to read 1 byte from input file
    365     E00309AA        			; SET_X0_FROM_X9              # Where are we reading from
    366     41000018        			; LOAD_W1_AHEAD               # Where to put it
    367     02000014        			; SKIP_32_DATA
    368     3C04 6000     			    ; &table
    369     220080D2        			; SET_X2_TO_1                 # set the size of chars we want
    370     E80780D2        			; SET_X8_TO_SYS_READ          # the syscall number for read
    371     010000D4        			; SYSCALL                     # call the Kernel
    372 
    373     1F0000F1        			; CMP_X0_TO_0
    374     41000054        			; SKIP_INST_NE
    375     060000 14			        ; ^~Read_byte_1 BRANCH
    376 
    377     # load byte
    378     40000098        			; LOAD_W0_AHEAD
    379     02000014        			; SKIP_32_DATA
    380     3C04 6000     			    ; &table
    381     00004039        			; LDR_BYTE_W0_[X0]            # load char, unsigned so zero-extended already
    382     C0035FD6        			; RETURN
    383 
    384 # Deal with EOF
    385 #:Read_byte_1
    386     60008092                    ; SET_X0_TO_MINUS_4           # Put EOF in x0
    387     C0035FD6                    ; RETURN
    388 
    389 #:print_chars
    390     E0030AAA   					; SET_X0_FROM_X10             # Write to target file
    391     41000018   					; LOAD_W1_AHEAD               # What we are writing
    392     02000014   					; SKIP_32_DATA
    393     3C04 6000					; &table
    394     080880D2   					; SET_X8_TO_SYS_WRITE         # the syscall number for write
    395     010000D4   					; SYSCALL                     # call the Kernel
    396     C0035FD6   					; RETURN
    397 
    398 #:Get_table_target
    399     FE0F1FF8      				; PUSH_LR                     # push lr
    400     E7FFFF 97				    ; ^~Read_byte RCALL           # Get single char label
    401     41000018      				; LOAD_W1_AHEAD
    402     02000014      				; SKIP_32_DATA
    403     3C04 6000   				; &table
    404     200C008B      				; ADD_X0_X1_X0_LSL_3          # Each label in table takes 8 bytes to store
    405     FE0741F8      				; POP_LR                      # pop lr
    406     C0035FD6      				; RETURN
    407 
    408 #:StoreLabel
    409     FE0F1FF8             		; PUSH_LR
    410     F7FFFF 97		            ; ^~Get_table_target RCALL
    411     0D0000F9             		; STR_X13_[X0]
    412     FE0741F8             		; POP_LR
    413     C0035FD6             		; RETURN
    414 
    415 #:StoreAbs16Pointer
    416     FE0F1FF8             		; PUSH_LR                     # push lr
    417     F2FFFF 97		            ; ^~Get_table_target RCALL    # Get address of pointer
    418     000040F9             		; DEREF_X0                    # Get pointer
    419     41000018             		; LOAD_W1_AHEAD
    420     02000014             		; SKIP_32_DATA
    421     3C04 6000          		    ; &table
    422     200000F9             		; STR_X0_[X1]                 # put value in output
    423     AD090091             		; ADD_X13_2                   # Increment IP
    424     420080D2             		; SET_X2_TO_2                 # set the size of chars we want
    425     E3FFFF 97     		        ; ^~print_chars RCALL
    426     FE0741F8             		; POP_LR                      # pop lr
    427     C0035FD6             		; RETURN
    428 
    429 #:StoreRel24Pointer
    430     FE0F1FF8             		; PUSH_LR                     # push lr
    431     E6FFFF 97		            ; ^~Get_table_target RCALL    # Get address of pointer
    432     000040F9             		; DEREF_X0                    # Get pointer
    433     00000DCB             		; SUB_X0_X0_X13               # target - ip
    434     00FC4293             		; ASR_X0_X0_2                 # rel24 pointer is 4-byte aligned
    435     41000018             		; LOAD_W1_AHEAD
    436     02000014             		; SKIP_32_DATA
    437     3C04 6000           		; &table
    438     200000F9             		; STR_X0_[X1]                 # put value in output
    439     AD0D0091             		; ADD_X13_3                   # Increment IP
    440     620080D2             		; SET_X2_TO_3                 # set the size of chars we want
    441     D5FFFF 97            		; ^~print_chars RCALL
    442     FE0741F8             		; POP_LR                      # pop lr
    443     C0035FD6             		; RETURN
    444 
    445 #:StoreAbs32Pointer
    446     FE0F1FF8             		; PUSH_LR                     # push lr
    447     D8FFFF 97		            ; ^~Get_table_target RCALL    # Get address of pointer
    448     000040F9             		; DEREF_X0                    # Get pointer
    449     41000018             		; LOAD_W1_AHEAD
    450     02000014             		; SKIP_32_DATA
    451     3C04 6000          		    ; &table
    452     200000F9             		; STR_X0_[X1]                 # put value in output
    453     AD110091             		; ADD_X13_4                   # Increment IP
    454     820080D2             		; SET_X2_TO_4                 # set the size of chars we want
    455     C9FFFF 97     		        ; ^~print_chars RCALL
    456     FE0741F8             		; POP_LR                      # pop lr
    457     C0035FD6             		; RETURN
    458 
    459 
    460 #:ELF_data
    461 #:table
    462     00                          ; NULL8
    463 
    464 #:ELF_end