Пример #1
0
VOID
Flash_Start_OS (
  )
{
    UINT32              Index = 0;
    UINTN               FDTConfigTable = 0;
    EFI_STATUS Status;
    ESL_LINUX LinuxKernel = (ESL_LINUX)(0x80000); 

    if (!PcdGet32(PcdIsMPBoot))
    {
        for (Index = 0; Index < gST->NumberOfTableEntries; Index ++) 
        {
            if (CompareGuid (&gFdtTableGuid, &(gST->ConfigurationTable[Index].VendorGuid)))
            {
                FDTConfigTable = (UINTN)gST->ConfigurationTable[Index].VendorTable;
                DEBUG ((EFI_D_ERROR, "FDTConfigTable Address: 0x%lx\n",FDTConfigTable));     
                break;
            }
        }
        gBS->CopyMem((void *)0x6000000,(void *)FDTConfigTable,0x100000);
        MicroSecondDelay(20000);
        
        gBS->CopyMem((void *)LinuxKernel,(void *)0x90100000,0x1F00000);
        MicroSecondDelay(200000);
        
        gBS->CopyMem((void *)0x7000000,(void *)0x92000000,0x4000000);
        MicroSecondDelay(200000);

        DEBUG((EFI_D_ERROR,"Update FDT\n"));
        Status = EFIFdtUpdate(0x06000000);
        if(EFI_ERROR(Status))
        {
            DEBUG((EFI_D_ERROR,"EFIFdtUpdate ERROR\n"));
            goto Exit;
        }
    }
    else
    {
        Status = LzmaDecompressKernel (LinuxKernel);
        if(EFI_ERROR(Status))
        {
            goto Exit;
        }

        gBS->CopyMem((void *)0x6000000, (void *)0xA47C0000, 0x20000);
        MicroSecondDelay(20000);

        gBS->CopyMem((void *)0x7000000, (void *)0xA4000000, 0x7C0000);
        MicroSecondDelay(200000);
    }

    Status = ShutdownUefiBootServices ();
    if(EFI_ERROR(Status)) 
    {
        DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
        goto Exit;
    }

    //
    // Switch off interrupts, caches, mmu, etc
    //
    Status = PreparePlatformHardware ();
    ASSERT_EFI_ERROR(Status);

    LinuxKernel (0x06000000,0,0,0);
    // Kernel should never exit
    // After Life services are not provided
    ASSERT(FALSE);

Exit:
    // Only be here if we fail to start Linux
    Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);
  
    // Free Runtimee Memory (kernel and FDT)
    return ;
}
Пример #2
0
VOID
ESL_Start_OS (
  )
{
    EFI_STATUS Status;
    UINTN     Reg_Value;
    ESL_LINUX LinuxKernel = (ESL_LINUX)(0x80000); 

    if(!PcdGet32(PcdIsMPBoot))
    {
        DEBUG((EFI_D_ERROR,"Update FDT\n"));
        Status = EFIFdtUpdate(0x06000000);
        if(EFI_ERROR(Status))
        {
            DEBUG((EFI_D_ERROR,"EFIFdtUpdate ERROR\n"));
            goto Exit;
        }
    }
    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Start to boot Linux\n", __FUNCTION__, __LINE__));

    SmmuConfigForLinux();

    ITSCONFIG();

    if(PcdGet32(PcdIsMPBoot))
    {
        *(volatile UINT32 *)(0x60016220)   = 0x7;
        *(volatile UINT32 *)(0x60016230)   = 0x40016260;
        *(volatile UINT32 *)(0x60016234)   = 0X0;
        *(volatile UINT32 *)(0x60016238)   = 0x60016260;
        *(volatile UINT32 *)(0x6001623C)   = 0x400;
        *(volatile UINT32 *)(0x60016240)   = 0x40016260;
        *(volatile UINT32 *)(0x60016244)   = 0x400;

        *(volatile UINT32 *)(0x40016220)   = 0x7;
        *(volatile UINT32 *)(0x40016230)   = 0x60016260;
        *(volatile UINT32 *)(0x40016234)   = 0X0;
        *(volatile UINT32 *)(0x40016238)   = 0x60016260;
        *(volatile UINT32 *)(0x4001623C)   = 0x400;
        *(volatile UINT32 *)(0x40016240)   = 0x40016260;
        *(volatile UINT32 *)(0x40016244)   = 0x400;

        *(volatile UINT32 *)(0x60016220 + S1_BASE)   = 0x7;
        *(volatile UINT32 *)(0x60016230 + S1_BASE)   = 0x40016260;
        *(volatile UINT32 *)(0x60016234 + S1_BASE)   = 0X0;
        *(volatile UINT32 *)(0x60016238 + S1_BASE)   = 0x60016260;
        *(volatile UINT32 *)(0x6001623C + S1_BASE)   = 0x0;
        *(volatile UINT32 *)(0x60016240 + S1_BASE)   = 0x40016260;
        *(volatile UINT32 *)(0x60016244 + S1_BASE)   = 0x400;

        *(volatile UINT32 *)(0x40016220 + S1_BASE)   = 0x7;
        *(volatile UINT32 *)(0x40016230 + S1_BASE)   = 0x60016260;
        *(volatile UINT32 *)(0x40016234 + S1_BASE)   = 0X0;
        *(volatile UINT32 *)(0x40016238 + S1_BASE)   = 0x60016260;
        *(volatile UINT32 *)(0x4001623C + S1_BASE)   = 0x400;
        *(volatile UINT32 *)(0x40016240 + S1_BASE)   = 0x40016260;
        *(volatile UINT32 *)(0x40016244 + S1_BASE)   = 0x0;
    }
    
    Status = ShutdownUefiBootServices ();
    if(EFI_ERROR(Status)) 
    {
        DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
        goto Exit;
    }

    //
    // Switch off interrupts, caches, mmu, etc
    //
    Status = PreparePlatformHardware ();
    ASSERT_EFI_ERROR(Status);

    *(volatile UINT32*)0xFFF8 = 0x0;
    *(volatile UINT32*)0xFFFC = 0x0;
    asm("DSB SY");
    asm("ISB");

    if (!PcdGet64 (PcdTrustedFirmwareEnable))
    {
        StartupAp();
    }

    Reg_Value = asm_read_reg();

    DEBUG((EFI_D_ERROR,"CPUECTLR_EL1 = 0x%llx\n",Reg_Value));

    MN_CONFIG ();

    DEBUG((EFI_D_ERROR, "[%a]:[%dL] Start to jump Linux kernel\n", __FUNCTION__, __LINE__));

    LinuxKernel (0x06000000,0,0,0);
    
    // Kernel should never exit
    // After Life services are not provided
    ASSERT(FALSE);

Exit:
    // Only be here if we fail to start Linux
    Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);

    // Free Runtimee Memory (kernel and FDT)
    return ;
}
Пример #3
0
STATIC
EFI_STATUS
StartLinux (
  IN  EFI_PHYSICAL_ADDRESS  LinuxImage,
  IN  UINTN                 LinuxImageSize,
  IN  EFI_PHYSICAL_ADDRESS  KernelParamsAddress,
  IN  UINTN                 KernelParamsSize,
  IN  UINT32                MachineType
  )
{
  EFI_STATUS            Status;
  LINUX_KERNEL          LinuxKernel;

  // Shut down UEFI boot services. ExitBootServices() will notify every driver that created an event on
  // ExitBootServices event. Example the Interrupt DXE driver will disable the interrupts on this event.
  Status = ShutdownUefiBootServices ();
  if(EFI_ERROR(Status)) {
    DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
    goto Exit;
  }

  // Move the kernel parameters to any address inside the first 1MB.
  // This is necessary because the ARM Linux kernel requires
  // the FTD / ATAG List to reside entirely inside the first 1MB of
  // physical memory.
  //Note: There is no requirement on the alignment
  if (MachineType != ARM_FDT_MACHINE_TYPE) {
    if (((UINTN)KernelParamsAddress > LINUX_ATAG_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxAtagMaxOffset))) {
      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_ATAG_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
    }
  } else {
    if (((UINTN)KernelParamsAddress > LINUX_FDT_MAX_OFFSET) && (KernelParamsSize < PcdGet32(PcdArmLinuxFdtMaxOffset))) {
      KernelParamsAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CopyMem (ALIGN32_BELOW(LINUX_FDT_MAX_OFFSET - KernelParamsSize), (VOID*)(UINTN)KernelParamsAddress, KernelParamsSize);
    }
  }

  if ((UINTN)LinuxImage > LINUX_KERNEL_MAX_OFFSET) {
    //Note: There is no requirement on the alignment
    LinuxKernel = (LINUX_KERNEL)CopyMem (ALIGN32_BELOW(LINUX_KERNEL_MAX_OFFSET - LinuxImageSize), (VOID*)(UINTN)LinuxImage, LinuxImageSize);
  } else {
    LinuxKernel = (LINUX_KERNEL)(UINTN)LinuxImage;
  }

  // Check if the Linux Image is a uImage
  if (*(UINT32*)LinuxKernel == LINUX_UIMAGE_SIGNATURE) {
    // Assume the Image Entry Point is just after the uImage header (64-byte size)
    LinuxKernel = (LINUX_KERNEL)((UINTN)LinuxKernel + 64);
    LinuxImageSize -= 64;
  }

  // Check there is no overlapping between kernel and its parameters
  // We can only assert because it is too late to fallback to UEFI (ExitBootServices has been called).
  ASSERT (!IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress) &&
          !IS_ADDRESS_IN_REGION(LinuxKernel, LinuxImageSize, KernelParamsAddress + KernelParamsSize));

  //
  // Switch off interrupts, caches, mmu, etc
  //
  Status = PreparePlatformHardware ();
  ASSERT_EFI_ERROR(Status);

  // Register and print out performance information
  PERF_END (NULL, "BDS", NULL, 0);
  if (PerformanceMeasurementEnabled ()) {
    PrintPerformance ();
  }

  //
  // Start the Linux Kernel
  //

  // Outside BootServices, so can't use Print();
  DEBUG((EFI_D_ERROR, "\nStarting the kernel:\n\n"));

  // Jump to kernel with register set
  LinuxKernel ((UINTN)0, MachineType, (UINTN)KernelParamsAddress);

  // Kernel should never exit
  // After Life services are not provided
  ASSERT(FALSE);

Exit:
  // Only be here if we fail to start Linux
  Print (L"ERROR  : Can not start the kernel. Status=0x%X\n", Status);

  // Free Runtimee Memory (kernel and FDT)
  return Status;
}