Browse Source

feat: bascule vers le format de noyau linux afin de bénéficier des outils de chargement qui vont bien

develop
Nicolas Hordé 5 years ago
parent
commit
620f63d101
  1. 36
      API.md
  2. 5
      README.md
  3. 1
      include/memory.h
  4. 13
      include/multiboot.h
  5. 391
      include/multiboot2.h
  6. 2
      lib/keyboard.c
  7. 26
      lib/memory.c
  8. 158
      lib/multiboot.c
  9. 10
      lib/process.c
  10. 2
      lib/scheduler.c
  11. 8
      lib/shell.c
  12. 12
      lib/syscall.c
  13. 9
      lib/vesa.c
  14. 18
      lib/video.c
  15. 10
      makefile
  16. 4
      makesyscall.py
  17. 4
      programs/include/libsys.h
  18. 12
      programs/lib/libsys.c
  19. 44
      syscalls.txt
  20. 1
      system/linker.lds
  21. 24
      system/makefile
  22. 88
      system/multiboot.S
  23. 4
      system/system.c
  24. 2
      templates/syscall.c
  25. 435
      tools/build.c
  26. 71
      tools/le_byteshift.h
  27. 28
      tools/makefile

36
API.md

@ -9,28 +9,26 @@ All fonctions in the "libsys" library.
------
`u32 getticks(void);`
`u32 exit(u32 resultcode);`
*Description:Return the internal value of the timer*
*Description:End a task for user or kernel domain*
* syscall id : **4**
* arguments : **0**
* syscall id : **5**
* arguments : **1**
* * argument 1 : **u32 resultcode** *Code result of the execution*
* results : **u32**
* dump of register cpu: **no**
------
`u32 testapi(u32 arg1, u32 arg2, u32 arg3);`
`u32 getticks(void);`
*Description:Simple function to test if SYSCALL API is correctly running*
*Description:Return the internal value of the timer*
* syscall id : **0**
* arguments : **3**
* * argument 1 : **u32 arg1** *first argument of your choice*
* * argument 2 : **u32 arg2** *second argument of your choice*
* * argument 3 : **u32 arg3** *third argument of your choice*
* syscall id : **4**
* arguments : **0**
* results : **u32**
* dump of register cpu: **yes**
* dump of register cpu: **no**
------
@ -45,15 +43,17 @@ All fonctions in the "libsys" library.
------
`u32 exit(u32 resultcode);`
`u32 testapi(u32 arg1, u32 arg2, u32 arg3);`
*Description:End a task for user or kernel domain*
*Description:Simple function to test if SYSCALL API is correctly running*
* syscall id : **5**
* arguments : **1**
* * argument 1 : **u32 resultcode** *Code result of the execution*
* syscall id : **0**
* arguments : **3**
* * argument 1 : **u32 arg1** *first argument of your choice*
* * argument 2 : **u32 arg2** *second argument of your choice*
* * argument 3 : **u32 arg3** *third argument of your choice*
* results : **u32**
* dump of register cpu: **no**
* dump of register cpu: **yes**
### LIBVIDEO

5
README.md

@ -228,8 +228,10 @@ Pour l'instant quelques commandes seulement sont disponibles:
#### En cours
* correction de bogues - stabilisation du projet
* correction de bogues - libération des ressources après destruction processus,
* liste d'API automatiquement mise à jour avec intégration de librairies & header,
* gestion du système de fichier CRAMFS,
* lancement du noyau par kernel et non par multiboot afin de bénéficier de initrd,
#### A faire
@ -247,6 +249,7 @@ Pour l'instant quelques commandes seulement sont disponibles:
Des fichiers sources utilisés par COS2000 sont sous d'autres licences, parmis ceux-ci figurent :
* `include/queues.h` sous licence Berkeley Software Distribution License
* `tools/*` sous licence GPL V2.0, fichiers issus du noyau Linux
#### Historique du projet
* Version 2.2fr - C en mode protégé Reprise du projet

1
include/memory.h

@ -100,6 +100,7 @@ typedef TAILQ_HEAD(page_s, page) page_t;
typedef TAILQ_HEAD(vrange_s, vrange) vrange_t;
void virtual_pd_show(pd *dst);
void panic(u8 * string);
void memset(void *dst, u8 val, u32 count, u32 size);
void memcpy(void *src, void *dst, u32 count, u32 size);

13
include/multiboot.h

@ -1,13 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "types.h"
#include "multiboot2.h"
u32 getgrubinfo(u8 type);
u8 *getgrubinfo_cmdline(void);
u32 getgrubinfo_ram(void);
struct multiboot_tag_mmap *getgrubinfo_mem(void);
struct multiboot_tag_framebuffer *getgrubinfo_fb(void);
void getgrubinfo_all(void);
void initmultiboot(const u32 addr);

391
include/multiboot2.h

