Porting newlib, messy first steps
Posted: Thu May 25, 2017 8:20 pm
So I just completed http://wiki.osdev.org/Porting_Newlib. I realize that page does not have the best advice and glosses over libgloss (sorry) but it seems to work just fine for my purposes. I'm interested to see if what I did seems fine for basic purposes. Note that I only cared about getting newlib working and I didn't do anything in the way of OS specific toolchain.
- Compile binutils and GCC with --with-sysroot pointing to some directory
- Follow the above link
- Have a implementation-defined list of indices for system calls and have each stub call an implementation-defined software interrupt with arguments, i.e:
Real code would wrap this in a macro
- Compile and install newlib files to the sysroot
- Treat 0x80 like any other interrupt and add an assembly stub/to the IDT
- In the ISR handler, if it's interrupt 0x80, pass the regs to the system call handler
- Check regs->eax for the system call type; call the corresponding function with the rest of the GPRs as arguments
- Link against -lc -lm (I have the feeling this is not necessary, so I screwed up somewhere)
seems to work just fine.
What I'm looking to do next is to figure out how to replace newlib's malloc with liballoc (I already have liballoc working kernel-wise) as it seems sbrk is not very popular nowadays. This would ostensibly make testing parts of the library easier before I get userspace working.
Sidenote:
From my search it seems other people are having problems with sbrk and need to zero out the BSS. I'm guessing this only becomes a problem when you enter userspace. For now my stub looks like this:
which I mirror'd after the linux man page.
- Compile binutils and GCC with --with-sysroot pointing to some directory
- Follow the above link
- Have a implementation-defined list of indices for system calls and have each stub call an implementation-defined software interrupt with arguments, i.e:
Code: Select all
#define sys_write 4
int write(int file, char *ptr, int len) {
int res;
asm volatile("int $0x80" : "=a" (res) : "0" (sys_write), "b" ((int)file), "c" ((long)ptr), "d" ((int)len));
return res;
}
- Compile and install newlib files to the sysroot
- Treat 0x80 like any other interrupt and add an assembly stub/to the IDT
- In the ISR handler, if it's interrupt 0x80, pass the regs to the system call handler
- Check regs->eax for the system call type; call the corresponding function with the rest of the GPRs as arguments
- Link against -lc -lm (I have the feeling this is not necessary, so I screwed up somewhere)
Code: Select all
write(1, "Test", sizeof("Test"));
What I'm looking to do next is to figure out how to replace newlib's malloc with liballoc (I already have liballoc working kernel-wise) as it seems sbrk is not very popular nowadays. This would ostensibly make testing parts of the library easier before I get userspace working.
Sidenote:
From my search it seems other people are having problems with sbrk and need to zero out the BSS. I'm guessing this only becomes a problem when you enter userspace. For now my stub looks like this:
Code: Select all
caddr_t sbrk(int incr) {
errno = ENOMEM;
return (caddr_t) -1;
}