github.com/transparency-dev/armored-witness-os@v0.1.3-0.20240514084412-27eef7325168/trusted_os/storage_debug.go (about) 1 // Copyright 2023 The Armored Witness OS authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build fake_storage 16 // +build fake_storage 17 18 package main 19 20 import ( 21 "fmt" 22 "log" 23 24 usbarmory "github.com/usbarmory/tamago/board/usbarmory/mk2" 25 "github.com/usbarmory/tamago/soc/nxp/imx6ul" 26 "github.com/usbarmory/tamago/soc/nxp/usdhc" 27 ) 28 29 const ( 30 // fakeCardBlockSize is the number of bytes in a single memory block. 31 fakeCardBlockSize = int64(512) 32 // fakeCardNumBlocks defines the claimed size of the storage. 33 fakeCardNumBlocks = int64(4<<30) / fakeCardBlockSize 34 ) 35 36 // storage will return MMC backed storage if running on real hardware, or 37 // a fake in-memory storage device otherwise. 38 func storage() Card { 39 if imx6ul.Native { 40 return usbarmory.MMC 41 } 42 return newFakeCard(fakeCardNumBlocks) 43 } 44 45 // fakeCard is an implementation of an in-memory storage device. 46 // 47 // Rather than allocating a slab of RAM to emulate the entire device, it 48 // uses a map internally to associate slices (<= fakeCardBlockSize bytes) 49 // with sector numbers - this allows us to save RAM on unused/unwritten blocks. 50 type fakeCard struct { 51 info usdhc.CardInfo 52 mem map[int64][]byte 53 } 54 55 // Read returns size bytes at offset in the fake storage 56 func (fc *fakeCard) Read(offset int64, size int64) ([]byte, error) { 57 l := int64(fakeCardNumBlocks * fakeCardBlockSize) 58 if offset >= l { 59 return nil, fmt.Errorf("offset (%d) past end of storage (%d)", offset, l) 60 } 61 if offset+size > l { 62 size = l - offset 63 } 64 if offset%fakeCardBlockSize != 0 { 65 panic(fmt.Sprintf("non sector-aligned read at %d", offset)) 66 } 67 r := make([]byte, size) 68 base := offset / fakeCardBlockSize 69 for i, rem := int64(0), size; rem > 0; i, rem = i+1, rem-fakeCardBlockSize { 70 copy(r[i*fakeCardBlockSize:], fc.mem[base+i]) 71 } 72 return r, nil 73 } 74 75 func (fc *fakeCard) WriteBlocks(lba int, b []byte) error { 76 if l := fakeCardNumBlocks; int64(lba) >= l { 77 return fmt.Errorf("lba (%d) >= device blocks (%d)", lba, l) 78 } 79 // If the data isn't a multiple of the blocksize, pad it up 80 // so that it is. 81 if r := int64(len(b)) % fakeCardBlockSize; r != 0 { 82 b = append(b, make([]byte, fakeCardBlockSize-r)...) 83 } 84 for i, rem := int64(0), int64(len(b)); rem > 0; i, rem = i+1, rem-fakeCardBlockSize { 85 buf := make([]byte, fakeCardBlockSize) 86 copy(buf, b[i*fakeCardBlockSize:]) 87 fc.mem[int64(lba)+i] = buf 88 } 89 return nil 90 } 91 92 func (fc *fakeCard) Info() usdhc.CardInfo { 93 return fc.info 94 } 95 96 func (fc *fakeCard) Detect() error { 97 log.Println("Using fake MMC storage") 98 return nil 99 } 100 101 // newFakeCard creates a new in-memory block device. 102 func newFakeCard(numBlocks int64) *fakeCard { 103 return &fakeCard{ 104 mem: make(map[int64][]byte), 105 info: usdhc.CardInfo{ 106 BlockSize: int(fakeCardBlockSize), 107 Blocks: int(numBlocks), 108 }, 109 } 110 }