用户elf加载备份

This commit is contained in:
XIAOYI12 2024-08-14 21:58:29 +08:00
parent ec1ef4e6c2
commit b0e065958d
19 changed files with 147601 additions and 80 deletions

View File

@ -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/*

View File

@ -1,7 +1,7 @@
#include "../include/stdio.h"
int main(){
debug_test();
while (1);
return 0;
}

View File

@ -2,5 +2,6 @@
#define CRASHPOWEROS_STDIO_H
void put_char(char c);
void debug_test();
#endif

View File

@ -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/*

View File

@ -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;
}

View File

@ -1,6 +1,8 @@
global put_char
global debug_test
put_char:
ret
push edx
push eax
mov edx,[ss:esp+12]
@ -8,4 +10,11 @@ put_char:
int 31h
pop eax
pop edx
ret
debug_test:
push edx
mov edx,0x02
int 31h
pop edx
ret

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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))

View 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 */

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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,8 +239,9 @@ 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);
uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE);
*(--stack_top) = (uint32_t) main;
*(--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();
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);
}

View File

@ -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;

147465
src/util/logo.c Normal file

File diff suppressed because it is too large Load Diff