@ -1,391 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#ifndef MULTIBOOT
# define MULTIBOOT
/* How many bytes from the start of the file we search for the header. */
# define MULTIBOOT_SEARCH 32768
# define MULTIBOOT_HEADER_ALIGN 8
/* The magic field should contain this. */
# define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
/* This should be in %eax. */
# define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
/* Alignment of multiboot modules. */
# define MULTIBOOT_MOD_ALIGN 0x00001000
/* Alignment of the multiboot info structure. */
# define MULTIBOOT_INFO_ALIGN 0x00000008
/* Flags set in the 'flags' member of the multiboot header. */
# define MULTIBOOT_TAG_ALIGN 8
# define MULTIBOOT_TAG_TYPE_END 0
# define MULTIBOOT_TAG_TYPE_CMDLINE 1
# define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
# define MULTIBOOT_TAG_TYPE_MODULE 3
# define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
# define MULTIBOOT_TAG_TYPE_BOOTDEV 5
# define MULTIBOOT_TAG_TYPE_MMAP 6
# define MULTIBOOT_TAG_TYPE_VBE 7
# define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
# define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
# define MULTIBOOT_TAG_TYPE_APM 10
# define MULTIBOOT_TAG_TYPE_EFI32 11
# define MULTIBOOT_TAG_TYPE_EFI64 12
# define MULTIBOOT_TAG_TYPE_SMBIOS 13
# define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
# define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
# define MULTIBOOT_TAG_TYPE_NETWORK 16
# define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
# define MULTIBOOT_TAG_TYPE_EFI_BS 18
# define MULTIBOOT_TAG_TYPE_EFI32_IH 19
# define MULTIBOOT_TAG_TYPE_EFI64_IH 20
# define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
# define MULTIBOOT_HEADER_TAG_END 0
# define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
# define MULTIBOOT_HEADER_TAG_ADDRESS 2
# define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
# define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
# define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
# define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
# define MULTIBOOT_HEADER_TAG_EFI_BS 7
# define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
# define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
# define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
# define MULTIBOOT_ARCHITECTURE_I386 0
# define MULTIBOOT_ARCHITECTURE_MIPS32 4
# define MULTIBOOT_HEADER_TAG_OPTIONAL 1
# define MULTIBOOT_LOAD_PREFERENCE_NONE 0
# define MULTIBOOT_LOAD_PREFERENCE_LOW 1
# define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
# define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
# define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
#include "types.h"
struct multiboot_header
{
/* Must be MULTIBOOT_MAGIC - see above. */
u32 magic;
/* ISA */
u32 architecture;
/* Total header length. */
u32 header_length;
/* The above fields plus this one must equal 0 mod 2^32. */
u32 checksum;
};
struct multiboot_header_tag
{
u16 type;
u16 flags;
u32 size;
};
struct multiboot_header_tag_information_request
{
u16 type;
u16 flags;
u32 size;
u32 requests[0];
};
struct multiboot_header_tag_address
{
u16 type;
u16 flags;
u32 size;
u32 header_addr;
u32 load_addr;
u32 load_end_addr;
u32 bss_end_addr;
};
struct multiboot_header_tag_entry_address
{
u16 type;
u16 flags;
u32 size;
u32 entry_addr;
};
struct multiboot_header_tag_console_flags
{
u16 type;
u16 flags;
u32 size;
u32 console_flags;
};
struct multiboot_header_tag_framebuffer
{
u16 type;
u16 flags;
u32 size;
u32 width;
u32 height;
u32 depth;
};
struct multiboot_header_tag_module_align
{
u16 type;
u16 flags;
u32 size;
};
struct multiboot_header_tag_relocatable
{
u16 type;
u16 flags;
u32 size;
u32 min_addr;
u32 max_addr;
u32 align;
u32 preference;
};
struct multiboot_color
{
u8 red;
u8 green;
u8 blue;
};
struct multiboot_mmap_entry
{
u64 addr;
u64 len;
# define MULTIBOOT_MEMORY_AVAILABLE 1
# define MULTIBOOT_MEMORY_RESERVED 2
# define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
# define MULTIBOOT_MEMORY_NVS 4
# define MULTIBOOT_MEMORY_BADRAM 5
u32 type;
u32 zero;
};
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
struct multiboot_tag
{
u32 type;
u32 size;
};
struct multiboot_tag_string
{
u32 type;
u32 size;
u8 string[0];
};
struct multiboot_tag_module
{
u32 type;
u32 size;
u32 mod_start;
u32 mod_end;
u8 cmdline[0];
};
struct multiboot_tag_basic_meminfo
{
u32 type;
u32 size;
u32 mem_lower;
u32 mem_upper;
};
struct multiboot_tag_bootdev
{
u32 type;
u32 size;
u32 biosdev;
u32 slice;
u32 part;
};
struct multiboot_tag_mmap
{
u32 type;
u32 size;
u32 entry_size;
u32 entry_version;
struct multiboot_mmap_entry entries[0];
};
struct multiboot_vbe_info_block
{
u8 external_specification[512];
};
struct multiboot_vbe_mode_info_block
{
u8 external_specification[256];
};
struct multiboot_tag_vbe
{
u32 type;
u32 size;
u16 vbe_mode;
u16 vbe_interface_seg;
u16 vbe_interface_off;
u16 vbe_interface_len;
struct multiboot_vbe_info_block vbe_control_info;
struct multiboot_vbe_mode_info_block vbe_mode_info;
};
struct multiboot_tag_framebuffer_common
{
u32 type;
u32 size;
u64 framebuffer_addr;
u32 framebuffer_pitch;
u32 framebuffer_width;
u32 framebuffer_height;
u8 framebuffer_bpp;
# define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
# define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
# define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
u8 framebuffer_type;
u16 reserved;
};
struct multiboot_tag_framebuffer
{
struct multiboot_tag_framebuffer_common common;
union
{
struct
{
u16 framebuffer_palette_num_colors;
struct multiboot_color framebuffer_palette[0];
};
struct
{
u8 framebuffer_red_field_position;
u8 framebuffer_red_mask_size;
u8 framebuffer_green_field_position;
u8 framebuffer_green_mask_size;
u8 framebuffer_blue_field_position;
u8 framebuffer_blue_mask_size;
};
};
};
struct multiboot_tag_elf_sections
{
u32 type;
u32 size;
u32 num;
u32 entsize;
u32 shndx;
u8 sections[0];
};
struct multiboot_tag_apm
{
u32 type;
u32 size;
u16 version;
u16 cseg;
u32 offset;
u16 cseg_16;
u16 dseg;
u16 flags;
u16 cseg_len;
u16 cseg_16_len;
u16 dseg_len;
};
struct multiboot_tag_efi32
{
u32 type;
u32 size;
u32 pointer;
};
struct multiboot_tag_efi64
{
u32 type;
u32 size;
u64 pointer;
};
struct multiboot_tag_smbios
{
u32 type;
u32 size;
u8 major;
u8 minor;
u8 reserved[6];
u8 tables[0];
};
struct multiboot_tag_old_acpi
{
u32 type;
u32 size;
u8 rsdp[0];
};
struct multiboot_tag_new_acpi
{
u32 type;
u32 size;
u8 rsdp[0];
};
struct multiboot_tag_network
{
u32 type;
u32 size;
u8 dhcpack[0];
};
struct multiboot_tag_efi_mmap
{
u32 type;
u32 size;
u32 descr_size;
u32 descr_vers;
u8 efi_mmap[0];
};
struct multiboot_tag_efi32_ih
{
u32 type;
u32 size;
u32 pointer;
};
struct multiboot_tag_efi64_ih
{
u32 type;
u32 size;
u64 pointer;
};
struct multiboot_tag_load_base_addr
{
u32 type;
u32 size;
u32 load_base_addr;
};
#endif

