3 Other Architecture-Specific Interfaces

3.1 System Calls

asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on);
asmlinkage int sys_iopl(long ebx,long ecx,long edx,
        long esi, long edi, long ebp, long eax, long ds,
        long es, long fs, long gs, long orig_eax,
        long eip,long cs,long eflags,long esp,long ss);
asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount);
asmlinkage int sys_fork(struct pt_regs regs);
asmlinkage int sys_clone(struct pt_regs regs);
asmlinkage int sys_execvesys_execve(struct pt_regs regs);
asmlinkage int sys_idle(void);
asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, 
        unsigned long set);
asmlinkage int sys_sigreturn(unsigned long __unused);
asmlinkage int sys_pipe(unsigned long * fildes);
asmlinkage int sys_vm86(struct vm86_struct * v86);

The i386 support must implement these system calls. See the Linux man pages for a description.

XXX

3.2 proc Filesystem Support

int get_irq_list(char *buf);

Print a description of IRQs to buf.

int get_cpuinfo(char *buf);

Print CPU information to buf.

#ifdef __SMP_PROF__
int get_smp_prof_list(char *buf);
#endif          

Print SMP profiling information to buf.

3.3 init/main.c Support

void setup_arch(char **cmdline_p, unsigned long *memory_start_p, 
        unsigned long *memory_end_p);

setup_arch (linuxarch/i386/kernel/setup.c/)initializes some global structures containing information about the configuration of the machine linux is running on. It expects the information at a well defined address (empty_zero_page), where it is put by code sequences in setup.S.

If we remove all unnessecary things, setup_arch initializes at least the following structures:

ROOT_DEV
Setup the root device. It is taken from ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC)), but I don't know were it really comes from. (There is a label in bootsect.S, but I don't know, how the value is transfered to empty_zero_page. It seems, that setup.S moves the values to 0x9000 and head.S moves them to empty_zero_page)

drive_info
Drive info is a 32 byte structure containing information about hard disks. It is taken from DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))

screen_info
SCREEN_INFO (*(struct screen_info *) (PARAM+0))
/*
 * These are set up by the setup-routine at boot-time:
 */

struct screen_info {
	unsigned char  orig_x;
	unsigned char  orig_y;
	unsigned char  unused1[2];
	unsigned short orig_video_page;
	unsigned char  orig_video_mode;
	unsigned char  orig_video_cols;
	unsigned short unused2;
	unsigned short orig_video_ega_bx;
	unsigned short unused3;
	unsigned char  orig_video_lines;
	unsigned char  orig_video_isVGA;
	unsigned short orig_video_points;
};

auxillary device info
AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))

set by setup.S, ps_mouse detected or not

memory_end and meory_start

init_task.mm

other
        ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
        drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
#ifdef CONFIG_APM
        apm_bios_info = APM_BIOS_INFO;
#endif
        aux_device_present = AUX_DEVICE_INFO;
        memory_end = (1<<20) + (EXT_MEM_K<<10);
        memory_end &= PAGE_MASK;
#ifdef CONFIG_BLK_DEV_RAM
        rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
        rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
        rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif
#ifdef CONFIG_MAX_16M
        if (memory_end > 16*1024*1024)
                memory_end = 16*1024*1024;
#endif
        if (!MOUNT_ROOT_RDONLY)
                root_mountflags &= ~MS_RDONLY;
        memory_start = (unsigned long) &_end;
        init_task.mm->start_code = TASK_SIZE;
        init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
        init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
        init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;

        /* Save unparsed command line copy for /proc/cmdline */
        memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
        saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
void init_IRQ(void);
void trap_init(void);
void arch_syms_export(void);

XXX

unsigned long paging_init(unsigned long start_mem, unsigned long end_mem);

Set up the page tables: map real memory into the kernel's user space, fix up start_mem accordingly. Also unmap the page at virtual kernel address 0, so that we can trap those pesky NULL-reference errors in the kernel. Then call free_area_init(start_mem, end_mem); (not declared anywhere).

void mem_init(unsigned long start_mem, unsigned long end_mem);

Setup the mem_map[] array. For each available page, call free_page() (declared in <linux/mm.h>).

3.4 Misc. Other Stuff

int dump_fpu (struct user_i387_struct* fpu);

Dump FPU state.

void hard_reset_now(void);

Reset the CPU and reboot.


Michael Hohmuth
March 21, 1996