📄 elf_loader.c
字号:
/* * ApOS (Another Project software for s3c2410) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Copyright caiyuqing * */#include "../include/kernel/elf.h"#include "../include/kernel/elf_loader.h"#define _ELFLOADER_DEBUG struct elf_loader_obj elf_loader_obj;char section_name[256]={'\0'};unsigned int* string_section;/* * 文件类型检查 * 如果文件发生下列一种情况,程序以失败返回 * * 1.文件不是ELF文件 * 2.不是可执行文件 * 3.不属于ARM平台 * 4.版本号错误 * 5.不是32位指令 * 6.不是little endian模式 */int elf_check_up(struct elf_loader_obj *elo){ //文件不是ELF文件#ifdef _ELFLOADER_DEBUG printk("file check...\n");#endif if(NOT_ELF_FILE(elo->elf32_header)) {#ifdef _ELFLOADER_DEBUG printk("NOT_ELF_FILE\n");#endif return -1; } //不是可执行文件 else if(NOT_EXEC_FILE(elo->elf32_header)) {#ifdef _ELFLOADER_DEBUG printk("NOT_EXEC_FILE\n");#endif return -1; } //不属于ARM平台 else if(NOT_ARM_PLATFORM(elo->elf32_header)) {#ifdef _ELFLOADER_DEBUG printk("NOT_ARM_PLATFORM\n");#endif return -1; } //版本号错误 else if(VERSION_ERROR(elo->elf32_header)) {#ifdef _ELFLOADER_DEBUG printk("VERSION_ERROR\n");#endif return -1; } //不是32位指令 else if(NOT_32BIT(elo->elf32_header)) {#ifdef _ELFLOADER_DEBUG printk("NOT_32BIT\n");#endif return -1; } //不是little endian模式 else if(NOT_LITTLE_ENDIAN(elo->elf32_header)) {#ifdef _ELFLOADER_DEBUG printk("NOT_LITTLE_ENDIAN\n");#endif return -1; } //通过检查 else {#ifdef _ELFLOADER_DEBUG printk("file check up successful\n");#endif return 1; }}//Elf32_Ehdr* get_elf32_header(struct elf_loader_obj *elo){ return (Elf32_Ehdr*)elo->elf_file_addr_base;}//Elf32_Shdr* get_section_header_table(struct elf_loader_obj *elo){ return (Elf32_Shdr*)((unsigned int )elo->elf_file_addr_base + elo->elf32_header->e_shoff);}//Elf32_Phdr* get_programe_header_table(struct elf_loader_obj *elo){ return (Elf32_Phdr*)((unsigned int )elo->elf_file_addr_base + elo->elf32_header->e_phoff);}//获得欲索引节区头部表表项指针Elf32_Shdr* section_header_index(struct elf_loader_obj *elo,unsigned int index){ return (Elf32_Shdr *)((char *)elo->section_header_table+index*sizeof(Elf32_Shdr));}//获得欲索引节区的首地址unsigned int* section_index(struct elf_loader_obj *elo,unsigned int index){ unsigned int* section_addr; Elf32_Shdr* section_header; section_header =section_header_index(elo,index); section_addr =(unsigned int *)((unsigned int)elo->elf_file_addr_base+section_header->sh_offset); return section_addr;}unsigned int* get_string_section(struct elf_loader_obj *elo){ unsigned int *section_addr=section_index(elo,elo->elf32_header->e_shstrndx); return section_addr;}//获得欲索引节区的名称char* get_section_name(struct elf_loader_obj *elo,int index){ return (((char *)elo->string_section)+index);}void move_code(unsigned int *section_address,unsigned int *section_vaddr,unsigned int size){ int i=0; for(i=0;i<size;i++) { *(section_vaddr+i)=*(section_address+i); }}int elf_loader(struct elf_loader_obj *elo,unsigned int *elf_file_base){ Elf32_Shdr* sh_pointer; int i; elo->elf_file_addr_base =elf_file_base; //获得“ELF头部”的地址(elf32_header),该地址为ELF文件首地址 elo->elf32_header =get_elf32_header(elo); //获得 "节区头部"基地址(section_header_table) elo->section_header_table =get_section_header_table(elo); //获得"程序头部表"基地址(programe_headers_table) elo->programe_header_table =get_programe_header_table(elo);#ifdef _ELFLOADER_DEBUG printk("elf_file_addr_base: 0x%0x\n",elo->elf_file_addr_base); printk("section_header_table address: 0x%0x\n",elo->section_header_table); printk("programe_header_table address: 0x%0x\n",elo->programe_header_table);#endif //文件类型检查 elf_check_up(elo); elo->string_section= get_string_section(elo); for(i=0;i<elo->elf32_header->e_shnum;i++) { elo->current_section_header =section_header_index(elo,i); elo->current_section =section_index(elo,i); if(elo->current_section_header->sh_addr!=0x00000000) { printk("%s section code moving...\n", get_section_name(elo,elo->current_section_header->sh_name)); printk("section address:0x%0x to section virtual address:0x%0x\n", elo->current_section,elo->current_section_header->sh_addr); move_code(elo->current_section,elo->current_section_header->sh_addr, elo->current_section_header->sh_size); } } asm volatile( //"ldr lr,=return \n\t" "ldr pc,%0 \n\t" //"return: \n\t" ::"m"(elo->elf32_header->e_entry) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -