2026-05-02 23:04:46 +03:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
2026-05-23 08:52:52 +03:00
|
|
|
|
kvs_builder.py - Сборка ELF из CSV таблицы
|
|
|
|
|
|
Читает CSV, берёт колонки 'адрес' и 'рассчитанный_байт',
|
|
|
|
|
|
заполняет пропуски в адресах нулями и записывает выходной файл
|
2026-05-02 23:04:46 +03:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import sys
|
2026-05-23 08:52:52 +03:00
|
|
|
|
import csv
|
2026-05-02 23:04:46 +03:00
|
|
|
|
import os
|
2026-05-23 08:52:52 +03:00
|
|
|
|
import stat
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
|
|
|
|
|
|
def read_csv(csv_file):
|
|
|
|
|
|
"""Читает CSV и возвращает список адресов и байтов"""
|
|
|
|
|
|
addresses = []
|
|
|
|
|
|
bytes_list = []
|
|
|
|
|
|
|
|
|
|
|
|
with open(csv_file, 'r', encoding='utf-8') as f:
|
|
|
|
|
|
reader = csv.reader(f, delimiter=';')
|
|
|
|
|
|
headers = next(reader)
|
|
|
|
|
|
|
|
|
|
|
|
# Находим индексы нужных колонок
|
|
|
|
|
|
try:
|
|
|
|
|
|
addr_idx = headers.index('адрес')
|
|
|
|
|
|
byte_idx = headers.index('рассчитанный_байт')
|
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
|
print(f"Ошибка: не найдена нужная колонка в CSV: {e}")
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
for row in reader:
|
|
|
|
|
|
addr_str = row[addr_idx].strip()
|
|
|
|
|
|
byte_str = row[byte_idx].strip()
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
if addr_str and addr_str.startswith('0x'):
|
2026-05-02 23:04:46 +03:00
|
|
|
|
addr = int(addr_str, 16)
|
2026-05-23 08:52:52 +03:00
|
|
|
|
addresses.append(addr)
|
|
|
|
|
|
|
|
|
|
|
|
if byte_str and byte_str.startswith('0x'):
|
|
|
|
|
|
bytes_list.append(int(byte_str, 16))
|
|
|
|
|
|
else:
|
|
|
|
|
|
bytes_list.append(0)
|
|
|
|
|
|
|
|
|
|
|
|
return addresses, bytes_list
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
def build_file(addresses, bytes_list, output_file):
|
|
|
|
|
|
"""Собирает файл, заполняя пропуски в адресах нулями"""
|
|
|
|
|
|
if not addresses:
|
|
|
|
|
|
print("Нет данных для сборки")
|
|
|
|
|
|
return False
|
2026-05-17 11:22:39 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
# Определяем размер файла (максимальный адрес + 1)
|
|
|
|
|
|
max_addr = max(addresses)
|
|
|
|
|
|
file_size = max_addr + 1
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
# Создаём буфер, заполненный нулями
|
|
|
|
|
|
buffer = bytearray(file_size)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
# Заполняем байты по известным адресам
|
|
|
|
|
|
for addr, byte_val in zip(addresses, bytes_list):
|
|
|
|
|
|
buffer[addr] = byte_val
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
# Записываем файл
|
|
|
|
|
|
with open(output_file, 'wb') as f:
|
|
|
|
|
|
f.write(buffer)
|
2026-05-17 11:22:39 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
# Добавляем права на исполнение (chmod +x)
|
|
|
|
|
|
st = os.stat(output_file)
|
|
|
|
|
|
os.chmod(output_file, st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
if len(sys.argv) != 3:
|
|
|
|
|
|
print("Использование: python kvs_builder.py <входной.csv> <выходной.elf>")
|
|
|
|
|
|
sys.exit(1)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
csv_file = sys.argv[1]
|
|
|
|
|
|
elf_file = sys.argv[2]
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
print(f"\n=== Сборка ELF из CSV ===")
|
|
|
|
|
|
print(f"Чтение CSV: {csv_file}")
|
2026-05-17 11:22:39 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
addresses, bytes_list = read_csv(csv_file)
|
|
|
|
|
|
print(f"Найдено {len(addresses)} записей")
|
2026-05-17 11:22:39 +03:00
|
|
|
|
|
2026-05-23 08:52:52 +03:00
|
|
|
|
if build_file(addresses, bytes_list, elf_file):
|
|
|
|
|
|
print(f"\n=== Сборка завершена ===")
|
|
|
|
|
|
print(f" Записей в CSV: {len(addresses)}")
|
|
|
|
|
|
print(f" Размер файла: {max(addresses) + 1} байт (0x{max(addresses) + 1:x})")
|
|
|
|
|
|
print(f" Выходной файл: {elf_file}")
|
|
|
|
|
|
print(f"\n Исполняемый файл готов!")
|
2026-05-23 21:14:49 +03:00
|
|
|
|
print(f" Запустить: {elf_file}")
|
2026-05-17 11:22:39 +03:00
|
|
|
|
else:
|
2026-05-23 08:52:52 +03:00
|
|
|
|
print("Ошибка при сборке")
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2026-05-23 08:52:52 +03:00
|
|
|
|
main()
|