From e66adcca9dc3d03949f163236f6f09bbe45a7c23 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 22 Nov 2023 05:25:09 -0800 Subject: [PATCH 1/3] Cleaned up genInitMem script to only generate necessary files and eliminate prompts --- linux/testvector-generation/genInitMem.sh | 109 ++++++++++------------ 1 file changed, 50 insertions(+), 59 deletions(-) diff --git a/linux/testvector-generation/genInitMem.sh b/linux/testvector-generation/genInitMem.sh index d34b758f8..b9c1d8c41 100755 --- a/linux/testvector-generation/genInitMem.sh +++ b/linux/testvector-generation/genInitMem.sh @@ -10,63 +10,54 @@ rawUntrimmedBootmemFile="$tvDir/untrimmedBootmemFileGDB.bin" untrimmedBootmemFile="$tvDir/untrimmedBootmemFile.bin" DEVICE_TREE=${imageDir}/wally-virt.dtb -read -p "Warning: running this script will overwrite the contents of: - * $rawRamFile - * $ramFile - * $rawBootmemFile - * $bootmemFile - * $rawUntrimmedBootmemFile - * $untrimmedBootmemFile -Would you like to proceed? (y/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - if [ ! -d "$tvDir" ]; then - echo "Error: linux testvector directory $tvDir not found!">&2 - echo "Please create it. For example:">&2 - echo " sudo mkdir -p $tvDir">&2 - exit 1 - fi - test -w $tvDir - if [ ! $? -eq 0 ]; then - echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2 - echo "Please chmod it. For example:">&2 - echo " sudo chmod -R a+rw $tvDir">&2 - exit 1 - fi - - echo "Launching QEMU in replay mode!" - (qemu-system-riscv64 \ - -M virt -m 256M -dtb $DEVICE_TREE \ - -nographic \ - -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ - -gdb tcp::$tcpPort -S) \ - & riscv64-unknown-elf-gdb --quiet \ - -ex "set pagination off" \ - -ex "set logging overwrite on" \ - -ex "set logging redirect on" \ - -ex "set confirm off" \ - -ex "target extended-remote :$tcpPort" \ - -ex "maintenance packet Qqemu.PhyMemMode:1" \ - -ex "printf \"Creating $rawBootmemFile\n\"" \ - -ex "dump binary memory $rawBootmemFile 0x1000 0x1fff" \ - -ex "printf \"Creating $rawUntrimmedBootmemFile\n\"" \ - -ex "printf \"Warning - please verify that the second half of $rawUntrimmedBootmemFile is all 0s\n\"" \ - -ex "dump binary memory $rawUntrimmedBootmemFile 0x1000 0x2fff" \ - -ex "printf \"Creating $rawRamFile\n\"" \ - -ex "dump binary memory $rawRamFile 0x80000000 0x8fffffff" \ - -ex "kill" \ - -ex "q" - - echo "Changing Endianness" - make fixBinMem - ./fixBinMem "$rawRamFile" "$ramFile" - ./fixBinMem "$rawBootmemFile" "$bootmemFile" - ./fixBinMem "$rawUntrimmedBootmemFile" "$untrimmedBootmemFile" - - echo "genInitMem.sh completed!" - echo "You may want to restrict write access to $tvDir now and give cad ownership of it." - echo "Run the following:" - echo " sudo chown -R cad:cad $tvDir" - echo " sudo chmod -R go-w $tvDir" +if [ ! -d "$tvDir" ]; then + echo "Error: linux testvector directory $tvDir not found!">&2 + echo "Please create it. For example:">&2 + echo " sudo mkdir -p $tvDir">&2 + exit 1 fi +test -w $tvDir +if [ ! $? -eq 0 ]; then + echo "Error: insuffcient write privileges for linux testvector directory $tvDir !">&2 + echo "Please chmod it. For example:">&2 + echo " sudo chmod -R a+rw $tvDir">&2 + exit 1 +fi + +echo "Launching QEMU in replay mode!" +(qemu-system-riscv64 \ +-M virt -m 256M -dtb $DEVICE_TREE \ +-nographic \ +-bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ +-gdb tcp::$tcpPort -S) \ +& riscv64-unknown-elf-gdb --quiet \ +-ex "set pagination off" \ +-ex "set logging overwrite on" \ +-ex "set logging redirect on" \ +-ex "set confirm off" \ +-ex "target extended-remote :$tcpPort" \ +-ex "maintenance packet Qqemu.PhyMemMode:1" \ +-ex "printf \"Creating $rawBootmemFile\n\"" \ +-ex "dump binary memory $rawBootmemFile 0x1000 0x1fff" \ +-ex "printf \"Creating $rawRamFile\n\"" \ +-ex "dump binary memory $rawRamFile 0x80000000 0x8fffffff" \ +-ex "kill" \ +-ex "q" + +#-ex "printf \"Warning - please verify that the second half of $rawUntrimmedBootmemFile is all 0s\n\"" \ +#-ex "printf \"Creating $rawUntrimmedBootmemFile\n\"" \ +#-ex "dump binary memory $rawUntrimmedBootmemFile 0x1000 0x2fff" \ + +echo "Changing Endianness" +make fixBinMem +./fixBinMem "$rawRamFile" "$ramFile" +./fixBinMem "$rawBootmemFile" "$bootmemFile" +#./fixBinMem "$rawUntrimmedBootmemFile" "$untrimmedBootmemFile" # doesn't seem to be used for anything +rm -f "$rawRamFile" "$rawBootmemFile" "$rawUntrimmedBootmemFile" + +echo "genInitMem.sh completed!" +echo "You may want to restrict write access to $tvDir now and give cad ownership of it." +echo "Run the following:" +echo " sudo chown -R cad:cad $tvDir" +echo " sudo chmod -R go-w $tvDir" + From c64ad9ff355db32e521b2b5af86c0e7c0db6e92a Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 22 Nov 2023 06:28:38 -0800 Subject: [PATCH 2/3] Extract rootfs during disassembly --- linux/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linux/Makefile b/linux/Makefile index a2cded5ea..cc19c7f2a 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -67,6 +67,10 @@ disassemble: find $(BUILDROOT)/output/build/linux-* -maxdepth 1 -name "vmlinux" | xargs cp -t $(BUILDROOT)/output/images/ mkdir -p $(DIS) make -j $(OBJDUMPS) + # extract rootfs + mkdir -p $(BUILDROOT)/output/images/disassembly/rootfs + echo "Ignore error about dev/console when extracting rootfs from rootfs.cpio" + -cpio -i -D $(BUILDROOT)/output/images/disassembly/rootfs < $(BUILDROOT)/output/images/rootfs.cpio $(DIS)/%.objdump: $(IMAGES)/%.elf riscv64-unknown-elf-objdump -DS $< >> $@ From 1d234c05c99bb1679c8a26140915cb90b7a22cf6 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 22 Nov 2023 22:17:01 -0800 Subject: [PATCH 3/3] disassembleBootTrace works on first 50M lines of boot --- .gitignore | 2 + linux/bootmem.txt | 2 +- .../disassembleBootTrace.py | 74 +++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100755 linux/testvector-generation/disassembleBootTrace.py diff --git a/.gitignore b/.gitignore index 3990c3823..f0afc3a98 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,8 @@ tests/linux-testgen/buildroot-image-output tests/linux-testgen/buildroot-config-src/main.config.old tests/linux-testgen/buildroot-config-src/linux.config.old tests/linux-testgen/buildroot-config-src/busybox.config.old +linux/testvector-generation/boottrace.S +linux/testvector-generation/boottrace_disasm.log sim/slack-notifier/slack-webhook-url.txt sim/logs fpga/generator/IP diff --git a/linux/bootmem.txt b/linux/bootmem.txt index 047cf5529..7cf7d8453 100644 --- a/linux/bootmem.txt +++ b/linux/bootmem.txt @@ -5,7 +5,7 @@ 00001010: 0182b283 ld t0, 24(t0) # t0 = 80000000 - start of firmware 00001014: 00028067 jr t0 # jump to firmware 00001018: 0000000080000000 # firmware start address -00001020: 0000000087000000 # flattened device tree load address +00001020: 000000008fe00000 # flattened device tree load address 00001028: 000000004942534f # a2 points to this 8 dword data structure 00001030: 0000000000000002 00001038: 0000000080200000 diff --git a/linux/testvector-generation/disassembleBootTrace.py b/linux/testvector-generation/disassembleBootTrace.py new file mode 100755 index 000000000..12e2202cb --- /dev/null +++ b/linux/testvector-generation/disassembleBootTrace.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 +# +# disassembleBootTrace.py +# David_Harris@hmc.edu 22 November 2023 +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# +# Reads boottrace.log and disassembles the machine code +# + +import csv +import os +import re + +# read a file from sim/logs/boottrace.log and extract the second comma-separated field containing the instruction +print("Reading boottrace.log") +trace = [] +count = 0 +with open('../../sim/logs/boottrace.log') as f: + reader = csv.reader(f, delimiter=',') + for row in reader: + trace.append(row) + count = count + 1 + if count > 50000000: + break +f.close() + +print("Disassembling boottrace.log instructions") +# Write an assembly language file with the machine code +with (open('boottrace.S', 'w')) as f: + f.write('main:\n') + for row in trace: + instr = row[1] + # scrape off leading white space from instr + instr = instr.lstrip() + # check if last character indicates an compressed or uncompressed instruction + lastNibble = instr[-1] + if (lastNibble == '3' or lastNibble == '7' or lastNibble == 'b' or lastNibble == 'f'): + # uncompressed + f.write('.word 0x' + instr + '\n') + else: + # compressed + instr = instr[-4:] + f.write('.hword 0x' + instr + '\n') +f.close() + +# Then assemble and disassemble the file +os.system('riscv64-unknown-elf-gcc -march=rv64gqc_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64d -c boottrace.S') +os.system('riscv64-unknown-elf-objdump -D boottrace.o > boottrace.objdump') + +# Patch disassembly back into boottrace +print("Inserting disassembly into trace") +dumpedLines = [] +with (open('boottrace.objdump', 'r')) as f: + lines = f.readlines() + f.close() +lines = lines[7:] # skip header +p = r'[^:]*:\s*(\S*)\s*(.*)' +for line in lines: + match = re.search(p, line) + if (match): + dump = [match.group(1), match.group(2)] + dumpedLines.append(dump) + +linenum = 0 +for i in range(len(trace)): + row = trace[i] + row.insert(2, dumpedLines[i][1]) + +# write trace back to csv file +print("Writing trace back to boottrace_disasm.log") +with (open('boottrace_disasm.log', 'w')) as f: + writer = csv.writer(f) + writer.writerows(trace) +f.close()