2
lib/keyboard.c

@ -133,7 +133,7 @@ u8 *getstring(u8 * temp)
"ARGS": [],
"RETURN":"u8"
}
END */
END-SYSCALL */
u8 waitascii(void)
{

26
lib/memory.c

@ -3,7 +3,6 @@
/* */
#include "types.h"
#include "memory.h"
#include "multiboot2.h"
#include "queue.h"
#include "asm.h"
@ -155,7 +154,7 @@ void vfree(void *vaddr)
u64 physical_getmemorysize()
{
u64 maxaddr = 0;
/*u64 maxaddr = 0;
struct multiboot_tag_mmap *tag = getgrubinfo_mem();
multiboot_memory_map_t *mmap;
for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;
@ -168,7 +167,7 @@ u64 physical_getmemorysize()
maxaddr = mmap->addr + mmap->len;
if (maxaddr >= MAXMEMSIZE)
maxaddr = MAXMEMSIZE - 1;
return maxaddr;
return maxaddr;*/
}
/*******************************************************************************/
@ -261,7 +260,7 @@ u64 getmemoryfree(void)
void physical_init(void)
{
u64 page;
/*u64 page;
for (page = 0; page < sizeof(bitmap); page++)
bitmap[page] = 0xFF;
struct multiboot_tag_mmap *tag = getgrubinfo_mem();
@ -276,7 +275,7 @@ void physical_init(void)
physical_range_free(mmap->addr, mmap->len);
else
physical_range_use(mmap->addr, mmap->len);
physical_range_use(0x0, KERNELSIZE);
physical_range_use(0x0, KERNELSIZE);*/
}
/*******************************************************************************/
@ -590,6 +589,23 @@ void virtual_pd_destroy(pd * dst)
return 0;
}
/*******************************************************************************/
/* Affiche toutes les page du directory */
void virtual_pd_show(pd *dst)
{
page *pg;
bool first=true;
TAILQ_FOREACH(pg, &dst->page_head, tailq)
{
if (!first)
print(",");
else
first=false;
printf("%Y",(u32)pg->vaddr);
}
}
/*******************************************************************************/
/* Initialise une pages virtuelles (size) pour le heap du noyau */

158
lib/multiboot.c

@ -1,158 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "multiboot2.h"
static u32 infobloc;
/*******************************************************************************/
/* Initialise avec l'adresse du bloc multiboot2 */
void initmultiboot(const u32 addr)
{
infobloc = addr;
}
/*******************************************************************************/
/* Renvoie les informations souhaitées multiboot2 */
u32 getgrubinfo(u8 type)
{
struct multiboot_tag *tag;
unsigned size = *(unsigned *) infobloc;
for (tag = (struct multiboot_tag *) (infobloc + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag =
(struct multiboot_tag *) ((u8 *) tag +
((tag->size + 7) & ~7)))
if (tag->type == type)
return tag;
}
/*******************************************************************************/
/* Renvoie la ligne de commande */
u8 *getgrubinfo_cmdline(void)
{
struct multiboot_tag_string *tag =
getgrubinfo(MULTIBOOT_TAG_TYPE_CMDLINE);
return tag->string;
}
/*******************************************************************************/
/* Renvoie la quantité de mémoire */
u32 getgrubinfo_ram(void)
{
struct multiboot_tag_basic_meminfo *tag =
getgrubinfo(MULTIBOOT_TAG_TYPE_BASIC_MEMINFO);
return tag->mem_upper;
}
/*******************************************************************************/
/* Renvoie le plan de la mémoire */
struct multiboot_tag_mmap *getgrubinfo_mem(void)
{
struct multiboot_tag_mmap *tag =
getgrubinfo(MULTIBOOT_TAG_TYPE_MMAP);
return tag;
}
/*******************************************************************************/
/* Renvoie les information sur le framebuffer */
struct multiboot_tag_framebuffer *getgrubinfo_fb(void)
{
struct multiboot_tag_framebuffer *tag =
getgrubinfo(MULTIBOOT_TAG_TYPE_FRAMEBUFFER);
return tag;
}
/*******************************************************************************/
/* Affiche les informations multiboot2 ;*/
void getgrubinfo_all(void)
{
struct multiboot_tag *tag;
u32 size = *(unsigned *) infobloc;
if (infobloc & 7)
print("Attention : Bloc non aligne...");
printf(" Taille :% 4u\r\n", (u32) size);
for (tag = (struct multiboot_tag *) (infobloc + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag =
(struct multiboot_tag *) ((u8 *) tag +
((tag->size + 7) & ~7)))
{
printf("--- Tag % hu, Taille % hu\r\n", tag->type,
tag->size);
switch (tag->type)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
printf(" Ligne de lancement : %s\r\n",
((struct multiboot_tag_string *)
tag)->string);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
printf(" Chargeur de boot : %s\r\n",
((struct multiboot_tag_string *)
tag)->string);
break;
case MULTIBOOT_TAG_TYPE_MODULE:
printf(" Module %X-%X. Command line %s\r\n", ((struct multiboot_tag_module *) tag)->mod_start, ((struct multiboot_tag_module *) tag)->mod_end, ((struct multiboot_tag_module *) tag)->cmdline);
break;
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
printf(" Memoire basse : %H, memoire haute = %lH\r\n", ((struct multiboot_tag_basic_meminfo *) tag)->mem_lower << 10, ((u64) ((struct multiboot_tag_basic_meminfo *) tag)->mem_upper) << 10);
break;
case MULTIBOOT_TAG_TYPE_BOOTDEV:
printf(" Peripherique de demarrage : %Y,%u,%u\r\n\r\n", ((struct multiboot_tag_bootdev *) tag)->biosdev, ((struct multiboot_tag_bootdev *) tag)->slice, ((struct multiboot_tag_bootdev *) tag)->part);
break;
case MULTIBOOT_TAG_TYPE_MMAP:
{
multiboot_memory_map_t *mmap;
printf("*** Plan de memoire ***\r\n");
for (mmap =
((struct multiboot_tag_mmap *)
tag)->entries;
(u8 *) mmap < (u8 *) tag + tag->size;
mmap =
(multiboot_memory_map_t
*) ((unsigned long) mmap +
((struct multiboot_tag_mmap *)
tag)->entry_size))
printf(" adresse: %lY, taille:%lY, type:%Y\r\n", (u64) (mmap->addr), (u64) (mmap->len), (u32) (mmap->type));
break;
}
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
{
struct multiboot_tag_framebuffer *tagfb =
(struct multiboot_tag_framebuffer
*) tag;
printf(" Framebuffer, resolution %d*%d*%d adresse: %X, ", tagfb->common.framebuffer_width, tagfb->common.framebuffer_height, tagfb->common.framebuffer_bpp, tagfb->common.framebuffer_addr);
switch (tagfb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
printf("mode graphique indexé\r\n");
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
printf("mode graphique RGB\r\n");
break;
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
printf("mode texte EGA\r\n");
break;
}
break;
}
case MULTIBOOT_TAG_TYPE_VBE:
{
struct multiboot_tag_vbe *tagvbe =
(struct multiboot_tag_framebuffer
*) tag;
printf(" VBE 2.0, mode %Y, adresse %hY:%hY-%hY\r\n", tagvbe->vbe_mode, tagvbe->vbe_interface_seg, tagvbe->vbe_interface_off, tagvbe->vbe_interface_len);
}
}
}
}
/*******************************************************************************/

10
lib/process.c

@ -72,7 +72,7 @@ u32 iself(u8 * src)
],
"RETURN":"u32"
}
END */
END-SYSCALL */
void processexit(void)
{
@ -273,6 +273,7 @@ void switchtask(tid_t tid)
}
if (((atask->dump.cs & 0xFFF8) !=SEL_KERNEL_CODE) && ((atask->dump.cs & 0xFFF8) !=SEL_USER_CODE))
cpuerror("SWITCH ERROR", &atask->dump, false);
//printf("%Y\r\n",atask->tid.pid);
atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF;
createdump(atask->dump);
if ((atask->dump.cs & 0xFFF8)==SEL_KERNEL_CODE)
@ -433,10 +434,12 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
}
else
{
TAILQ_INSERT_TAIL(&aprocess->pdd->page_head, apage, tailq);
new->kernel_stack.ss0 = SEL_KERNEL_STACK;
new->kernel_stack.esp0 =
(u32) apage->vaddr + PAGESIZE - 16;
page *apage = virtual_page_getfree();
TAILQ_INSERT_TAIL(&aprocess->pdd->page_head, apage, tailq);
new->syscall_stack.ss0 = SEL_KERNEL_STACK;
new->syscall_stack.esp0 =
(u32) apage->vaddr + PAGESIZE - 16;
@ -517,11 +520,12 @@ void deleteprocess(pid_t pid)
stopprocess(pid);
process* aprocess=findprocess(pid);
if (aprocess==NULL) return;
if (current.pid==pid)
current=maketid(1,1);
task *next;
TAILQ_FOREACH(next, &aprocess->task_head, tailq)
deletetask(next->tid);
virtual_pd_destroy(aprocess->pdd);
if (current.pid==pid)
current=maketid(1,1);
aprocess->status = PROCESS_STATUS_FREE;
sti();
}

2
lib/scheduler.c

@ -28,7 +28,7 @@ static u32 time = 0;
"ARGS": [],
"RETURN":"u32"
}
END */
END-SYSCALL */
u32 gettimer(void)
{

8
lib/shell.c

@ -11,7 +11,6 @@
#include "string.h"
#include "gdt.h"
#include "shell.h"
#include "multiboot2.h"
#include "math.h"
#include "debug.h"
#include "VGA/ansi.c"
@ -100,11 +99,13 @@ static u8* taskstatus[] = {"PRET ","EXEC.","PAUSE"};
int ps()
{
print("*** Processus en memoire\r\n| PID | Parent|Status|K|P.| Pages|\r\n");
print("*** Processus en memoire\r\n| PID | Parent|Status|K|P.|Directo.|Pages...\r\n");
process* aprocess=findprocess((pid_t)1);
while(true)
{
printf("|%Y|%Y| %s|%c|%hh u|%Y|\r\n",(u32)aprocess->pid,(u32)aprocess->parent,processstatus[aprocess->status],(aprocess->iskernel?'X':' '),aprocess->priority,(u32)aprocess->pdd);
printf("|%Y|%Y| %s|%c|%hh u|%Y|",(u32)aprocess->pid,(u32)aprocess->parent,processstatus[aprocess->status],(aprocess->iskernel?'X':' '),aprocess->priority,(u32)aprocess->pdd);
if (aprocess->pdd!=NULL) virtual_pd_show(aprocess->pdd);
print("\r\n");
aprocess=getnextprocess(aprocess,PROCESS_STATUS_ALL);
if (aprocess==NULL || aprocess->pid==(pid_t)1) break;
}
@ -477,7 +478,6 @@ int err(u8 * commandline)
/* Information sur le démarrage */
int showinfo()
{
getgrubinfo_all();
return 0;
}

12
lib/syscall.c

@ -47,7 +47,7 @@ void initsyscall(void)
"RETURN":"u32",
"DUMP":"yes"
}
END */
END-SYSCALL */
u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump)
{
@ -62,20 +62,20 @@ __attribute__ ((noreturn)) void sysenter_handler(regs *dump)
sti();
switch (dump->eax)
{
case 5:
dump->eax=(u32) processexit(dump->ebx);
break;
case 4:
dump->eax=(u32) gettimer();
break;
case 2:
dump->eax=(u32) print(dump->ebx);
break;
case 0:
dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump);
break;
case 1:
dump->eax=(u32) waitascii();
break;
case 5:
dump->eax=(u32) processexit(dump->ebx);
case 0:
dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump);
break;
default:

9
lib/vesa.c

