用户elf加载备份
This commit is contained in:
parent
ec1ef4e6c2
commit
b0e065958d
|
@ -8,7 +8,7 @@ out/%.obj : %.c Makefile
|
||||||
out/%.obj : %.cpp Makefile
|
out/%.obj : %.cpp Makefile
|
||||||
$(CPP) -c $*.cpp -o out/$*.obj
|
$(CPP) -c $*.cpp -o out/$*.obj
|
||||||
out/%.obj : %.asm Makefile
|
out/%.obj : %.asm Makefile
|
||||||
nasm -f elf $*.asm -o out/$*.obj
|
nasm -f elf_i386 $*.asm -o out/$*.obj
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm out/*
|
rm out/*
|
|
@ -1,7 +1,7 @@
|
||||||
#include "../include/stdio.h"
|
#include "../include/stdio.h"
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
|
debug_test();
|
||||||
while (1);
|
while (1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -2,5 +2,6 @@
|
||||||
#define CRASHPOWEROS_STDIO_H
|
#define CRASHPOWEROS_STDIO_H
|
||||||
|
|
||||||
void put_char(char c);
|
void put_char(char c);
|
||||||
|
void debug_test();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@ out/%.obj : %.c Makefile
|
||||||
out/%.obj : %.cpp Makefile
|
out/%.obj : %.cpp Makefile
|
||||||
$(CPP) -c $*.cpp -o out/$*.obj
|
$(CPP) -c $*.cpp -o out/$*.obj
|
||||||
out/%.obj : %.asm Makefile
|
out/%.obj : %.asm Makefile
|
||||||
nasm -f elf $*.asm -o out/$*.obj
|
nasm -f elf_i386 $*.asm -o out/$*.obj
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm out/*
|
rm out/*
|
|
@ -1,11 +1,11 @@
|
||||||
#include "../include/stdio.h"
|
#include "../include/stdio.h"
|
||||||
|
|
||||||
void putc(char c){
|
void hlt(){
|
||||||
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
putc('A');
|
hlt();
|
||||||
while (1);
|
//put_char('A');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
global put_char
|
global put_char
|
||||||
|
global debug_test
|
||||||
|
|
||||||
put_char:
|
put_char:
|
||||||
|
ret
|
||||||
push edx
|
push edx
|
||||||
push eax
|
push eax
|
||||||
mov edx,[ss:esp+12]
|
mov edx,[ss:esp+12]
|
||||||
|
@ -8,4 +10,11 @@ put_char:
|
||||||
int 31h
|
int 31h
|
||||||
pop eax
|
pop eax
|
||||||
pop edx
|
pop edx
|
||||||
|
ret
|
||||||
|
|
||||||
|
debug_test:
|
||||||
|
push edx
|
||||||
|
mov edx,0x02
|
||||||
|
int 31h
|
||||||
|
pop edx
|
||||||
ret
|
ret
|
|
@ -40,7 +40,7 @@ copy_page_physical:
|
||||||
popf ; Pop EFLAGS back.
|
popf ; Pop EFLAGS back.
|
||||||
pop ebx ; Get the original value of EBX back.
|
pop ebx ; Get the original value of EBX back.
|
||||||
|
|
||||||
switch_to:
|
switch_to: ;void switch_to(struct context *prev, struct context *next);
|
||||||
mov eax, [esp+4]
|
mov eax, [esp+4]
|
||||||
|
|
||||||
mov [eax+0], esp
|
mov [eax+0], esp
|
||||||
|
|
|
@ -32,8 +32,7 @@ char read_serial() {
|
||||||
int is_transmit_empty() { return io_in8(SERIAL_PORT + 5) & 0x20; }
|
int is_transmit_empty() { return io_in8(SERIAL_PORT + 5) & 0x20; }
|
||||||
|
|
||||||
void write_serial(char a) {
|
void write_serial(char a) {
|
||||||
while (is_transmit_empty() == 0)
|
return;
|
||||||
;
|
while (is_transmit_empty() == 0);
|
||||||
|
|
||||||
io_out8(SERIAL_PORT, a);
|
io_out8(SERIAL_PORT, a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,21 @@
|
||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
#include "../include/multiboot2.h"
|
#include "../include/multiboot2.h"
|
||||||
#include "../include/timer.h"
|
#include "../include/timer.h"
|
||||||
|
#include "../include/bmp.h"
|
||||||
|
|
||||||
uint32_t width, height;
|
uint32_t width, height;
|
||||||
uint32_t c_width, c_height; // 字符绘制总宽高
|
uint32_t c_width, c_height; // 字符绘制总宽高
|
||||||
int32_t x, y;
|
int32_t x, y;
|
||||||
int32_t cx, cy; // 字符坐标
|
int32_t cx, cy; // 字符坐标
|
||||||
uint32_t color, back_color;
|
uint32_t color, back_color;
|
||||||
|
|
||||||
uint32_t *screen;
|
uint32_t *screen;
|
||||||
|
|
||||||
uint32_t *char_buffer;
|
uint32_t *char_buffer;
|
||||||
extern uint8_t ascfont[];
|
extern uint8_t ascfont[];
|
||||||
extern uint8_t plfont[];
|
extern uint8_t plfont[];
|
||||||
extern uint8_t bafont[];
|
extern uint8_t bafont[];
|
||||||
|
extern uint8_t logo_bmp[];
|
||||||
|
|
||||||
bool vbe_status = false;
|
bool vbe_status = false;
|
||||||
|
|
||||||
|
@ -54,44 +58,18 @@ void vbe_scroll() {
|
||||||
screen[i] = back_color;
|
screen[i] = back_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (cy >= c_height) {
|
|
||||||
cy = c_height - 1;
|
|
||||||
for (int i = 0; i < height; i++) {
|
|
||||||
for (int j = 0; j < width; j++) {
|
|
||||||
screen[j + i * width] = screen[j + (i + 16) * width];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (y == height - height % 16) {
|
|
||||||
cy = c_height - 1;
|
|
||||||
for (int i = 0; i < height; i++) {
|
|
||||||
for (int j = 0; j < width; j++) {
|
|
||||||
(screen)[j + i * width] = (screen)[j + (i + 16 - height % 16) * width];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < width; i++) {
|
|
||||||
for (int j = 0; j < 28; j++) {
|
|
||||||
screen[height * (width + j) + i] = back_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void vbe_draw_char(char c, int32_t x, int32_t y) {
|
void vbe_draw_char(char c, int32_t x, int32_t y) {
|
||||||
if (c == ' ') {
|
if (c == ' ') {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
for (int j = 0; j < 9; j++) {
|
for (int j = 0; j < 9; j++) {
|
||||||
screen[(y + i) * width + x + j] = back_color;
|
//screen[(y + i) * width + x + j] = back_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t *font = bafont;
|
uint8_t *font = bafont;
|
||||||
//uint8_t *font = ascfont;
|
//uint8_t *font = ascfont;
|
||||||
|
|
||||||
|
@ -104,13 +82,6 @@ void vbe_draw_char(char c, int32_t x, int32_t y) {
|
||||||
} //else screen[(y + i) * width + x + j] = back_color;
|
} //else screen[(y + i) * width + x + j] = back_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
for (int j = 0; j < 9; j++) {
|
|
||||||
if (font[i] & (0x80 >> j)) {
|
|
||||||
screen[(y + i) * width + x + j] = color;
|
|
||||||
} //else screen[(y + i) * width + x + j + 1] = back_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cur_task() {
|
int cur_task() {
|
||||||
|
@ -147,7 +118,9 @@ void vbe_putchar(char ch) {
|
||||||
if (cy != 0) cy -= 1;
|
if (cy != 0) cy -= 1;
|
||||||
if (cy == 0) cx = 0, cy = 0;
|
if (cy == 0) cx = 0, cy = 0;
|
||||||
}
|
}
|
||||||
//draw_rect(x, y, x + 9, y + 16, back_color);
|
int x = (cx+1) * 9 - 7;
|
||||||
|
int y = cy * 16;
|
||||||
|
draw_rect(x, y, x + 9, y + 16, back_color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +131,10 @@ void vbe_putchar(char ch) {
|
||||||
|
|
||||||
void vbe_write(const char *data, size_t size) {
|
void vbe_write(const char *data, size_t size) {
|
||||||
static const long hextable[] = {
|
static const long hextable[] = {
|
||||||
[0 ... 255] = -1, // bit aligned access into this table is considerably
|
[0 ... 255] = -1,
|
||||||
['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // faster for most modern processors,
|
['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
['A'] = 10, 11, 12, 13, 14, 15, // for the space conscious, reduce to
|
['A'] = 10, 11, 12, 13, 14, 15,
|
||||||
['a'] = 10, 11, 12, 13, 14, 15 // signed char.
|
['a'] = 10, 11, 12, 13, 14, 15
|
||||||
};
|
};
|
||||||
|
|
||||||
for (;*data; ++data){
|
for (;*data; ++data){
|
||||||
|
@ -215,4 +188,7 @@ void initVBE(multiboot_t *info) {
|
||||||
c_height = height / 16;
|
c_height = height / 16;
|
||||||
|
|
||||||
vbe_clear();
|
vbe_clear();
|
||||||
|
|
||||||
|
Bmp *bmp = (Bmp*) &logo_bmp;
|
||||||
|
display(bmp,0,0,false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "../include/vfs.h"
|
#include "../include/vfs.h"
|
||||||
#include "../include/vdisk.h"
|
#include "../include/vdisk.h"
|
||||||
#include "../include/printf.h"
|
#include "../include/printf.h"
|
||||||
|
|
||||||
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector);
|
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector);
|
||||||
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
||||||
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
|
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
|
||||||
|
|
|
@ -3225,5 +3225,6 @@ int elf32Validate(Elf32_Ehdr *hdr);
|
||||||
void load_segment(Elf32_Phdr *phdr,page_directory_t *pdt, void *elf);
|
void load_segment(Elf32_Phdr *phdr,page_directory_t *pdt, void *elf);
|
||||||
uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *pdt);
|
uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *pdt);
|
||||||
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr);
|
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr);
|
||||||
|
uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr);
|
||||||
|
|
||||||
#endif /* elf.h */
|
#endif /* elf.h */
|
||||||
|
|
|
@ -79,6 +79,14 @@ typedef struct mmap_entry_t {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
} __attribute__((packed)) mmap_entry_t;
|
} __attribute__((packed)) mmap_entry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t biosdev;
|
||||||
|
uint32_t partition;
|
||||||
|
uint32_t sub_partition;
|
||||||
|
} multiboot_tag_bootdev_t;
|
||||||
|
|
||||||
// 声明全局的 multiboot_t * 指针
|
// 声明全局的 multiboot_t * 指针
|
||||||
// 内核未建立分页机制前暂存的指针
|
// 内核未建立分页机制前暂存的指针
|
||||||
extern multiboot_t *mboot_ptr_tmp;
|
extern multiboot_t *mboot_ptr_tmp;
|
||||||
|
|
|
@ -31,23 +31,24 @@ struct context{
|
||||||
uint32_t eip;
|
uint32_t eip;
|
||||||
uint32_t ds;
|
uint32_t ds;
|
||||||
uint32_t cs;
|
uint32_t cs;
|
||||||
|
uint32_t ss;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 进程控制块 PCB
|
// 进程控制块 PCB
|
||||||
struct task_struct {
|
struct task_struct {
|
||||||
volatile task_state state; // 进程当前状态
|
volatile task_state state; // 进程当前状态
|
||||||
int pid; // 进程标识符
|
int pid; // 进程标识符
|
||||||
int mem_size; //内存利用率
|
int mem_size; // 内存利用率
|
||||||
char *name; // 进程名
|
char *name; // 进程名
|
||||||
void *stack; // 进程的内核栈地址
|
void *stack; // 进程的内核栈地址
|
||||||
header_t *head;
|
header_t *head; // 进程堆
|
||||||
header_t *tail;
|
header_t *tail;
|
||||||
bool isUser;
|
bool isUser; // 是否是用户进程
|
||||||
uint32_t program_break;
|
uint32_t program_break; // 进程堆基址
|
||||||
uint32_t program_break_end;
|
uint32_t program_break_end; // 进程堆尾
|
||||||
page_directory_t *pgd_dir; // 进程页表
|
page_directory_t *pgd_dir; // 进程页表
|
||||||
struct context context; // 上下文信息
|
struct context context; // 上下文信息
|
||||||
struct task_struct *next; // 链表指针
|
struct task_struct *next; // 链表指针
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int is_print);
|
void print_proc_t(int *i,struct task_struct *base,struct task_struct *cur,int is_print);
|
||||||
|
|
|
@ -75,6 +75,13 @@ void kernel_main(multiboot_t *multiboot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
initVBE(multiboot);
|
initVBE(multiboot);
|
||||||
|
|
||||||
|
|
||||||
|
char* cmdline = multiboot->cmdline;
|
||||||
|
if(cmdline != NULL){
|
||||||
|
printf("Multiboot command line: %s\n",cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
printf("CPOS_Kernel %s (GRUB Multiboot) on an i386.\n",OS_VERSION);
|
printf("CPOS_Kernel %s (GRUB Multiboot) on an i386.\n",OS_VERSION);
|
||||||
printf("Memory Size: %dMB\n",(multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1);
|
printf("Memory Size: %dMB\n",(multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1);
|
||||||
gdt_install();
|
gdt_install();
|
||||||
|
|
|
@ -44,8 +44,10 @@ void panic_pane(char* msg,enum PANIC_TYPE type){
|
||||||
back_color = 0x1e90ff;
|
back_color = 0x1e90ff;
|
||||||
color = 0xffffff;
|
color = 0xffffff;
|
||||||
screen_clear();
|
screen_clear();
|
||||||
if(panic_bmp != NULL)
|
if(panic_bmp != NULL){
|
||||||
display(panic_bmp,0,0,true);
|
display(panic_bmp,0,0,false);
|
||||||
|
} else klogf(false,"Cannot draw panic image.\n");
|
||||||
|
|
||||||
cx = 10;
|
cx = 10;
|
||||||
cy = c_height - 10;
|
cy = c_height - 10;
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include "../include/graphics.h"
|
#include "../include/graphics.h"
|
||||||
#include "../include/io.h"
|
#include "../include/io.h"
|
||||||
|
|
||||||
extern asm_syscall_handler();
|
|
||||||
|
|
||||||
void syscall_handler(registers_t regs){
|
void syscall_handler(registers_t regs){
|
||||||
io_cli();
|
io_cli();
|
||||||
printf("Syscall is enable.\n");
|
printf("Syscall is enable.\n");
|
||||||
|
@ -18,5 +16,5 @@ void syscall_handler(registers_t regs){
|
||||||
}
|
}
|
||||||
|
|
||||||
void syscall_install(){
|
void syscall_install(){
|
||||||
register_interrupt_handler(31,asm_syscall_handler);
|
register_interrupt_handler(31,syscall_handler);
|
||||||
}
|
}
|
|
@ -140,7 +140,7 @@ void task_kill(int pid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
argv->state = TASK_DEATH;
|
argv->state = TASK_DEATH;
|
||||||
printf("Taskkill process PID:%d Name:%s\n", current->pid, current->name);
|
printf("Taskkill process PID:%d Name:%s\n", argv->pid, argv->name);
|
||||||
printf("Task [%s] exit code: -130.\n", argv->name);
|
printf("Task [%s] exit code: -130.\n", argv->name);
|
||||||
|
|
||||||
kfree(argv);
|
kfree(argv);
|
||||||
|
@ -175,15 +175,17 @@ void change_task_to(registers_t *reg,struct task_struct *next) {
|
||||||
prev->context.ds = reg->ds;
|
prev->context.ds = reg->ds;
|
||||||
prev->context.cs = reg->cs;
|
prev->context.cs = reg->cs;
|
||||||
prev->context.eax = reg->eax;
|
prev->context.eax = reg->eax;
|
||||||
|
prev->context.ss = reg->ss;
|
||||||
switch_to(&(prev->context), &(current->context));
|
switch_to(&(prev->context), &(current->context));
|
||||||
reg->ds = current->context.ds;
|
reg->ds = current->context.ds;
|
||||||
reg->cs = current->context.cs;
|
reg->cs = current->context.cs;
|
||||||
reg->eip = current->context.eip;
|
reg->eip = current->context.eip;
|
||||||
reg->eax = current->context.eax;
|
reg->eax = current->context.eax;
|
||||||
|
reg->ss = current->context.ss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t user_process(char *path, char *name){
|
int32_t user_process(char *path, char *name){ // 用户进程创建
|
||||||
can_sche = 0;
|
can_sche = 0;
|
||||||
if(path == NULL){
|
if(path == NULL){
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -216,6 +218,8 @@ int32_t user_process(char *path, char *name){
|
||||||
|
|
||||||
page_switch(page);
|
page_switch(page);
|
||||||
|
|
||||||
|
printf("TASK I\n");
|
||||||
|
|
||||||
for (int i = USER_START; i < USER_END;i++) {
|
for (int i = USER_START; i < USER_END;i++) {
|
||||||
page_t *pg = get_page(i,1,page, false);
|
page_t *pg = get_page(i,1,page, false);
|
||||||
alloc_frame(pg,0,1);
|
alloc_frame(pg,0,1);
|
||||||
|
@ -223,8 +227,10 @@ int32_t user_process(char *path, char *name){
|
||||||
|
|
||||||
char* buffer = user_alloc(new_task,size);
|
char* buffer = user_alloc(new_task,size);
|
||||||
|
|
||||||
|
printf("TASK II\n");
|
||||||
|
|
||||||
memset(buffer,0,size);
|
memset(buffer,0,size);
|
||||||
vfs_readfile(path,buffer);
|
vfs_readfile(path,buffer); //能加载, 但是执行一会就不知道跳哪里去了,给自己爆了
|
||||||
|
|
||||||
Elf32_Ehdr *ehdr = buffer;
|
Elf32_Ehdr *ehdr = buffer;
|
||||||
if(!elf32Validate(ehdr)){
|
if(!elf32Validate(ehdr)){
|
||||||
|
@ -233,8 +239,9 @@ int32_t user_process(char *path, char *name){
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t main = load_elf(ehdr,page);
|
uint32_t main = load_elf(ehdr,page);
|
||||||
|
printf("Task [PID: %d] start_function: %08x\n",new_task->pid,main);
|
||||||
|
|
||||||
uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE);
|
uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE);
|
||||||
|
|
||||||
*(--stack_top) = (uint32_t) main;
|
*(--stack_top) = (uint32_t) main;
|
||||||
*(--stack_top) = (uint32_t) kthread_exit;
|
*(--stack_top) = (uint32_t) kthread_exit;
|
||||||
|
@ -262,7 +269,7 @@ int32_t user_process(char *path, char *name){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t kernel_thread(int (*fn)(void *), void *arg, char *name) {
|
int32_t kernel_thread(int (*fn)(void *), void *arg, char *name) { // 内核进程(线程) 创建
|
||||||
io_cli();
|
io_cli();
|
||||||
struct task_struct *new_task = (struct task_struct *) kmalloc(STACK_SIZE);
|
struct task_struct *new_task = (struct task_struct *) kmalloc(STACK_SIZE);
|
||||||
assert(new_task != NULL, "kern_thread: kmalloc error");
|
assert(new_task != NULL, "kern_thread: kmalloc error");
|
||||||
|
@ -316,7 +323,6 @@ void kthread_exit() {
|
||||||
register uint32_t val asm ("eax");
|
register uint32_t val asm ("eax");
|
||||||
printf("Task [PID: %d] exited with value %d\n", current->pid,val);
|
printf("Task [PID: %d] exited with value %d\n", current->pid,val);
|
||||||
task_kill(current->pid);
|
task_kill(current->pid);
|
||||||
current->state = TASK_DEATH;
|
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,22 @@ bool elf32Validate(Elf32_Ehdr *hdr) {
|
||||||
hdr->e_ident[EI_MAG2] == ELFMAG2 && hdr->e_ident[EI_MAG3] == ELFMAG3;
|
hdr->e_ident[EI_MAG2] == ELFMAG2 && hdr->e_ident[EI_MAG3] == ELFMAG3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_segment(Elf32_Phdr *phdr,page_directory_t *pdt, void *elf) {
|
uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr) {
|
||||||
|
Elf32_Phdr *phdr = (Elf32_Phdr *) ((uint32_t) hdr + hdr->e_phoff);
|
||||||
|
uint32_t max = 0;
|
||||||
|
for (int i = 0; i < hdr->e_phnum; i++) {
|
||||||
|
uint32_t size = MAX(
|
||||||
|
phdr->p_filesz,
|
||||||
|
phdr->p_memsz); // 如果memsz大于filesz 说明这是bss段,我们以最大的为准
|
||||||
|
max = MAX(max, phdr->p_vaddr + size);
|
||||||
|
phdr++;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_segment(Elf32_Phdr *phdr, page_directory_t *pdt, void *elf) {
|
||||||
unsigned int p = div_round_up(phdr->p_memsz, 0x1000);
|
unsigned int p = div_round_up(phdr->p_memsz, 0x1000);
|
||||||
|
|
||||||
int d = phdr->p_paddr;
|
int d = phdr->p_paddr;
|
||||||
if (d & 0x00000fff) {
|
if (d & 0x00000fff) {
|
||||||
unsigned e = d + phdr->p_memsz;
|
unsigned e = d + phdr->p_memsz;
|
||||||
|
@ -23,28 +37,61 @@ void load_segment(Elf32_Phdr *phdr,page_directory_t *pdt, void *elf) {
|
||||||
p = (e - d) / 0x1000 + 1;
|
p = (e - d) / 0x1000 + 1;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < p; i++) {
|
for (unsigned i = 0; i < p; i++) {
|
||||||
alloc_frame(get_page(d + i * 0x1000,1,pdt,false),0,1);
|
alloc_frame(get_page(d + i * 0x1000, 1, pdt, false), 0, 1);
|
||||||
}
|
}
|
||||||
memcpy(phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz);
|
memcpy(phdr->p_vaddr, elf + phdr->p_offset, phdr->p_filesz);
|
||||||
|
|
||||||
if (phdr->p_memsz > phdr->p_filesz) { // 这个是bss段
|
if (phdr->p_memsz > phdr->p_filesz) { // 这个是bss段
|
||||||
memset(phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
|
memset(phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *pdt) {
|
static uint32_t reload_elf_file(uint8_t *file_buffer) {
|
||||||
Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff);
|
Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) file_buffer;
|
||||||
|
//检测文件类型
|
||||||
|
if ((elf_hdr->e_ident[0] != 0x7f) || (elf_hdr->e_ident[1] != 'E') ||
|
||||||
|
(elf_hdr->e_ident[2] != 'L') || (elf_hdr->e_ident[3] != 'F')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < elf_hdr->e_phnum; i++) {
|
||||||
|
Elf32_Phdr *phdr = (Elf32_Phdr *) (file_buffer + elf_hdr->e_phoff) + i;
|
||||||
|
if (phdr->p_type != PT_LOAD) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//获取源文件地址以及需要加载的位置
|
||||||
|
uint8_t *src = file_buffer + phdr->p_offset;
|
||||||
|
//printf("POFFSET: %08x\n",phdr->p_offset);
|
||||||
|
uint8_t *dest = (uint8_t *) phdr->p_paddr;
|
||||||
|
for (int j = 0; j < phdr->p_filesz; j++) {
|
||||||
|
*dest++ = *src++;
|
||||||
|
}
|
||||||
|
//计算结束地址, 对bss区域进行清零
|
||||||
|
dest = (uint8_t *) phdr->p_paddr + phdr->p_filesz;
|
||||||
|
for (int j = 0; j < phdr->p_memsz - phdr->p_filesz; j++) {
|
||||||
|
*dest++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//返回进入的地址
|
||||||
|
return elf_hdr->e_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t load_elf(Elf32_Ehdr *hdr, page_directory_t *pdt) {
|
||||||
|
Elf32_Phdr *phdr = (Elf32_Phdr *) ((uint32_t) hdr + hdr->e_phoff);
|
||||||
for (int i = 0; i < hdr->e_phnum; i++) {
|
for (int i = 0; i < hdr->e_phnum; i++) {
|
||||||
load_segment(phdr,pdt, (void *)hdr);
|
if (phdr->p_type != PT_LOAD) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
load_segment(phdr, pdt, (void *) hdr);
|
||||||
phdr++;
|
phdr++;
|
||||||
}
|
}
|
||||||
return hdr->e_entry;
|
return hdr->e_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr) {
|
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr) {
|
||||||
uint8_t *p = (uint8_t *)elfhdr;
|
uint8_t *p = (uint8_t *) elfhdr;
|
||||||
for (int i = 0; i < elfhdr->e_shnum; i++) {
|
for (int i = 0; i < elfhdr->e_shnum; i++) {
|
||||||
Elf32_Shdr *shdr =
|
Elf32_Shdr *shdr =
|
||||||
(Elf32_Shdr *)(p + elfhdr->e_shoff + sizeof(Elf32_Shdr) * i);
|
(Elf32_Shdr *) (p + elfhdr->e_shoff + sizeof(Elf32_Shdr) * i);
|
||||||
|
|
||||||
if (shdr->sh_type != SHT_PROGBITS || !(shdr->sh_flags & SHF_ALLOC)) {
|
if (shdr->sh_type != SHT_PROGBITS || !(shdr->sh_flags & SHF_ALLOC)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue