2023-02-06 02:27:33 -06:00
|
|
|
#include "progs.h"
|
2024-01-07 22:33:27 -06:00
|
|
|
#include "paging.h"
|
2023-02-14 23:48:11 -06:00
|
|
|
#include "file.h"
|
2023-02-06 02:27:33 -06:00
|
|
|
|
2023-02-17 01:41:30 -06:00
|
|
|
extern char _USERMODE, _USERMODE_END;
|
2024-01-07 22:33:27 -06:00
|
|
|
static uintptr_t USERMODE_STACK = (uintptr_t)&_USERMODE_END - 0x100000;
|
2023-02-06 05:49:03 -06:00
|
|
|
extern uint32_t create_user_child(uint32_t esp, uint32_t eip, uint32_t argc, ...);
|
2024-01-07 22:33:27 -06:00
|
|
|
void programLoadTestInner(char *path) {
|
2023-02-06 05:49:03 -06:00
|
|
|
uint16_t *vga_text = (uint16_t *)0xb8000;
|
|
|
|
for (int i = 0; i < 80*25; i++)
|
|
|
|
vga_text[i] = 0x0f00;
|
|
|
|
uint32_t successcount;
|
2024-01-07 22:33:27 -06:00
|
|
|
|
2023-02-12 00:42:14 -06:00
|
|
|
uint8_t *diskReadBuf = (uint8_t *)&_USERMODE;
|
2023-02-06 05:49:03 -06:00
|
|
|
{
|
|
|
|
uint32_t err;
|
2023-02-17 06:21:43 -06:00
|
|
|
dirent de;
|
|
|
|
err = path_getinfo(path, &de);
|
2024-01-07 22:33:27 -06:00
|
|
|
if (de.size > 0xE00000 || err) {
|
2023-02-17 06:21:43 -06:00
|
|
|
vga_text += printStr("File too large or error.", vga_text);
|
|
|
|
return;
|
|
|
|
}
|
2023-02-14 23:48:11 -06:00
|
|
|
FILE file;
|
|
|
|
err = file_open(&file, path, OPENREAD);
|
2023-02-06 05:49:03 -06:00
|
|
|
if (err) {
|
|
|
|
vga_text += printStr("Open Error: ", vga_text);
|
|
|
|
printDword(err, vga_text);
|
|
|
|
return;
|
|
|
|
}
|
2023-02-14 23:48:11 -06:00
|
|
|
err = file_seek(&file, 0);
|
|
|
|
if (err) {
|
2023-02-06 05:49:03 -06:00
|
|
|
vga_text += printStr("Seek Error", vga_text);
|
|
|
|
return;
|
|
|
|
}
|
2023-02-17 06:21:43 -06:00
|
|
|
successcount = err = file_read(&file, diskReadBuf, de.size);
|
|
|
|
if (!err && de.size > 0) {
|
2023-02-14 23:48:11 -06:00
|
|
|
vga_text += printStr("Read Error", vga_text);
|
2023-02-06 05:49:03 -06:00
|
|
|
printDword(err, vga_text);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vga_text += printStr("Successfully loaded program \"", vga_text);
|
|
|
|
vga_text += printStr((char*)path, vga_text);
|
|
|
|
vga_text += printStr("\", ", vga_text);
|
|
|
|
vga_text += printDec(successcount, vga_text);
|
|
|
|
vga_text += printStr(" Bytes.", vga_text);
|
2023-02-10 04:45:47 -06:00
|
|
|
vga_text = nextLine(vga_text,(uint16_t*)0xb8000);
|
2023-02-06 05:49:03 -06:00
|
|
|
vga_text += printStr("Press any key to run.", vga_text);
|
|
|
|
kbd_wait();
|
2024-01-07 22:33:27 -06:00
|
|
|
uint32_t res = create_user_child(USERMODE_STACK, (uintptr_t)&_USERMODE, 0);
|
|
|
|
|
2023-02-08 03:41:13 -06:00
|
|
|
union V86Regs_t regs;
|
|
|
|
regs.w.ax = 3; // text mode
|
|
|
|
V8086Int(0x10, ®s);
|
2023-02-06 05:49:03 -06:00
|
|
|
vga_text = (uint16_t *)0xb8000;
|
|
|
|
for (int i = 0; i < 80*25; i++)
|
|
|
|
vga_text[i] = 0x0f00;
|
|
|
|
vga_text += printStr("Program returned code: ", vga_text);
|
|
|
|
vga_text += printDec(res, vga_text);
|
|
|
|
vga_text += printStr(" (0x", vga_text);
|
|
|
|
vga_text += printDword(res, vga_text);
|
|
|
|
vga_text += printStr("). Press any key to exit.", vga_text);
|
2024-01-07 22:33:27 -06:00
|
|
|
}
|
|
|
|
void ProgramLoadTest(char *path) {
|
|
|
|
// Get free memory (8MB)
|
|
|
|
uintptr_t process_page0 = add_pages(4|2|1);
|
|
|
|
uintptr_t process_page1 = add_pages(4|2|1);
|
|
|
|
// Map usermode memory
|
|
|
|
move_pages(process_page0 >> 22, (uintptr_t)&_USERMODE >> 22);
|
|
|
|
move_pages(process_page1 >> 22, ((uintptr_t)&_USERMODE >> 22) + 1);
|
|
|
|
// Inner program
|
|
|
|
programLoadTestInner(path);
|
2023-02-06 05:49:03 -06:00
|
|
|
kbd_wait();
|
2024-01-07 22:33:27 -06:00
|
|
|
// Free process memory
|
|
|
|
free_pages(process_page0 >> 22);
|
|
|
|
free_pages(process_page1 >> 22);
|
2023-02-06 05:49:03 -06:00
|
|
|
}
|