@ -6,7 +6,6 @@
#include "memory.h"
#include "asm.h"
#include "types.h"
#include "multiboot2.h"
static videoinfos infos;
@ -19,11 +18,11 @@ static capabilities vesacapabilities[] = {
void VESA_remap_memory(u32 vaddr)
{
struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb();
/* struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb();
u32 len = infos.pagesize * 2;
u32 paddr = tagfb->common.framebuffer_addr;
virtual_range_use_kernel(vaddr, paddr, len, PAGE_NOFLAG);
infos.baseaddress = vaddr;
infos.baseaddress = vaddr;*/
}
/*******************************************************************************/
@ -31,7 +30,7 @@ void VESA_remap_memory(u32 vaddr)
u8 *VESA_detect_hardware(void)
{
struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb();
/* struct multiboot_tag_framebuffer *tagfb = getgrubinfo_fb();
switch (tagfb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
@ -54,7 +53,7 @@ u8 *VESA_detect_hardware(void)
case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
return NULL;
break;
}
}*/
}
/*******************************************************************************/

18
lib/video.c

@ -1045,7 +1045,7 @@ void triangle(vertex2d * AA, vertex2d * BB, vertex2d * CC, u32 color)
],
"RETURN":"u32"
}
END */
END-SYSCALL */
u32 print(u8 * string)
{
@ -1082,6 +1082,11 @@ u32 storestr(u8 * src, u8 ** dest, u32 len)
return len;
}
/* EXPORT
{
"LIBRARY":"libsys"
}
*/
#define maxbuffersize 4096
/*******************************************************************************/
@ -1155,14 +1160,18 @@ u32 format(const u8 * string, va_list args, u32 maxsize,
u8 strbase16[] = "0x\000";
u8 hexadecimal[] = "*0x\000";
u8 achar, temp;
u8 asize, charadd, unit, precisioni, precisionf;
u8 asize=2;
u8 charadd=0xFF;
u8 unit = 0;
u8 precisioni = 0;
u8 precisionf = 0;
u8 buffer[maxbuffersize];
u8 *bufferend;
u32 buffersize;
u8 *str = string;
u8 *strtemp;
u32 i = 0, counter = 0;
u64 num;
u64 num = 0;
bool flag = false, intok = false, decok = false;
for (achar = *str; achar != '\000'; i++, achar = *(str + i))
@ -1383,7 +1392,6 @@ u32 format(const u8 * string, va_list args, u32 maxsize,
u64);
if (charadd == 0xFF)
charadd = ' ';
unit = 0;
while (num > 1024 * 10)
{
num = num >> 10;
@ -1715,3 +1723,5 @@ u8 *sitoa(u64 num, u8 * str, u64 dim)
strinvert(str);
return pointer;
}
/* END-EXPORT */

10
makefile

@ -1,4 +1,4 @@
all: programs bits32 bits64 harddisk uefi
all: tools programs bits32 bits64 harddisk uefi
sync
bits32: ARCH=bits32
@ -9,6 +9,11 @@ bits64: ARCH=bits64
bits64: lib/libs.o system/system.sys
sync
tools: tools/build
tools/build:
make -C tools
syscall: clean remakeapi all
remakeapi:
@ -37,6 +42,7 @@ togit:
make -C lib togit
make -C final togit
make -C programs togit
make -C tools togit
git status
sync
@ -45,6 +51,7 @@ clean:
make -C lib clean
make -C final clean
make -C programs clean
make -C tools clean
sync
littleclean:
@ -58,6 +65,7 @@ indent:
make -C system indent
make -C lib indent
make -C programs indent
make -C tools indent
sync
backup: clean

4
makesyscall.py

@ -41,7 +41,7 @@ def get_duplicates(sorted_list):
path = "./"
files = os.listdir(path)
pattern = r'\/\* SYSCALL.*END \*\/'
pattern = r'\/\* SYSCALL.*END-SYSCALL \*\/'
output_file = "syscalls.txt"
if os.path.exists(output_file):
os.remove(output_file)
@ -59,7 +59,7 @@ for root, dirs, files in os.walk(path):
results = re.findall(pattern, content, re.MULTILINE| re.DOTALL)
for result in results:
print("Fichier :"+os.path.join(root, name))
new=string.replace(string.replace(result,"/* SYSCALL ",""),"END */","")
new=string.replace(string.replace(result,"/* SYSCALL ",""),"END-SYSCALL */","")
if fo.tell()>2:
new=","+new;
fo.write(new+"\r\n")

4
programs/include/libsys.h

@ -4,8 +4,8 @@
#include "types.h";
u32 exit(u32 resultcode);
u32 getticks(void);
u32 testapi(u32 arg1, u32 arg2, u32 arg3);
u8 waitkey(void);
u32 exit(u32 resultcode);
u32 testapi(u32 arg1, u32 arg2, u32 arg3);

12
programs/lib/libsys.c

@ -6,14 +6,14 @@
#include "syscall.h";
#include "types.h";
u32 getticks(void)
u32 exit(u32 resultcode)
{
return syscall0(4);
return syscall1(5,(u32) resultcode);
}
u32 testapi(u32 arg1, u32 arg2, u32 arg3)
u32 getticks(void)
{
return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3);
return syscall0(4);
}
u8 waitkey(void)
@ -21,9 +21,9 @@ u8 waitkey(void)
return syscall0(1);
}
u32 exit(u32 resultcode)
u32 testapi(u32 arg1, u32 arg2, u32 arg3)
{
return syscall1(5,(u32) resultcode);
return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3);
}

44
syscalls.txt

