include-linux
config.h
#ifndef _CONFIG_H
#define _CONFIG_H
/* #define LASU_HD */
#define LINUS_HD
/*
- Amount of ram memory (in bytes, 640k-1M not discounted). Currently 8Mb.
- Don’t make this bigger without making sure that there are enough page
- directory entries (boot/head.s)
*/
#if defined(LINUS_HD)
#define HIGH_MEMORY (0x800000)
#elif defined(LASU_HD)
#define HIGH_MEMORY (0x400000)
#else
#error “must define hd”
#endif
/* End of buffer memory. Must be 0xA0000, or > 0x100000, 4096-byte aligned */
#if (HIGH_MEMORY>=0x600000)
#define BUFFER_END 0x200000
#else
#define BUFFER_END 0xA0000
#endif
/* Root device at bootup. */
#if defined(LINUS_HD)
#define ROOT_DEV 0x306
#elif defined(LASU_HD)
#define ROOT_DEV 0x302
#else
#error “must define HD”
#endif
/*
- HD type. If 2, put 2 structures with a comma. If just 1, put
- only 1 struct. The structs are { HEAD, SECTOR, TRACKS, WPCOM, LZONE, CTL }
- NOTE. CTL is supposed to be 0 for drives with less than 8 heads, and
- 8 if heads >= 8. Don’t know why, and I haven’t tested it on a drive with
- more than 8 heads, but that is what the bios-listings seem to imply. I
- just love not having a manual.
*/
#if defined(LASU_HD)
#define HD_TYPE { 7,35,915,65536,920,0 }
#elif defined(LINUS_HD)
#define HD_TYPE { 5,17,980,300,980,0 },{ 5,17,980,300,980,0 }
#else
#error “must define a hard-disk type”
#endif
#endif
fs.h
/*
- This file has definitions for some important file table
- structures etc.
*/
#ifndef _FS_H
#define _FS_H
#include <sys/types.h>
/* devices are as follows: (same as minix, so we can use the minix
- file system. These are major numbers.)
- 0 - unused (nodev)
- 1 - /dev/mem
- 2 - /dev/fd
- 3 - /dev/hd
- 4 - /dev/ttyx
- 5 - /dev/tty
- 6 - /dev/lp
- 7 - unnamed pipes
*/
#define IS_BLOCKDEV(x) ((x)==2 || (x)==3)
#define READ 0
#define WRITE 1
void buffer_init(void);
#define MAJOR(a) (((unsigned)(a))>>8)
#define MINOR(a) ((a)&0xff)
#define NAME_LEN 14
#define I_MAP_SLOTS 8
#define Z_MAP_SLOTS 8
#define SUPER_MAGIC 0x137F
#define NR_OPEN 20
#define NR_INODE 32
#define NR_FILE 64
#define NR_SUPER 8
#define NR_HASH 307
#define NR_BUFFERS nr_buffers
#define BLOCK_SIZE 1024
#ifndef NULL
#define NULL ((void *) 0)
#endif
#define INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct d_inode)))
#define DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct dir_entry)))
typedef char buffer_block[BLOCK_SIZE];
struct buffer_head {
char * b_data; /* pointer to data block (1024 bytes) /
unsigned short b_dev; / device (0 = free) /
unsigned short b_blocknr; / block number /
unsigned char b_uptodate;
unsigned char b_dirt; / 0-clean,1-dirty /
unsigned char b_count; / users using this block /
unsigned char b_lock; / 0 - ok, 1 -locked */
struct task_struct * b_wait;
struct buffer_head * b_prev;
struct buffer_head * b_next;
struct buffer_head * b_prev_free;
struct buffer_head * b_next_free;
};
struct d_inode {
unsigned short i_mode;
unsigned short i_uid;
unsigned long i_size;
unsigned long i_time;
unsigned char i_gid;
unsigned char i_nlinks;
unsigned short i_zone[9];
};
struct m_inode {
unsigned short i_mode;
unsigned short i_uid;
unsigned long i_size;
unsigned long i_mtime;
unsigned char i_gid;
unsigned char i_nlinks;
unsigned short i_zone[9];
/* these are in memory also */
struct task_struct * i_wait;
unsigned long i_atime;
unsigned long i_ctime;
unsigned short i_dev;
unsigned short i_num;
unsigned short i_count;
unsigned char i_lock;
unsigned char i_dirt;
unsigned char i_pipe;
unsigned char i_mount;
unsigned char i_seek;
unsigned char i_update;
};
#define PIPE_HEAD(inode) (((long *)((inode).i_zone))[0])
#define PIPE_TAIL(inode) (((long *)((inode).i_zone))[1])
#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)PIPE_TAIL(inode))
#define PIPE_FULL(inode) (PIPE_SIZE(inode)(PAGE_SIZE-1))
#define INC_PIPE(head)
asm(“incl %0\n\tandl $4095,%0”::“m” (head))
struct file {
unsigned short f_mode;
unsigned short f_flags;
unsigned short f_count;
struct m_inode * f_inode;
off_t f_pos;
};
struct super_block {
unsigned short s_ninodes;
unsigned short s_nzones;
unsigned short s_imap_blocks;
unsigned short s_zmap_blocks;
unsigned short s_firstdatazone;
unsigned short s_log_zone_size;
unsigned long s_max_size;
unsigned short s_magic;
/* These are only in memory */
struct buffer_head * s_imap[8];
struct buffer_head * s_zmap[8];
unsigned short s_dev;
struct m_inode * s_isup;
struct m_inode * s_imount;
unsigned long s_time;
unsigned char s_rd_only;
unsigned char s_dirt;
};
struct dir_entry {
unsigned short inode;
char name[NAME_LEN];
};
extern struct m_inode inode_table[NR_INODE];
extern struct file file_table[NR_FILE];
extern struct super_block super_block[NR_SUPER];
extern struct buffer_head * start_buffer;
extern int nr_buffers;
extern void truncate(struct m_inode * inode);
extern void sync_inodes(void);
extern void wait_on(struct m_inode * inode);
extern int bmap(struct m_inode * inode,int block);
extern int create_block(struct m_inode * inode,int block);
extern struct m_inode * namei(const char * pathname);
extern int open_namei(const char * pathname, int flag, int mode,
struct m_inode ** res_inode);
extern void iput(struct m_inode * inode);
extern struct m_inode * iget(int dev,int nr);
extern struct m_inode * get_empty_inode(void);
extern struct m_inode * get_pipe_inode(void);
extern struct buffer_head * get_hash_table(int dev, int block);
extern struct buffer_head * getblk(int dev, int block);
extern void ll_rw_block(int rw, struct buffer_head * bh);
extern void brelse(struct buffer_head * buf);
extern struct buffer_head * bread(int dev,int block);
extern int new_block(int dev);
extern void free_block(int dev, int block);
extern struct m_inode * new_inode(int dev);
extern void free_inode(struct m_inode * inode);
extern void mount_root(void);
extern inline struct super_block * get_super(int dev)
{
struct super_block * s;
for(s = 0+super_block;s < NR_SUPER+super_block; s++)
if (s->s_dev == dev)
return s;
return NULL;
}
#endif
hdreg.h
/*
- This file contains some defines for the AT-hd-controller.
- Various sources. Check out some definitions (see comments with
- a ques).
*/
#ifndef _HDREG_H
#define _HDREG_H
/* currently supports only 1 hd, put type here */
#define HARD_DISK_TYPE 17
/*
- Ok, hard-disk-type is currently hardcoded. Not beatiful,
- but easier. We don’t use BIOS for anything else, why should
- we get HD-type from it? Get these values from Reference Guide.
*/
#if HARD_DISK_TYPE == 17
#define _CYL 977
#define _HEAD 5
#define __WPCOM 300
#define _LZONE 977
#define _SECT 17
#define _CTL 0
#elif HARD_DISK_TYPE == 18
#define _CYL 977
#define _HEAD 7
#define __WPCOM (-1)
#define _LZONE 977
#define _SECT 17
#define _CTL 0
#else
#error Define HARD_DISK_TYPE and parameters, add your own entries as well
#endif
/* Controller wants just wp-com/4 */
#if __WPCOM >= 0
#define _WPCOM ((__WPCOM)>>2)
#else
#define _WPCOM __WPCOM
#endif
/* Hd controller regs. Ref: IBM AT Bios-listing /
#define HD_DATA 0x1f0 / _CTL when writing /
#define HD_ERROR 0x1f1 / see err-bits /
#define HD_NSECTOR 0x1f2 / nr of sectors to read/write /
#define HD_SECTOR 0x1f3 / starting sector /
#define HD_LCYL 0x1f4 / starting cylinder /
#define HD_HCYL 0x1f5 / high byte of starting cyl /
#define HD_CURRENT 0x1f6 / 101dhhhh , d=drive, hhhh=head /
#define HD_STATUS 0x1f7 / see status-bits /
#define HD_PRECOMP HD_ERROR / same io address, read=error, write=precomp /
#define HD_COMMAND HD_STATUS / same io address, read=status, write=cmd */
#define HD_CMD 0x3f6
/* Bits of HD_STATUS /
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 / Corrected error */
#define DRQ_STAT 0x08
#define SEEK_STAT 0x10
#define WRERR_STAT 0x20
#define READY_STAT 0x40
#define BUSY_STAT 0x80
/* Values for HD_COMMAND */
#define WIN_RESTORE 0x10
#define WIN_READ 0x20
#define WIN_WRITE 0x30
#define WIN_VERIFY 0x40
#define WIN_FORMAT 0x50
#define WIN_INIT 0x60
#define WIN_SEEK 0x70
#define WIN_DIAGNOSE 0x90
#define WIN_SPECIFY 0x91
/* Bits for HD_ERROR /
#define MARK_ERR 0x01 / Bad address mark ? /
#define TRK0_ERR 0x02 / couldn’t find track 0 /
#define ABRT_ERR 0x04 / ? /
#define ID_ERR 0x10 / ? /
#define ECC_ERR 0x40 / ? /
#define BBD_ERR 0x80 / ? */
struct partition {
unsigned char boot_ind; /* 0x80 - active (unused) /
unsigned char head; / ? /
unsigned char sector; / ? /
unsigned char cyl; / ? /
unsigned char sys_ind; / ? /
unsigned char end_head; / ? /
unsigned char end_sector; / ? /
unsigned char end_cyl; / ? /
unsigned int start_sect; / starting sector counting from 0 /
unsigned int nr_sects; / nr of sectors in partition */
};
#endif
head.h
#ifndef _HEAD_H
#define _HEAD_H
typedef struct desc_struct {
unsigned long a,b;
} desc_table[256];
extern unsigned long pg_dir[1024];
extern desc_table idt,gdt;
#define GDT_NUL 0
#define GDT_CODE 1
#define GDT_DATA 2
#define GDT_TMP 3
#define LDT_NUL 0
#define LDT_CODE 1
#define LDT_DATA 2
#endif
kernel.h
/*
- ‘kernel.h’ contains some often-used function prototypes etc
*/
void verify_area(void * addr,int count);
volatile void panic(const char * str);
int printf(const char * fmt, …);
int printk(const char * fmt, …);
int tty_write(unsigned ch,char * buf,int count);
mm.h
#ifndef _MM_H
#define _MM_H
#define PAGE_SIZE 4096
extern unsigned long get_free_page(void);
extern unsigned long put_page(unsigned long page,unsigned long address);
extern void free_page(unsigned long addr);
#endif
sched.h
#ifndef _SCHED_H
#define _SCHED_H
#define NR_TASKS 64
#define HZ 100
#define FIRST_TASK task[0]
#define LAST_TASK task[NR_TASKS-1]
#include <linux/head.h>
#include <linux/fs.h>
#include <linux/mm.h>
#if (NR_OPEN > 32)
#error “Currently the close-on-exec-flags are in one word, max 32 files/proc”
#endif
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_ZOMBIE 3
#define TASK_STOPPED 4
#ifndef NULL
#define NULL ((void *) 0)
#endif
extern int copy_page_tables(unsigned long from, unsigned long to, long size);
extern int free_page_tables(unsigned long from, long size);
extern void sched_init(void);
extern void schedule(void);
extern void trap_init(void);
extern void panic(const char * str);
extern int tty_write(unsigned minor,char * buf,int count);
typedef int (*fn_ptr)();
struct i387_struct {
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
};
struct tss_struct {
long back_link; /* 16 high bits zero /
long esp0;
long ss0; / 16 high bits zero /
long esp1;
long ss1; / 16 high bits zero /
long esp2;
long ss2; / 16 high bits zero /
long cr3;
long eip;
long eflags;
long eax,ecx,edx,ebx;
long esp;
long ebp;
long esi;
long edi;
long es; / 16 high bits zero /
long cs; / 16 high bits zero /
long ss; / 16 high bits zero /
long ds; / 16 high bits zero /
long fs; / 16 high bits zero /
long gs; / 16 high bits zero /
long ldt; / 16 high bits zero /
long trace_bitmap; / bits: trace 0, bitmap 16-31 */
struct i387_struct i387;
};
struct task_struct {
/* these are hardcoded - don’t touch /
long state; / -1 unrunnable, 0 runnable, >0 stopped /
long counter;
long priority;
long signal;
fn_ptr sig_restorer;
fn_ptr sig_fn[32];
/ various fields /
int exit_code;
unsigned long end_code,end_data,brk,start_stack;
long pid,father,pgrp,session,leader;
unsigned short uid,euid,suid;
unsigned short gid,egid,sgid;
long alarm;
long utime,stime,cutime,cstime,start_time;
unsigned short used_math;
/ file system info /
int tty; / -1 if no tty, so it must be signed /
unsigned short umask;
struct m_inode * pwd;
struct m_inode * root;
unsigned long close_on_exec;
struct file * filp[NR_OPEN];
/ ldt for this task 0 - zero 1 - cs 2 - ds&ss /
struct desc_struct ldt[3];
/ tss for this task */
struct tss_struct tss;
};
/*
- INIT_TASK is used to set up the first task table, touch at
- your own risk!. Base=0, limit=0x9ffff (=640kB)
/
#define INIT_TASK
/ state etc / { 0,15,15,
/ signals / 0,NULL,{(fn_ptr) 0,},
/ ec,brk… / 0,0,0,0,0,
/ pid etc… / 0,-1,0,0,0,
/ uid etc / 0,0,0,0,0,0,
/ alarm / 0,0,0,0,0,0,
/ math / 0,
/ fs info / -1,0133,NULL,NULL,0,
/ filp / {NULL,},
{
{0,0},
/ ldt */ {0x9f,0xc0fa00},
{0x9f,0xc0f200},
},
/tss/ {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,
0,0,0,0,0,0,0,0,
0,0,0x17,0x17,0x17,0x17,0x17,0x17,
_LDT(0),0x80000000,
{}
},
}
extern struct task_struct *task[NR_TASKS];
extern struct task_struct *last_task_used_math;
extern struct task_struct *current;
extern long volatile jiffies;
extern long startup_time;
#define CURRENT_TIME (startup_time+jiffies/HZ)
extern void sleep_on(struct task_struct ** p);
extern void interruptible_sleep_on(struct task_struct ** p);
extern void wake_up(struct task_struct ** p);
/*
- Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall
- 4-TSS0, 5-LDT0, 6-TSS1 etc …
/
#define FIRST_TSS_ENTRY 4
#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
#define ltr(n) asm(“ltr %%ax”::“a” (_TSS(n)))
#define lldt(n) asm(“lldt %%ax”::“a” (_LDT(n)))
#define str(n)
asm(“str %%ax\n\t”
“subl %2,%%eax\n\t”
“shrl $4,%%eax”
:"=a" (n)
:“a” (0),“i” (FIRST_TSS_ENTRY<<3))
/ - switch_to(n) should switch tasks to task nr n, first
- checking that n isn’t the current task, in which case it does nothing.
- This also clears the TS-flag if the task we switched to has used
- tha math co-processor latest.
/
#define switch_to(n) {
struct {long a,b;} __tmp;
asm(“cmpl %%ecx,_current\n\t”
“je 1f\n\t”
“xchgl %%ecx,_current\n\t”
“movw %%dx,%1\n\t”
“ljmp %0\n\t”
“cmpl %%ecx,%2\n\t”
“jne 1f\n\t”
“clts\n”
“1:”
::“m” (&__tmp.a),“m” (*&__tmp.b),
“m” (last_task_used_math),“d” _TSS(n),“c” ((long) task[n]));
}
#define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000)
#define _set_base(addr,base)
asm(“movw %%dx,%0\n\t”
“rorl $16,%%edx\n\t”
“movb %%dl,%1\n\t”
“movb %%dh,%2”
::“m” (((addr)+2)),
“m” (((addr)+4)),
“m” (*((addr)+7)),
“d” (base)
:“dx”)
#define _set_limit(addr,limit)
asm(“movw %%dx,%0\n\t”
“rorl $16,%%edx\n\t”
“movb %1,%%dh\n\t”
“andb $0xf0,%%dh\n\t”
“orb %%dh,%%dl\n\t”
“movb %%dl,%1”
::“m” ((addr)),
“m” (((addr)+6)),
“d” (limit)
:“dx”)
#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
#define _get_base(addr) ({
unsigned long __base;
asm(“movb %3,%%dh\n\t”
“movb %2,%%dl\n\t”
“shll $16,%%edx\n\t”
“movw %1,%%dx”
:"=d" (__base)
:“m” (((addr)+2)),
“m” (((addr)+4)),
“m” (*((addr)+7)));
__base;})
#define get_base(ldt) _get_base( ((char *)&(ldt)) )
#define get_limit(segment) ({
unsigned long __limit;
asm(“lsll %1,%0\n\tincl %0”:"=r" (__limit):“r” (segment));
__limit;})
#endif
sys.h
extern int sys_setup();
extern int sys_exit();
extern int sys_fork();
extern int sys_read();
extern int sys_write();
extern int sys_open();
extern int sys_close();
extern int sys_waitpid();
extern int sys_creat();
extern int sys_link();
extern int sys_unlink();
extern int sys_execve();
extern int sys_chdir();
extern int sys_time();
extern int sys_mknod();
extern int sys_chmod();
extern int sys_chown();
extern int sys_break();
extern int sys_stat();
extern int sys_lseek();
extern int sys_getpid();
extern int sys_mount();
extern int sys_umount();
extern int sys_setuid();
extern int sys_getuid();
extern int sys_stime();
extern int sys_ptrace();
extern int sys_alarm();
extern int sys_fstat();
extern int sys_pause();
extern int sys_utime();
extern int sys_stty();
extern int sys_gtty();
extern int sys_access();
extern int sys_nice();
extern int sys_ftime();
extern int sys_sync();
extern int sys_kill();
extern int sys_rename();
extern int sys_mkdir();
extern int sys_rmdir();
extern int sys_dup();
extern int sys_pipe();
extern int sys_times();
extern int sys_prof();
extern int sys_brk();
extern int sys_setgid();
extern int sys_getgid();
extern int sys_signal();
extern int sys_geteuid();
extern int sys_getegid();
extern int sys_acct();
extern int sys_phys();
extern int sys_lock();
extern int sys_ioctl();
extern int sys_fcntl();
extern int sys_mpx();
extern int sys_setpgid();
extern int sys_ulimit();
extern int sys_uname();
extern int sys_umask();
extern int sys_chroot();
extern int sys_ustat();
extern int sys_dup2();
extern int sys_getppid();
extern int sys_getpgrp();
extern int sys_setsid();
fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
sys_unlink, sys_execve, sys_chdir, sys_time, sys_mknod, sys_chmod,
sys_chown, sys_break, sys_stat, sys_lseek, sys_getpid, sys_mount,
sys_umount, sys_setuid, sys_getuid, sys_stime, sys_ptrace, sys_alarm,
sys_fstat, sys_pause, sys_utime, sys_stty, sys_gtty, sys_access,
sys_nice, sys_ftime, sys_sync, sys_kill, sys_rename, sys_mkdir,
sys_rmdir, sys_dup, sys_pipe, sys_times, sys_prof, sys_brk, sys_setgid,
sys_getgid, sys_signal, sys_geteuid, sys_getegid, sys_acct, sys_phys,
sys_lock, sys_ioctl, sys_fcntl, sys_mpx, sys_setpgid, sys_ulimit,
sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
sys_getpgrp,sys_setsid};
tty.h
/*
- ‘tty.h’ defines some structures used by tty_io.c and some defines.
- NOTE! Don’t touch this without checking that nothing in rs_io.s or
- con_io.s breaks. Some constants are hardwired into the system (mainly
- offsets into ‘tty_queue’
*/
#ifndef _TTY_H
#define _TTY_H
#include <termios.h>
#define TTY_BUF_SIZE 1024
struct tty_queue {
unsigned long data;
unsigned long head;
unsigned long tail;
struct task_struct * proc_list;
char buf[TTY_BUF_SIZE];
};
#define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1))
#define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1))
#define EMPTY(a) ((a).head == (a).tail)
#define LEFT(a) (((a).tail-(a).head-1)&(TTY_BUF_SIZE-1))
#define LAST(a) ((a).buf[(TTY_BUF_SIZE-1)&((a).head-1)])
#define FULL(a) (!LEFT(a))
#define CHARS(a) (((a).head-(a).tail)&(TTY_BUF_SIZE-1))
#define GETCH(queue,c)
(void)({c=(queue).buf[(queue).tail];INC((queue).tail);})
#define PUTCH(c,queue)
(void)({(queue).buf[(queue).head]=©;INC((queue).head);})
#define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF])
#define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR])
#define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP])
#define START_CHAR(tty) ((tty)->termios.c_cc[VSTART])
#define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE])
struct tty_struct {
struct termios termios;
int pgrp;
int stopped;
void (*write)(struct tty_struct * tty);
struct tty_queue read_q;
struct tty_queue write_q;
struct tty_queue secondary;
};
extern struct tty_struct tty_table[];
/* intr=^C quit=^| erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Y eol=\0
reprint=^R discard=^U werase=^W lnext=^V
eol2=\0
*/
#define INIT_C_CC “\003\034\177\025\004\0\1\0\021\023\031\0\022\017\027\026\0”
void rs_init(void);
void con_init(void);
void tty_init(void);
int tty_read(unsigned c, char * buf, int n);
int tty_write(unsigned c, char * buf, int n);
void rs_write(struct tty_struct * tty);
void con_write(struct tty_struct * tty);
void copy_to_cooked(struct tty_struct * tty);
#endif