Jump to content

    

doom13

Свой
  • Content Count

    1488
  • Joined

  • Last visited

Community Reputation

0 Обычный

About doom13

  • Rank
    Профессионал
  • Birthday 02/09/1982

Контакты

  • Сайт
    http://
  • ICQ
    0

Информация

  • Город
    Минск, Беларусь

Recent Profile Visitors

6372 profile views
  1. Вам нужны исходники? Тогда тут. Если проект под PetaLinux, то там это всё уже есть и при сборке получаем все бинарники в папке petalinux_project/images/linux.
  2. Непонятно, что вы пытаетесь сгенерировать. Эта команда загрузочный бинарник формирует и если опцию --u-boot используете, то необходимо указывать и путь к u-boot.elf, иначе ищет его в дефолтной директории.
  3. U-Boot + BareMetal application

    Нашёл, на форуме Xilinx это. Каким-то чудом BareMetal стал стартовать по команде go с настройкой EL1 для BSP (предварительно правда пересобрал bl31). Пока так и не понял, что именно ему помогло запуститься. Остался вопрос с проектом под FreeRTOS, в этом случае в BSP не могу найти опцию для EL1.
  4. U-Boot + BareMetal application

    Для bootelf последовательность такая: /* Interpreter command to boot an arbitrary ELF image from memory */ int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ char *sload = NULL; const char *ep = env_get("autostart"); int rcode = 0; /* Consume 'bootelf' */ argc--; argv++; /* Check for flag. */ if (argc >= 1 && (argv[0][0] == '-' && \ (argv[0][1] == 'p' || argv[0][1] == 's'))) { sload = argv[0]; /* Consume flag. */ argc--; argv++; } /* Check for address. */ if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) != -EINVAL) { /* Consume address */ argc--; argv++; } else addr = load_addr; if (!valid_elf_image(addr)) return 1; if (sload && sload[1] == 'p') addr = load_elf_image_phdr(addr); else addr = load_elf_image_shdr(addr); if (ep && !strcmp(ep, "no")) return rcode; printf("## Starting application at 0x%08lx ...\n", addr); /* * pass address parameter as argv[0] (aka command name), * and all remaining args */ rc = do_bootelf_exec((void *)addr, argc, argv); if (rc != 0) rcode = 1; printf("## Application terminated, rc = 0x%lx\n", rc); return rcode; } /* Allow ports to override the default behavior */ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), int argc, char * const argv[]) { unsigned long ret; /* * pass address parameter as argv[0] (aka command name), * and all remaining args */ ret = entry(argc, argv); return ret; } как понимаю, парсит elf и идёт на entry point, тут похоже останется в EL2, но мой BareMetal опять же хочет видеть EL3. Тут тогда вопрос: может ли BL31 стартануть U-Boot c EL3? Тогда bootelf возможно и сработала бы. Но у меня система с U-Boot стартует только если формирую бинарник таким образом: //arch = zynqmp; split = false; format = BIN the_ROM_image: { [fsbl_config]a53_x64 [bootloader]/home/andrei/workspace/ZynqMP/xczu9eg/xczu9eg.sdk/fsbl_a530/Debug/fsbl_a530.elf [pmufw_image]/home/andrei/workspace/ZynqMP/xczu9eg/xczu9eg.sdk/pmufw/Debug/pmufw.elf [destination_device = pl]/home/andrei/workspace/ZynqMP/xczu9eg/xczu9eg.runs/impl_1/xczu9eg.bit [destination_cpu = a53-0, exception_level = el-3, trustzone]/home/andrei/workspace/ZynqMP/linux/images/linux/bl31.elf [destination_cpu = a53-0, exception_level = el-2]/home/andrei/workspace/ZynqMP/u-boot-xlnx/u-boot.elf }
  5. U-Boot + BareMetal application

    Я тут пока сам не пойму. Например для go U-boot выполняет: unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc, char * const argv[]) { int ret = 0; printf ("2. In file zynqmp.c\n"); if (current_el() > 1) { printf ("EL = %d\n", current_el()); smp_kick_all_cpus(); dcache_disable(); armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry, ES_TO_AARCH64); } else { printf("FAIL: current EL is not above EL1\n"); ret = EINVAL; } return ret; } т.е. переключает на EL1 и переходит на мой адрес старта boot.S, а там уже EL не совпадает и: _prestart: _boot: mov x0, #0 mov x1, #0 mov x2, #0 mov x3, #0 mov x4, #0 mov x5, #0 mov x6, #0 mov x7, #0 mov x8, #0 mov x9, #0 mov x10, #0 mov x11, #0 mov x12, #0 mov x13, #0 mov x14, #0 mov x15, #0 mov x16, #0 mov x17, #0 mov x18, #0 mov x19, #0 mov x20, #0 mov x21, #0 mov x22, #0 mov x23, #0 mov x24, #0 mov x25, #0 mov x26, #0 mov x27, #0 mov x28, #0 mov x29, #0 mov x30, #0 #if 0 //dont put other a53 cpus in wfi //Which core am I // ---------------- mrs x0, MPIDR_EL1 and x0, x0, #0xFF //Mask off to leave Aff0 cbz x0, OKToRun //If core 0, run the primary init code EndlessLoop0: wfi b EndlessLoop0 #endif OKToRun: mrs x0, currentEL cmp x0, #0xC beq InitEL3 cmp x0, #0x4 beq InitEL1 b error и как понимаю, вероятнее всего попадает на error и там висит (такой результат работы наблюдаю, если BSP сгенерить под гипервизор с EL1, будет висеть на error)
  6. U-Boot + BareMetal application

    Пока вижу в нем проблему не запуска BareMetal, bsp которого компилится под EL3, и поменять это малой кровью я не могу. Аналогичная проблема без ответа. Возможно ли в U-Boot при переходе на BareMeta переключать EL в положение 3?
  7. U-Boot + BareMetal application

    Что можете сказать по этому поводу: link Или это ерунда какая-то
  8. U-Boot + BareMetal application

    Он уже умеет лить прошивку по TFTP в RAM, писать во flash, и вроде как должен уметь стартануть elf/bin, то что мне и необходимо. Лень делать то, что уже сделано. С этим всё норм. По JTAG всё льётся и работает. Сливалась с git где-то в марте, т.е. почти свежая. В elf.c нахожу такое: /* * A very simple ELF64 loader, assumes the image is valid, returns the * entry point address. * * Note if U-Boot is 32-bit, the loader assumes the to segment's * physical address and size is within the lower 32-bit address space. */ static unsigned long load_elf64_image_phdr(unsigned long addr) { Elf64_Ehdr *ehdr; /* Elf header structure pointer */ Elf64_Phdr *phdr; /* Program header structure pointer */ int i; ehdr = (Elf64_Ehdr *)addr; phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff); /* Load each program header */ for (i = 0; i < ehdr->e_phnum; ++i) { void *dst = (void *)(ulong)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; debug("Loading phdr %i to 0x%p (%lu bytes)\n", i, dst, (ulong)phdr->p_filesz); if (phdr->p_filesz) memcpy(dst, src, phdr->p_filesz); if (phdr->p_filesz != phdr->p_memsz) memset(dst + phdr->p_filesz, 0x00, phdr->p_memsz - phdr->p_filesz); flush_cache((unsigned long)dst, phdr->p_filesz); ++phdr; } if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags & EF_PPC64_ELFV1_ABI)) { /* * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function * descriptor pointer with the first double word being the * address of the entry point of the function. */ uintptr_t addr = ehdr->e_entry; return *(Elf64_Addr *)addr; } return ehdr->e_entry; } Вот не получается стартануть моего elf-a из u-boot. Пробовал команду bootelf для elf, перегнал elf в bin и пробовал те же bootelf и go, попробовал переконвертить bin в img и стартануть при помощи bootm, но всё не то, пишет что стартую приложение по такому-то адресу и опа. Исходники u-boot поковырял - делаю вывод, что и не может оно стартануть приложение с EL3. Для go вызывает такую вот функцию unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc, char * const argv[]) { int ret = 0; printf ("2. In file zynqmp.c\n"); if (current_el() > 1) { printf ("EL = %d\n", current_el()); smp_kick_all_cpus(); dcache_disable(); armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry, ES_TO_AARCH64); } else { printf("FAIL: current EL is not above EL1\n"); ret = EINVAL; } return ret; } т.е. перед стартом на EL1 переключается. Посмотрел asm, что работает при старте прошивы и вижу, что там похоже и дохнет, EL не совпадает с тем что SDK генерит. В BSP есть настройка для супервизора EL1, но это как понял совсем не мой случай. Попробовал u-boot стартануть с настройкой для BIF-файла EL3 - не стартует. Стартует и нормально работает только с BL31 в EL3 и u-boot в EL2, все другие варианты - тишина. Что посоветуете? Пилить свой загрузчик?
  9. Приветствую. Нужен совет по реализации загрузчика для ZynqMP. На данный момент всю систему разруливает FreeRTOS на A53 #0. Далее будут задействованы ещё одно A53 и одно R5 (возможно все) c BareMetal или FreeRTOS. Удалённое обновление ПО по Ethernet (TFTP server) и запись в QSPI, тут вроде всё просто. Ещё думаю над возможностью в целях отладки реализовать загрузку в RAM (PS DDR) и тут вопросы. Может попробовать как-то использовать u-boot, флэху писать он умеет, грузить RAM тож умеет (вопрос только как быть, если загрузили прошивки под разные ядра, как их тут стартануть) или писать свой загрузчик? Но тут тот же вопрос, прошивки разложили, как их все стартануть? Спасибо.
  10. Здравствуйте. Подскажите, что почитать по теме. Пока прошёлся по докам FreeRTOS.
  11. Т.е. ваш Linux крутится на одном ядре
  12. Спасибо, посмотрел, получается device-tree она не парсит. И что тогда, кривой драйвер?
  13. Исходники для dev_get_platdata найти не могу, поэтому пока не понимаю, могла ли она помочь достать поддержку для 8 бит из device-tree
  14. Нет, если перед ней не ставлю mmc_of_parse(dev, &plat->cfg);// ТУТ ДОБАВИТ ПОДДЕРЖКУ 8-бит , то поддержку 8ми бит не получу int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, u32 f_max, u32 f_min) { u32 caps, caps_1 = 0; #ifdef __DOOM13_DEBUG printf("-----------------------------------\n"); printf("RUN: int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, u32 f_max, u32 f_min)\n"); printf("cfg->host_caps = %x\n", cfg->host_caps); printf("\n"); #endif caps = sdhci_readl(host, SDHCI_CAPABILITIES); #ifdef CONFIG_MMC_SDHCI_SDMA if (!(caps & SDHCI_CAN_DO_SDMA)) { printf("%s: Your controller doesn't support SDMA!!\n", __func__); return -EINVAL; } #endif if (host->quirks & SDHCI_QUIRK_REG32_RW) host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16; else host->version = sdhci_readw(host, SDHCI_HOST_VERSION); cfg->name = host->name; #ifndef CONFIG_DM_MMC cfg->ops = &sdhci_ops; #endif /* Check whether the clock multiplier is supported or not */ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT; } if (host->max_clk == 0) { if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; else host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; host->max_clk *= 1000000; if (host->clk_mul) host->max_clk *= host->clk_mul; } if (host->max_clk == 0) { printf("%s: Hardware doesn't specify base clock frequency\n", __func__); return -EINVAL; } if (f_max && (f_max < host->max_clk)) cfg->f_max = f_max; else cfg->f_max = host->max_clk; if (f_min) cfg->f_min = f_min; else { if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_300; else cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_200; } cfg->voltages = 0; if (caps & SDHCI_CAN_VDD_330) cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; if (caps & SDHCI_CAN_VDD_300) cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; if (caps & SDHCI_CAN_VDD_180) cfg->voltages |= MMC_VDD_165_195; if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE) cfg->voltages |= host->voltages; #ifdef __DOOM13_DEBUG printf("cfg->host_caps = %x\n", cfg->host_caps); printf("\n"); #endif cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; #ifdef __DOOM13_DEBUG printf("cfg->host_caps = %x\n", cfg->host_caps); printf("\n"); #endif /* Since Host Controller Version3.0 */ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { if (!(caps & SDHCI_CAN_DO_8BIT)) cfg->host_caps &= ~MMC_MODE_8BIT; } if (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE) { cfg->host_caps &= ~MMC_MODE_HS; cfg->host_caps &= ~MMC_MODE_HS_52MHz; } if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); if (!(cfg->voltages & MMC_VDD_165_195) || (host->quirks & SDHCI_QUIRK_NO_1_8_V)) caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50); if (caps_1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50)) cfg->host_caps |= MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25); if (caps_1 & SDHCI_SUPPORT_SDR104) { cfg->host_caps |= MMC_CAP(UHS_SDR104) | MMC_CAP(UHS_SDR50); /* * SD3.0: SDR104 is supported so (for eMMC) the caps2 * field can be promoted to support HS200. */ cfg->host_caps |= MMC_CAP(MMC_HS_200); } else if (caps_1 & SDHCI_SUPPORT_SDR50) { cfg->host_caps |= MMC_CAP(UHS_SDR50); } if (caps_1 & SDHCI_SUPPORT_DDR50) cfg->host_caps |= MMC_CAP(UHS_DDR50); if (host->host_caps) cfg->host_caps |= host->host_caps; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; return 0; } Получается, что в static int arasan_sdhci_probe(struct udevice *dev) { конфиг 8бит из device-tree могла достать только struct arasan_sdhci_plat *plat = dev_get_platdata(dev); но она этого не сделала (может ещё какой-то конфиг не установлен), а больше некому, только если править драйвер, добавляя парсер для device-tree