@ -1,5 +1,18 @@
[
{
"ID":5,
"LIBRARY":"libsys",
"NAME":"exit",
"INTERNALNAME":"processexit",
"DESCRIPTION":"End a task for user or kernel domain",
"ARGS": [
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
],
"RETURN":"u32"
}
,
{
"ID":4,
"NAME":"getticks",
"LIBRARY":"libsys",
@ -22,22 +35,6 @@
"RETURN":"u32"
}
,
{
"ID":0,
"LIBRARY":"libsys",
"NAME":"testapi",
"INTERNALNAME":"testapi",
"DESCRIPTION":"Simple function to test if SYSCALL API is correctly running",
"ARGS": [
{"TYPE":"u32","NAME":"arg1","DESCRIPTION":"first argument of your choice"},
{"TYPE":"u32","NAME":"arg2","DESCRIPTION":"second argument of your choice"},
{"TYPE":"u32","NAME":"arg3","DESCRIPTION":"third argument of your choice"}
],
"RETURN":"u32",
"DUMP":"yes"
}
,
{
"ID":1,
@ -51,15 +48,18 @@
,
{
"ID":5,
"ID":0,
"LIBRARY":"libsys",
"NAME":"exit",
"INTERNALNAME":"processexit",
"DESCRIPTION":"End a task for user or kernel domain",
"NAME":"testapi",
"INTERNALNAME":"testapi",
"DESCRIPTION":"Simple function to test if SYSCALL API is correctly running",
"ARGS": [
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
{"TYPE":"u32","NAME":"arg1","DESCRIPTION":"first argument of your choice"},
{"TYPE":"u32","NAME":"arg2","DESCRIPTION":"second argument of your choice"},
{"TYPE":"u32","NAME":"arg3","DESCRIPTION":"third argument of your choice"}
],
"RETURN":"u32"
"RETURN":"u32",
"DUMP":"yes"
}
]

1
system/linker.lds

@ -1,5 +1,6 @@
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
OUPUT(system.bin)
ENTRY(start)

24
system/makefile

@ -1,24 +1,32 @@
GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m32 -fno-pie -no-pie -c -o
GCCREAL=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m16 -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -mstack-alignment=4 -mno-80387 -mno-fp-ret-in-387 -c -o
ASM=gcc -nostdinc -ffreestanding -fno-builtin -m32 -c -fno-pie -no-pie
LINK=ld -m elf_i386 -T linker.lds -n -o
LINK=ld -m elf_i386 -n -o
CONVERT=dos2unix
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
REMOVE=rm -f
CHANGEPERM=chmod 644
all: system.sys
all: system.sys
system.sys: setup.bin system.bin
tools/build setup.bin system.bin zoffset.h system.sys
sync
togit: clean indent
system.sys: multiboot.o system.o ../lib/libs.o
$(LINK) system.sys multiboot.o system.o ../lib/libs.o
system.bin: system.o ../lib/libs.o
$(LINK) -T linker.lds multiboot.o system.o ../lib/libs.o
system.o:
$(GCC) system.o system.c
setup.bin: setup.o
$(LINK) $@ $^
$(OBJDUMP)
multiboot.o:
$(ASM) multiboot.S -DVESA=$(VESA)
setup.o:
$(GCCREAL) $@ $^
system.o:
$(GCC) $@ $^
clean:
$(REMOVE) *.o

88
system/multiboot.S

@ -1,88 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#define MULTIBOOT_SEARCH 32768
#define MULTIBOOT_HEADER_ALIGN 8
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
#define MULTIBOOT_MOD_ALIGN 0x00001000
#define MULTIBOOT_INFO_ALIGN 0x00000008
#define MULTIBOOT_TAG_ALIGN 8
#define MULTIBOOT_TAG_TYPE_END 0
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
#define MULTIBOOT_TAG_TYPE_MODULE 3
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
#define MULTIBOOT_TAG_TYPE_MMAP 6
#define MULTIBOOT_TAG_TYPE_VBE 7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
#define MULTIBOOT_TAG_TYPE_APM 10
#define MULTIBOOT_TAG_TYPE_EFI32 11
#define MULTIBOOT_TAG_TYPE_EFI64 12
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
#define MULTIBOOT_TAG_TYPE_NETWORK 16
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
#define MULTIBOOT_HEADER_TAG_END 0
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
#define MULTIBOOT_ARCHITECTURE_I386 0
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
.section .multiboot, "a"
.align MULTIBOOT_HEADER_ALIGN
multiboot_header:
.long MULTIBOOT2_HEADER_MAGIC
.long MULTIBOOT_ARCHITECTURE_I386
.long multiboot_header_end - multiboot_header
.long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
#ifdef VESA
#warning VESA active
framebuffer_tag_start:
.align MULTIBOOT_HEADER_ALIGN
.short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
.short MULTIBOOT_HEADER_TAG_OPTIONAL
.long framebuffer_tag_end - framebuffer_tag_start
.long 1024
.long 768
.long 32
framebuffer_tag_end:
#endif
.align MULTIBOOT_HEADER_ALIGN
.short MULTIBOOT_HEADER_TAG_END
.short 0
.long 8
multiboot_header_end:
.section .text
.globl start
start:
pushl %ebx
pushl %eax
call main
hlt

4
system/system.c

@ -46,11 +46,9 @@ void error()
return;
}
int main(u32 magic, u32 addr)
int main(u8* info)
{
cli();
if (magic == MULTIBOOT2_BOOTLOADER_MAGIC)
initmultiboot(addr);
initdriver();
registerdriver(&vgafonctions);
registerdriver(&vesafonctions);

2
templates/syscall.c

@ -47,7 +47,7 @@ void initsyscall(void)
"RETURN":"u32",
"DUMP":"yes"
}
END */
END-SYSCALL */
u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump)
{

435
tools/build.c

@ -0,0 +1,435 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1997 Martin Mares
* Copyright (C) 2007 H. Peter Anvin
*/
/*
* This file builds a disk-image from three different files:
*
* - setup: 8086 machine code, sets up system parm
* - system: 80386 code for actual system
* - zoffset.h: header with ZO_* defines
*
* It does some checking that all files are of the correct type, and writes
* the result to the specified destination, removing headers and padding to
* the right amount. It also writes some system data to stdout.
*/
/*
* Changes by tytso to allow root device specification
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
* Cross compiling fixes by Gertjan van Wingerde, July 1996
* Rewritten by Martin Mares, April 1997
* Substantially overhauled by H. Peter Anvin, April 2007
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <le_byteshift.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#define DEFAULT_MAJOR_ROOT 0
#define DEFAULT_MINOR_ROOT 0
#define DEFAULT_ROOT_DEV (DEFAULT_MAJOR_ROOT << 8 | DEFAULT_MINOR_ROOT)
/* Minimal number of setup sectors */
#define SETUP_SECT_MIN 5
#define SETUP_SECT_MAX 64
/* This must be large enough to hold the entire setup */
u8 buf[SETUP_SECT_MAX*512];
#define PECOFF_RELOC_RESERVE 0x20
unsigned long efi32_stub_entry;
unsigned long efi64_stub_entry;
unsigned long efi_pe_entry;
unsigned long startup_64;
/*----------------------------------------------------------------------*/
static const u32 crctab32[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
0x2d02ef8d
};
static u32 partial_crc32_one(u8 c, u32 crc)
{
return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
}
static u32 partial_crc32(const u8 *s, int len, u32 crc)
{
while (len--)
crc = partial_crc32_one(*s++, crc);
return crc;
}
static void die(const char * str, ...)
{
va_list args;
va_start(args, str);
vfprintf(stderr, str, args);
fputc('\n', stderr);
exit(1);
}
static void usage(void)
{
die("Usage: build setup system zoffset.h image");
}
#ifdef CONFIG_EFI_STUB
static void update_pecoff_section_header_fields(char *section_name, u32 vma, u32 size, u32 datasz, u32 offset)
{
unsigned int pe_header;
unsigned short num_sections;
u8 *section;
pe_header = get_unaligned_le32(&buf[0x3c]);
num_sections = get_unaligned_le16(&buf[pe_header + 6]);
#ifdef CONFIG_X86_32
section = &buf[pe_header + 0xa8];
#else
section = &buf[pe_header + 0xb8];
#endif
while (num_sections > 0) {
if (strncmp((char*)section, section_name, 8) == 0) {
/* section header size field */
put_unaligned_le32(size, section + 0x8);
/* section header vma field */
put_unaligned_le32(vma, section + 0xc);
/* section header 'size of initialised data' field */
put_unaligned_le32(datasz, section + 0x10);
/* section header 'file offset' field */
put_unaligned_le32(offset, section + 0x14);
break;
}
section += 0x28;
num_sections--;
}
}
static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
{
update_pecoff_section_header_fields(section_name, offset, size, size, offset);
}
static void update_pecoff_setup_and_reloc(unsigned int size)
{
u32 setup_offset = 0x200;
u32 reloc_offset = size - PECOFF_RELOC_RESERVE;
u32 setup_size = reloc_offset - setup_offset;
update_pecoff_section_header(".setup", setup_offset, setup_size);
update_pecoff_section_header(".reloc", reloc_offset, PECOFF_RELOC_RESERVE);
/*
* Modify .reloc section contents with a single entry. The
* relocation is applied to offset 10 of the relocation section.
*/
put_unaligned_le32(reloc_offset + 10, &buf[reloc_offset]);
put_unaligned_le32(10, &buf[reloc_offset + 4]);
}
static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
{
unsigned int pe_header;
unsigned int text_sz = file_sz - text_start;
pe_header = get_unaligned_le32(&buf[0x3c]);
/*
* Size of code: Subtract the size of the first sector (512 bytes)
* which includes the header.
*/
put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]);
/*
* Address of entry point for PE/COFF executable
*/
put_unaligned_le32(text_start + efi_pe_entry, &buf[pe_header + 0x28]);
update_pecoff_section_header(".text", text_start, text_sz);
}
static void update_pecoff_bss(unsigned int file_sz, unsigned int init_sz)
{
unsigned int pe_header;
unsigned int bss_sz = init_sz - file_sz;
pe_header = get_unaligned_le32(&buf[0x3c]);
/* Size of uninitialized data */
put_unaligned_le32(bss_sz, &buf[pe_header + 0x24]);
/* Size of image */
put_unaligned_le32(init_sz, &buf[pe_header + 0x50]);
update_pecoff_section_header_fields(".bss", file_sz, bss_sz, 0, 0);
}
static int reserve_pecoff_reloc_section(int c)
{
/* Reserve 0x20 bytes for .reloc section */
memset(buf+c, 0, PECOFF_RELOC_RESERVE);
return PECOFF_RELOC_RESERVE;
}
static void efi_stub_defaults(void)
{
/* Defaults for old kernel */
#ifdef CONFIG_X86_32
efi_pe_entry = 0x10;
#else
efi_pe_entry = 0x210;
startup_64 = 0x200;
#endif
}
static void efi_stub_entry_update(void)
{
unsigned long addr = efi32_stub_entry;
#ifdef CONFIG_X86_64
/* Yes, this is really how we defined it :( */
addr = efi64_stub_entry - 0x200;
#endif
#ifdef CONFIG_EFI_MIXED
if (efi32_stub_entry != addr)
die("32-bit and 64-bit EFI entry points do not match\n");
#endif
put_unaligned_le32(addr, &buf[0x264]);
}
#else
static inline void update_pecoff_setup_and_reloc(unsigned int size) {}
static inline void update_pecoff_text(unsigned int text_start,
unsigned int file_sz) {}
static inline void update_pecoff_bss(unsigned int file_sz,
unsigned int init_sz) {}
static inline void efi_stub_defaults(void) {}
static inline void efi_stub_entry_update(void) {}
static inline int reserve_pecoff_reloc_section(int c)
{
return 0;
}
#endif /* CONFIG_EFI_STUB */
/*
* Parse zoffset.h and find the entry points. We could just #include zoffset.h
* but that would mean tools/build would have to be rebuilt every time. It's
* not as if parsing it is hard...
*/
#define PARSE_ZOFS(p, sym) do { \
if (!strncmp(p, "#define ZO_" #sym " ", 11+sizeof(#sym))) \
sym = strtoul(p + 11 + sizeof(#sym), NULL, 16); \
} while (0)
static void parse_zoffset(char *fname)
{
FILE *file;
char *p;
int c;
file = fopen(fname, "r");
if (!file)
die("Unable to open `%s': %m", fname);
c = fread(buf, 1, sizeof(buf) - 1, file);
if (ferror(file))
die("read-error on `zoffset.h'");
fclose(file);
buf[c] = 0;
p = (char *)buf;
while (p && *p) {
PARSE_ZOFS(p, efi32_stub_entry);
PARSE_ZOFS(p, efi64_stub_entry);
PARSE_ZOFS(p, efi_pe_entry);
PARSE_ZOFS(p, startup_64);
p = strchr(p, '\n');
while (p && (*p == '\r' || *p == '\n'))
p++;
}
}
int main(int argc, char ** argv)
{
unsigned int i, sz, setup_sectors, init_sz;
int c;
u32 sys_size;
struct stat sb;
FILE *file, *dest;
int fd;
void *kernel;
u32 crc = 0xffffffffUL;
efi_stub_defaults();
if (argc != 5)
usage();
parse_zoffset(argv[3]);
dest = fopen(argv[4], "w");
if (!dest)
die("Unable to write `%s': %m", argv[4]);
/* Copy the setup code */
file = fopen(argv[1], "r");
if (!file)
die("Unable to open `%s': %m", argv[1]);
c = fread(buf, 1, sizeof(buf), file);
if (ferror(file))
die("read-error on `setup'");
if (c < 1024)
die("The setup must be at least 1024 bytes");
if (get_unaligned_le16(&buf[510]) != 0xAA55)
die("Boot block hasn't got boot flag (0xAA55)");
fclose(file);
c += reserve_pecoff_reloc_section(c);
/* Pad unused space with zeros */
setup_sectors = (c + 511) / 512;
if (setup_sectors < SETUP_SECT_MIN)
setup_sectors = SETUP_SECT_MIN;
i = setup_sectors*512;
memset(buf+c, 0, i-c);
update_pecoff_setup_and_reloc(i);
/* Set the default root device */
put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
printf("Setup is %d bytes (padded to %d bytes).\n", c, i);
/* Open and stat the kernel file */
fd = open(argv[2], O_RDONLY);
if (fd < 0)
die("Unable to open `%s': %m", argv[2]);
if (fstat(fd, &sb))
die("Unable to stat `%s': %m", argv[2]);
sz = sb.st_size;
printf("System is %d kB\n", (sz+1023)/1024);
kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
if (kernel == MAP_FAILED)
die("Unable to mmap '%s': %m", argv[2]);
/* Number of 16-byte paragraphs, including space for a 4-byte CRC */
sys_size = (sz + 15 + 4) / 16;
/* Patch the setup code with the appropriate size parameters */
buf[0x1f1] = setup_sectors-1;
put_unaligned_le32(sys_size, &buf[0x1f4]);
update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
init_sz = get_unaligned_le32(&buf[0x260]);
update_pecoff_bss(i + (sys_size * 16), init_sz);
efi_stub_entry_update();
crc = partial_crc32(buf, i, crc);
if (fwrite(buf, 1, i, dest) != i)
die("Writing setup failed");
/* Copy the kernel code */
crc = partial_crc32(kernel, sz, crc);
if (fwrite(kernel, 1, sz, dest) != sz)
die("Writing kernel failed");
/* Add padding leaving 4 bytes for the checksum */
while (sz++ < (sys_size*16) - 4) {
crc = partial_crc32_one('\0', crc);
if (fwrite("\0", 1, 1, dest) != 1)
die("Writing padding failed");
}
/* Write the CRC */
printf("CRC %x\n", crc);
put_unaligned_le32(crc, buf);
if (fwrite(buf, 1, 4, dest) != 4)
die("Writing CRC failed");
/* Catch any delayed write failures */
if (fclose(dest))
die("Writing image failed");
close(fd);
/* Everything is OK */
return 0;
}

71
tools/le_byteshift.h

@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _TOOLS_LE_BYTESHIFT_H
#define _TOOLS_LE_BYTESHIFT_H
#include <stdint.h>
static inline uint16_t __get_unaligned_le16(const uint8_t *p)
{
return p[0] | p[1] << 8;
}
static inline uint32_t __get_unaligned_le32(const uint8_t *p)
{
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
}
static inline uint64_t __get_unaligned_le64(const uint8_t *p)
{
return (uint64_t)__get_unaligned_le32(p + 4) << 32 |
__get_unaligned_le32(p);
}
static inline void __put_unaligned_le16(uint16_t val, uint8_t *p)
{
*p++ = val;
*p++ = val >> 8;
}
static inline void __put_unaligned_le32(uint32_t val, uint8_t *p)
{
__put_unaligned_le16(val >> 16, p + 2);
__put_unaligned_le16(val, p);
}
static inline void __put_unaligned_le64(uint64_t val, uint8_t *p)
{
__put_unaligned_le32(val >> 32, p + 4);
__put_unaligned_le32(val, p);
}
static inline uint16_t get_unaligned_le16(const void *p)
{
return __get_unaligned_le16((const uint8_t *)p);
}
static inline uint32_t get_unaligned_le32(const void *p)
{
return __get_unaligned_le32((const uint8_t *)p);
}
static inline uint64_t get_unaligned_le64(const void *p)
{
return __get_unaligned_le64((const uint8_t *)p);
}
static inline void put_unaligned_le16(uint16_t val, void *p)
{
__put_unaligned_le16(val, p);
}
static inline void put_unaligned_le32(uint32_t val, void *p)
{
__put_unaligned_le32(val, p);
}
static inline void put_unaligned_le64(uint64_t val, void *p)
{
__put_unaligned_le64(val, p);
}
#endif /* _TOOLS_LE_BYTESHIFT_H */

28
tools/makefile

@ -0,0 +1,28 @@
CC=gcc -I . -o
SRCS= $(wildcard *.c)
EXECS= $(SRCS:.c=)
CONVERT=dos2unix
INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl
REMOVE=rm -f
CHANGELF=elfedit --output-osabi FenixOS
CHANGEPERM=chmod 644
all: $(EXECS)
sync
togit: clean indent
%: %.c
$(CC) $@ $<
clean:
$(REMOVE) *.o
$(REMOVE) *.c~
find . -type f ! -name makefile -perm /u=x -maxdepth 1 -regex '.+/\.?[^\.]+' -exec $(REMOVE) {} \;
sync
indent:
$(CHANGEPERM) *.c
$(CONVERT) *.c
$(INDENT) *.c
$(REMOVE) *.c~
sync
Loading…
Cancel
Save