用户elf加载备份
This commit is contained in:
parent
ec1ef4e6c2
commit
b0e065958d
|
@ -8,7 +8,7 @@ out/%.obj : %.c Makefile
|
|||
out/%.obj : %.cpp Makefile
|
||||
$(CPP) -c $*.cpp -o out/$*.obj
|
||||
out/%.obj : %.asm Makefile
|
||||
nasm -f elf $*.asm -o out/$*.obj
|
||||
nasm -f elf_i386 $*.asm -o out/$*.obj
|
||||
|
||||
clean:
|
||||
rm out/*
|
|
@ -1,7 +1,7 @@
|
|||
#include "../include/stdio.h"
|
||||
|
||||
int main(){
|
||||
|
||||
debug_test();
|
||||
while (1);
|
||||
return 0;
|
||||
}
|
|
@ -2,5 +2,6 @@
|
|||
#define CRASHPOWEROS_STDIO_H
|
||||
|
||||
void put_char(char c);
|
||||
void debug_test();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,7 +8,7 @@ out/%.obj : %.c Makefile
|
|||
out/%.obj : %.cpp Makefile
|
||||
$(CPP) -c $*.cpp -o out/$*.obj
|
||||
out/%.obj : %.asm Makefile
|
||||
nasm -f elf $*.asm -o out/$*.obj
|
||||
nasm -f elf_i386 $*.asm -o out/$*.obj
|
||||
|
||||
clean:
|
||||
rm out/*
|
|
@ -1,11 +1,11 @@
|
|||
#include "../include/stdio.h"
|
||||
|
||||
void putc(char c){
|
||||
|
||||
void hlt(){
|
||||
while (1);
|
||||
}
|
||||
|
||||
int main(){
|
||||
putc('A');
|
||||
while (1);
|
||||
hlt();
|
||||
//put_char('A');
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
global put_char
|
||||
global debug_test
|
||||
|
||||
put_char:
|
||||
ret
|
||||
push edx
|
||||
push eax
|
||||
mov edx,[ss:esp+12]
|
||||
|
@ -9,3 +11,10 @@ put_char:
|
|||
pop eax
|
||||
pop edx
|
||||
ret
|
||||
|
||||
debug_test:
|
||||
push edx
|
||||
mov edx,0x02
|
||||
int 31h
|
||||
pop edx
|
||||
ret
|
|
@ -40,7 +40,7 @@ copy_page_physical:
|
|||
popf ; Pop EFLAGS 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+0], esp
|
||||
|
|
|
@ -32,8 +32,7 @@ char read_serial() {
|
|||
int is_transmit_empty() { return io_in8(SERIAL_PORT + 5) & 0x20; }
|
||||
|
||||
void write_serial(char a) {
|
||||
while (is_transmit_empty() == 0)
|
||||
;
|
||||
|
||||
return;
|
||||
while (is_transmit_empty() == 0);
|
||||
io_out8(SERIAL_PORT, a);
|
||||
}
|
||||
|
|
|
@ -4,17 +4,21 @@
|
|||
#include "../include/common.h"
|
||||
#include "../include/multiboot2.h"
|
||||
#include "../include/timer.h"
|
||||
#include "../include/bmp.h"
|
||||
|
||||
uint32_t width, height;
|
||||
uint32_t c_width, c_height; // 字符绘制总宽高
|
||||
int32_t x, y;
|
||||
int32_t cx, cy; // 字符坐标
|
||||
uint32_t color, back_color;
|
||||
|
||||
uint32_t *screen;
|
||||
|
||||
uint32_t *char_buffer;
|
||||
extern uint8_t ascfont[];
|
||||
extern uint8_t plfont[];
|
||||
extern uint8_t bafont[];
|
||||
extern uint8_t logo_bmp[];
|
||||
|
||||
bool vbe_status = false;
|
||||
|
||||
|
@ -54,44 +58,18 @@ void vbe_scroll() {
|
|||
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) {
|
||||
if (c == ' ') {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
screen[(y + i) * width + x + j] = back_color;
|
||||
//screen[(y + i) * width + x + j] = back_color;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *font = bafont;
|
||||
//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;
|
||||
}
|
||||
}
|
||||
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() {
|
||||
|
@ -147,7 +118,9 @@ void vbe_putchar(char ch) {
|
|||
if (cy != 0) cy -= 1;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -158,10 +131,10 @@ void vbe_putchar(char ch) {
|
|||
|
||||
void vbe_write(const char *data, size_t size) {
|
||||
static const long hextable[] = {
|
||||
[0 ... 255] = -1, // bit aligned access into this table is considerably
|
||||
['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // faster for most modern processors,
|
||||
['A'] = 10, 11, 12, 13, 14, 15, // for the space conscious, reduce to
|
||||
['a'] = 10, 11, 12, 13, 14, 15 // signed char.
|
||||
[0 ... 255] = -1,
|
||||
['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
['A'] = 10, 11, 12, 13, 14, 15,
|
||||
['a'] = 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
for (;*data; ++data){
|
||||
|
@ -215,4 +188,7 @@ void initVBE(multiboot_t *info) {
|
|||
c_height = height / 16;
|
||||
|
||||
vbe_clear();
|
||||
|
||||
Bmp *bmp = (Bmp*) &logo_bmp;
|
||||
display(bmp,0,0,false);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "../include/vfs.h"
|
||||
#include "../include/vdisk.h"
|
||||
#include "../include/printf.h"
|
||||
|
||||
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_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);
|
||||
uint32_t load_elf(Elf32_Ehdr *hdr,page_directory_t *pdt);
|
||||
void elf32LoadData(Elf32_Ehdr *elfhdr, uint8_t *ptr);
|
||||
uint32_t elf32_get_max_vaddr(Elf32_Ehdr *hdr);
|
||||
|
||||
#endif /* elf.h */
|
||||
|
|
|
@ -79,6 +79,14 @@ typedef struct mmap_entry_t {
|
|||
uint32_t type;
|
||||
} __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 * 指针
|
||||
// 内核未建立分页机制前暂存的指针
|
||||
extern multiboot_t *mboot_ptr_tmp;
|
||||
|
|
|
@ -31,23 +31,24 @@ struct context{
|
|||
uint32_t eip;
|
||||
uint32_t ds;
|
||||
uint32_t cs;
|
||||
uint32_t ss;
|
||||
};
|
||||
|
||||
// 进程控制块 PCB
|
||||
struct task_struct {
|
||||
volatile task_state state; // 进程当前状态
|
||||
int pid; // 进程标识符
|
||||
int mem_size; //内存利用率
|
||||
char *name; // 进程名
|
||||
void *stack; // 进程的内核栈地址
|
||||
header_t *head;
|
||||
volatile task_state state; // 进程当前状态
|
||||
int pid; // 进程标识符
|
||||
int mem_size; // 内存利用率
|
||||
char *name; // 进程名
|
||||
void *stack; // 进程的内核栈地址
|
||||
header_t *head; // 进程堆
|
||||
header_t *tail;
|
||||
bool isUser;
|
||||
uint32_t program_break;
|
||||
uint32_t program_break_end;
|
||||
page_directory_t *pgd_dir; // 进程页表
|
||||
struct context context; // 上下文信息
|
||||
struct task_struct *next; // 链表指针
|
||||
bool isUser; // 是否是用户进程
|
||||
uint32_t program_break; // 进程堆基址
|
||||
uint32_t program_break_end; // 进程堆尾
|
||||
page_directory_t *pgd_dir; // 进程页表
|
||||
struct context context; // 上下文信息
|
||||
struct task_struct *next; // 链表指针
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
||||
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("Memory Size: %dMB\n",(multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1);
|
||||
gdt_install();
|
||||
|
|
|
@ -44,8 +44,10 @@ void panic_pane(char* msg,enum PANIC_TYPE type){
|
|||
back_color = 0x1e90ff;
|
||||
color = 0xffffff;
|
||||
screen_clear();
|
||||
if(panic_bmp != NULL)
|
||||
display(panic_bmp,0,0,true);
|
||||
if(panic_bmp != NULL){
|
||||
display(panic_bmp,0,0,false);
|
||||
} else klogf(false,"Cannot draw panic image.\n");
|
||||
|
||||
cx = 10;
|
||||
cy = c_height - 10;
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#include "../include/graphics.h"
|
||||
#include "../include/io.h"
|
||||
|
||||
extern asm_syscall_handler();
|
||||
|
||||
void syscall_handler(registers_t regs){
|
||||
io_cli();
|
||||
printf("Syscall is enable.\n");
|
||||
|
@ -18,5 +16,5 @@ void syscall_handler(registers_t regs){
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
kfree(argv);
|
||||
|
@ -175,15 +175,17 @@ void change_task_to(registers_t *reg,struct task_struct *next) {
|
|||
prev->context.ds = reg->ds;
|
||||
prev->context.cs = reg->cs;
|
||||
prev->context.eax = reg->eax;
|
||||
prev->context.ss = reg->ss;
|
||||
switch_to(&(prev->context), &(current->context));
|
||||
reg->ds = current->context.ds;
|
||||
reg->cs = current->context.cs;
|
||||
reg->eip = current->context.eip;
|
||||
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;
|
||||
if(path == NULL){
|
||||
return -1;
|
||||
|
@ -216,6 +218,8 @@ int32_t user_process(char *path, char *name){
|
|||
|
||||
page_switch(page);
|
||||
|
||||
printf("TASK I\n");
|
||||
|
||||
for (int i = USER_START; i < USER_END;i++) {
|
||||
page_t *pg = get_page(i,1,page, false);
|
||||
alloc_frame(pg,0,1);
|
||||
|
@ -223,8 +227,10 @@ int32_t user_process(char *path, char *name){
|
|||
|
||||
char* buffer = user_alloc(new_task,size);
|
||||
|
||||
printf("TASK II\n");
|
||||
|
||||
memset(buffer,0,size);
|
||||
vfs_readfile(path,buffer);
|
||||
vfs_readfile(path,buffer); //能加载, 但是执行一会就不知道跳哪里去了,给自己爆了
|
||||
|
||||
Elf32_Ehdr *ehdr = buffer;
|
||||
if(!elf32Validate(ehdr)){
|
||||
|
@ -233,6 +239,7 @@ int32_t user_process(char *path, char *name){
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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();
|
||||
struct task_struct *new_task = (struct task_struct *) kmalloc(STACK_SIZE);
|
||||
assert(new_task != NULL, "kern_thread: kmalloc error");
|
||||
|
@ -316,7 +323,6 @@ void kthread_exit() {
|
|||
register uint32_t val asm ("eax");
|
||||
printf("Task [PID: %d] exited with value %d\n", current->pid,val);
|
||||
task_kill(current->pid);
|
||||
current->state = TASK_DEATH;
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,22 @@ bool elf32Validate(Elf32_Ehdr *hdr) {
|
|||
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);
|
||||
|
||||
int d = phdr->p_paddr;
|
||||
if (d & 0x00000fff) {
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
if (phdr->p_memsz > phdr->p_filesz) { // 这个是bss段
|
||||
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) {
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)hdr + hdr->e_phoff);
|
||||
static uint32_t reload_elf_file(uint8_t *file_buffer) {
|
||||
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++) {
|
||||
load_segment(phdr,pdt, (void *)hdr);
|
||||
if (phdr->p_type != PT_LOAD) {
|
||||
continue;
|
||||
}
|
||||
load_segment(phdr, pdt, (void *) hdr);
|
||||
phdr++;
|
||||
}
|
||||
return hdr->e_entry;
|
||||
}
|
||||
|
||||
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++) {
|
||||
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)) {
|
||||
continue;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue