MoV PC, R4 @ call kernel is definitely redirected to R4: 40008000 to start execution
Start to enter the image. The image is generated by vmlinux. Therefore, read and understand the image from vmlinux.
ARCH/Unicore/kernel directory. According to its link script, start from head. S:
_ Lookup_processor_type:
Compare proc_info_list with processor by using relative fetch address (because an image supports one processor, the processor information is retrieved from C0: 4d000863 of the coprocessor ). The relative values should be used first, because the compiled kernel is compiled by the virtual address, followed by proc_info_list storage: We declare in the program. section ".proc.info. init ", and then link the defined input section in the script, and take _ proc_info_begin and _ proc_info_end as the boundary. Therefore, the header file's proc_info_begin struct does not have the corresponding variable, the content of this section is determined during compilation.
_ Lookup_machine_type:
The verification process is the same as _ lookup_processor_type. Because each processor is in a different environment, each board has a corresponding machine_type. In the boot stage, the arch_id: 0x9fc is passed in, you can compare it with the settings in the kernel image to verify whether the kernel image can run on the Development Board.
(View:/ARCH/Unicore/mach-sep0611/mach-tiger-test.c + 226
/ARCH/Unicore/include/ASM/Mach/arch. H + 53)
_ Vet_atags parameter address verification
_ Create_page_tables:
Create a kernel page table (at 40007000, 1 K level-1 transformation entries can be created based on the 4 K size starting from the kernel). Because unicore32 supports 4 M Ultra pages, it is very easy to create a kernel page table, create a page table for the kernel at the starting address of the kernel compilation and the end address at the end of the BSS segment, and create a level-1 superpage table ing for the first 4 m of the DDR2 virtual address. Of course, this is actually a bit repetitive, because the starting address of our kernel link is c0008000, and the starting virtual address of DDR2 to be established is c0000000.
LDW R13, _ switch_data @ address to jump to after
@ MMU has been enabled
Adr lr, _ enable_mmu @ return (PIC) Address
Add PC, R10, # procinfo_initfunc (actually run B _ ucv2_setup in. Section ".proc.info. init)
_ Ucv2_setup:
The cache is invalid, and the TLB is invalid. The system writes the cache and MMU to R0. We use the interrupt vector starting with 0xffff0000, I and dcache, and dcache uses the write_back policy, address check and enable it, busrt transmission enabling, MMU enabling (note that these are not written into the co-control register), and finally execute the command
MoV PC, LR
So start to run _ enable_mmu:
Write the base address of the page table to limit C2 and jump to _ turn_mmu_on (note that the LR register value is not changed)
_ Turn_mmu_on:
Write R0 to PC. C1 movc 1_c1, R0, #0
MoV PC and R13 run in virtual address
NOP; NOP (unicore32 is an eight-level flow, but there are still more. Of course, who cares about this)
_ Switch_data:
Start to create a BSS segment, and store processor_id, _ machine_arch_type, _ atags_pointer, and cr_alignment in a fixed address (of course, these parameters are not quite clear, so let's take a look later ), another stack value is init_thread_union + thread_start_sp. The disassembly is 0xc058dff8, which is located in the data segment. This stack value does not understand why this setting is required.
Run B start_kernel to jump to/init/Main. C and start executing the first C program.